Ion-checkbox 'required' passes form validation even if it's not checked

I’ve had a search through the forum/GitHub issues and it seems a few people have encountered the same issue, but on previous versions of Ionic or their solutions do not appear to work for me.

I am using ionic 2.1.0 - this appears to also affect all versions of ionic2.

I have a form similar to this:

<form (ngSubmit)="register()" #registerForm="ngForm">
    <ion-item>
        <ion-input type="text" name="username" [(ngModel)]="registration.username" required></ion-input>
    </ion-item>

    .... more inputs ....

    <ion-item>
        <ion-checkbox name="grantPermission" [(ngmodel)]="registration.grantPermission" required></ion-checkbox>
    </ion-item>

    <button type="submit" ion-button round block [disabled]="!registerForm.form.valid">Create Account</button>
</form>

What I’m encountering:

  • Filling in all inputs, but leaving ‘grantPermission’ checkbox UNCHECKED causes the submit button to become active, as if the form has passed validation.

What I expect:

  • The form to only become valid once the ‘required’ checkbox is checked.

Any help on this one would be appreciated, thank you!

1 Like

Build a FormGroup instead of using ngModel. Connect the ion-checkbox to a boolean formControl validated when true. Set the (ionChange) event of the ion-checkbox to call ChangeDetectorRef.detectChanges(), so the formControl updates when the ion-checkbox changes.

There might be a way to make it work with ngModel also, but I’ve found I have much clearer control over FormGroups, especially when ionic-specific inputs are part of the form.

I agree with @AaronSterling’s suggestion of using a FormGroup, but there should be no need for futzing with ChangeDetectorRefs. The following works as expected for me:

<form [formGroup]="form" (ngSubmit)="onSubmit()">
  <ion-list>
    <ion-item>
      <ion-checkbox formControlName="cbox"></ion-checkbox>
      <ion-label item-right>mandatory</ion-label>
    </ion-item>
    <button ion-item [disabled]="!form.valid">submit form</button>
  </ion-list>
</form>

export class HomePage {
  form: FormGroup;

  constructor(fb: FormBuilder) {
    this.form = fb.group({
      cbox: [false, HomePage.mustBeTruthy]
    });
  }

  onSubmit() {
  }

  static mustBeTruthy(c: AbstractControl): { [key: string]: boolean } {
    let rv: { [key: string]: boolean } = {};
    if (!c.value) {
      rv['notChecked'] = true;
    }
    return rv;
  }
}
4 Likes

That code is really sweet.

Thank you! This makes sense to me.

Hey thanks a lot for your reply but I don’t finish to understand it, you declare an object

let rv: { [key: string]: boolean } = {};

and then you use it, if c.value is false, with rv[‘notChecked’] = true, but this value is not part of an FormControl.

If you reply me I apreciate a so much. @rapropos

Validators return a map of errors; they aren’t part of a FormControl. See here.

1 Like

This worked perfectly for what I needed. Thanks