Nathan Taylor
Nathan Taylor

Reputation: 25

Angular2: best way to use FormBuilder Validators.required with a checkbox group

I'm building a form in Angular2 with FormBuilder & ngFormModel and cannot find an elegant way of validating that 1 or more checkboxes in a checkbox group are checked. I don't want to have to write a custom component method to validate checkbox groups everywhere I use them. Ideally it would be great to leverage the ngFormModel with FormBuilder & Validators.required or even a custom validator.

Upvotes: 1

Views: 4581

Answers (2)

Thierry Templier
Thierry Templier

Reputation: 202326

You need to define a group for your checkboxes and specify a group validator:

this.myForm = this.builder.group({
  'checkboxes': fb.group({
    checkbox1: [ '' ],
    checkbox2: [ '' ]
  }, {validator: this.checkboxRequired})
});

and the validator:

checkboxRequired(group: FormGroup) {
  var valid = false;

  for (name in group.controls) {
    var val = group.controls[name].value;
    if (val) {
      valid = true;
      break;
    }
  }

  if (valid) {
    return null;
  }

  return {
    checkboxRequired: true
  };
}

You can link this with the form this way:

<form [ngFormModel]="myForm">
  Checkbox1: <input type="checkbox" 
    [ngFormControl]="myForm.controls.checkboxes.controls.checkbox1"/>
  Checkbox2: <input type="checkbox" 
    [ngFormControl]="myForm.controls.checkboxes.controls.checkbox2"/>
</form>

See this question for more details:

You could improve the validator code leveraging Validators.required:

checkboxRequired(group: ControlGroup) {
  var valid = false;

  for (name in group.controls) {
    var check = Validators.required(group.controls[name]);
    if (!check) {
      valid = true;
      break;
    }
  }

  if (valid) {
    return null;
  }

  return {
    checkboxRequired: true
  };
}

Upvotes: 6

Shouvik S Mazumdar
Shouvik S Mazumdar

Reputation: 205

As the APIs have slightly changed. A slightly refreshed version of the above answer below. This is bit verbose on purpose

this.myForm = this._fb.group({
        myName: ['', [<any>Validators.required, <any>Validators.minLength(5)]],
        role: new FormGroup({
             prog:  new FormControl(null),
             mgr:  new FormControl(null),
             designer:  new FormControl(null),
          }, this.CheckGroupValidation)
  });

The Validation function :

private CheckGroupValidation(group:FormGroup)
{

    var valid = false;
    var control_name:any;


    for (control_name in group.controls) 
    {
      var check = group.controls[control_name].value;
      if (check) { valid = true; break;  }
    }

    if (valid) { return null;}
    return { CheckGroupValidation: true}; // not qualified
}

The Template File

<form [formGroup]="myForm" novalidate (ngSubmit)="save()"   >

<ion-list>

    <ion-item>
        <ion-label>Username</ion-label>
        <ion-input type="text" value="" formControlName="myName" ></ion-input>
    </ion-item>


</ion-list>

<ion-list formGroupName="role">
    <ion-item>
        <ion-label>Programmer</ion-label>
        <ion-checkbox color="dark" checked="true" formControlName="prog" ></ion-checkbox>
    </ion-item>

    <ion-item>
        <ion-label>Manager</ion-label>
        <ion-checkbox color="dark" checked="false" formControlName="mgr"></ion-checkbox>
    </ion-item>

    <ion-item>
        <ion-label>Designer</ion-label>
        <ion-checkbox color="dark" checked="false" formControlName="designer"></ion-checkbox>
    </ion-item>

</ion-list> 

<button type="submit" 
         [disabled] = "!myForm.valid" 
         [hidden]= "isProcessing"
         ion-button full style="margin-top:0px;" >Submit</button>
</form>

Upvotes: 0

Related Questions