iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Forms

Ionic Forms are Angular / React / Vue forms wrapped in ion-input, ion-textarea, ion-select, ion-toggle, etc. They render native-feeling on iOS and Android, with shared validation logic.

Reactive form + validation + submission

EXAMPLE
<!-- 1) Angular — reactive form -->
<form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
    <ion-item lines="inset">
        <ion-label position="floating">Email</ion-label>
        <ion-input type="email" formControlName="email" autocomplete="email"></ion-input>
    </ion-item>
    <ion-note color="danger" *ngIf="email.invalid && email.touched">
        Please enter a valid email.
    </ion-note>

    <ion-item>
        <ion-label position="floating">Password</ion-label>
        <ion-input type="password" formControlName="password"></ion-input>
    </ion-item>
    <ion-note color="danger" *ngIf="password.invalid && password.touched">
        Min 8 characters required.
    </ion-note>

    <ion-item>
        <ion-label>Newsletter</ion-label>
        <ion-toggle formControlName="newsletter" slot="end"></ion-toggle>
    </ion-item>

    <ion-item>
        <ion-label>Country</ion-label>
        <ion-select formControlName="country" interface="action-sheet">
            <ion-select-option value="au">Australia</ion-select-option>
            <ion-select-option value="us">United States</ion-select-option>
            <ion-select-option value="gb">UK</ion-select-option>
        </ion-select>
    </ion-item>

    <ion-button expand="block" type="submit" [disabled]="signupForm.invalid">
        Sign up
    </ion-button>
</form>

// signup.page.ts
import { FormBuilder, Validators } from '@angular/forms';

export class SignupPage {
    signupForm = this.fb.nonNullable.group({
        email:      ['', [Validators.required, Validators.email]],
        password:   ['', [Validators.required, Validators.minLength(8)]],
        newsletter: [true],
        country:    ['au', Validators.required],
    });

    constructor(private fb: FormBuilder, private toast: ToastController) {}

    get email()    { return this.signupForm.controls.email; }
    get password() { return this.signupForm.controls.password; }

    async onSubmit() {
        if (this.signupForm.invalid) return;
        try {
            await this.api.signup(this.signupForm.getRawValue());
            (await this.toast.create({ message: 'Welcome!', duration: 2000 })).present();
        } catch (e: any) {
            (await this.toast.create({ message: e.message, color: 'danger', duration: 3000 })).present();
        }
    }
}

<!-- 2) React (Ionic React) — controlled inputs -->
export function Signup() {
    const [email, setEmail] = useState('');
    const [pw, setPw] = useState('');
    const valid = email.includes('@') && pw.length >= 8;

    return (
        <form onSubmit={(e) => { e.preventDefault(); api.signup({ email, password: pw }); }}>
            <IonItem>
                <IonLabel position="floating">Email</IonLabel>
                <IonInput value={email} onIonInput={(e) => setEmail(e.detail.value!)} />
            </IonItem>
            <IonItem>
                <IonLabel position="floating">Password</IonLabel>
                <IonInput type="password" value={pw} onIonInput={(e) => setPw(e.detail.value!)} />
            </IonItem>
            <IonButton expand="block" type="submit" disabled={!valid}>Sign up</IonButton>
        </form>
    );
}

Why it matters

Use ion-select interface=\"action-sheet\" on mobile — the default popover behaves oddly with the soft keyboard. Test your forms with the on-screen keyboard open, not just on a desktop browser.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
<form (ngSubmit)="save()" [formGroup]="f">
    <ion-item>
        <ion-label position="floating">Email</ion-label>
        <ion-input type="email" formControlName="email"></ion-input>
    </ion-item>
    <ion-button type="submit">Save</ion-button>
</form>
Try it Yourself »

Discussion

Loading…