Skip to content Skip to sidebar Skip to footer

Angular 2: Add Validators To Ngmodelgroup

I am using a ngModelGroup directive to group several form inputs together. In the docs (https://angular.io/docs/ts/latest/api/forms/index/NgModelGroup-directive.html) I read that t

Solution 1:

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:

@Directive({
  selector: '[hasRequiredCheckboxInGroup]',
  providers: [{provide: NG_VALIDATORS, useExisting: HasRequiredCheckBoxInGroup, multi: true}]
})
exportclassHasRequiredCheckBoxInGroupimplementsValidator, OnChanges {
  private valFn = Validators.nullValidator;

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

  validate(control: AbstractControl): {[key: string]: any} {
    returnthis.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 parameterlet isValid = false; //default to invalid for this caseif(group) {
          for(let ctrl ingroup.controls) {
            if(group.controls[ctrl].value && typeofgroup.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) {
          returnnull;
        } 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"><divngModelGroup="checkboxes" #chks="ngModelGroup"hasRequiredCheckboxInGroup><inputtype="checkbox"name="chk1" [(ngModel)]="checks['1']"/><inputtype="checkbox"name="chk2" [(ngModel)]="checks['2']"/></div><div>
      {{chks.valid}}
      </div></form>

And here's a plunker with all this available to play with: http://plnkr.co/edit/AXWGn5XwRo60fkqGBU3V?p=preview

Solution 2:

Thanks all for helping me out! I've accepted Silentsod's answer because it was most helpful.

My final solution was simply building the form using FormBuilder.

In my component, create the form and add the validator function to it:

ngOnInit(): void {
    // Validator function:let validateMemberList = (group: FormGroup) => {
        let checked = Object.keys(group.controls).reduce((count, key: string) => {
            return count + (group.controls[key].value ? 1 : 0);
        }, 0);

        return checked === 0 ? {'minchecked': 1} : null;
    };

    this.jobForm = this.formBuilder.group({
        jobTitle: ['', Validators.required],
        // more inputs...
        members: this.formBuilder.group({}, {
            // The 2nd argument is an object with a validator property:
            validator: validateMemberList
        }),
        supportMembers: this.formBuilder.group({}, {
            validator: validateMemberList
        })
    });

Then in my template:

<form [formGroup]="jobForm"><ulformGroupName="members"><li *ngFor="let user of teamMembers.members"><labelclass="e-label"><inputclass="e-input"type="checkbox" [formControlName]="user.$key"><user-badge [user]="user"></user-badge></label></li></ul>
...

This validates the form allowing me to display errors and disable the submit button.

Thanks all for the help!

Solution 3:

Looks like each control in your ModelGroup should have is own validator. once this is done you might have access to each one through the validators array. so add the required attribute to the inputs that are required

Post a Comment for "Angular 2: Add Validators To Ngmodelgroup"