Johan Johan - 4 months ago 49
Javascript Question

Angular 2: Add validators to ngModelGroup

I am using a

directive to group several form inputs together.

In the docs ( I read that there is a
validators: any[]

Does this mean I can add a custom validator function which validates only that
? If so, how do I use it?

That would be awesome because I would like to check if at least one of the checkboxes in the
is checked. I can't use
because that would mean all checkboxes are required. I can't find anything about this in the documentation or am I looking in the wrong place?


This is entirely possible with a ngModelGroup and a custom directive for validation. Key to understanding why this works is that ngModelGroup

Creates and binds a FormGroup instance to a DOM element.

First, we'll build out our directive which is pretty boilerplate with nothing special going on:

  selector: '[hasRequiredCheckboxInGroup]',
  providers: [{provide: NG_VALIDATORS, useExisting: HasRequiredCheckBoxInGroup, multi: true}]
export class HasRequiredCheckBoxInGroup implements Validator, OnChanges {
  private valFn = Validators.nullValidator;

  constructor() {
    this.valFn = validateRequiredCheckboxInGroup();

  validate(control: AbstractControl): {[key: string]: any} {
    return this.valFn(control);

Our validation function is where we take our key knowledge that ngModelGroup creates a FormGroup and apply it:

function validateRequiredCheckboxInGroup() : ValidatorFn {
      return (group) => { //take the group we declare in the template as a parameter
        let isValid = false; //default to invalid for this case
        if(group) {
          for(let ctrl in group.controls) {
            if(group.controls[ctrl].value && typeof group.controls[ctrl].value === 'boolean') { // including a radio button set might blow this up, but hey, let's be careful with the directives
              isValid = group.controls[ctrl].value;

        if(isValid) {
          return null;
        } else {
          return { checkboxRequired: true };

And finally, having included and declared in our Module the directive, we return to the template (needs to be in a form):

<form #f="ngForm">
      <div ngModelGroup="checkboxes" #chks="ngModelGroup" hasRequiredCheckboxInGroup>
          <input type="checkbox" name="chk1" [(ngModel)]="checks['1']"/>
          <input type="checkbox" name="chk2" [(ngModel)]="checks['2']"/>

And here's a plunker with all this available to play with: