irudji
irudji

Reputation: 229

Adding custom validator to whole form group in Angular Reactive From

I'm dynamically creating reactive forms in Angular based on JSON data received from API. Sometimes form has only several formControls but sometimes there are a lot of form groups or formArrays with FormGroups.

I have a question about FormArray with several FormGroups. In this FormGroups some FormControls can be required and some not. But the whole FormGroup is not required. Only if some FormControls in group are edited, after that whole form group must be valid (every required FormControl can't be empty).

So my question is how to create custom validator for whole FormGroup, which will secure that if every FormControl in these concrete group will be empty, then this group will be valid. But if for example one FormControl will be edited, then every required FormControl must be filled.

Thanks a lot for your ideas.

Upvotes: 7

Views: 15508

Answers (2)

Omar Hasan
Omar Hasan

Reputation: 798

What about trying this simple solution

this is my form init

this.sponsorshipForm = this.fb.group(
  {
    startDate: ['', [Validators.required]],
    endDate: ['', [Validators.required]]
  },
  { validators: [this.sponsorshipDurationValidation] }
);

and this is my validator you can make whatever you need and customize it

sponsorshipDurationValidation(form: FormGroup) {
   if (form.value.startDate && form.value.end) {
     console.log('form ', form, form.status);
   }
   if (something false happen or not valid value) {
     return { validUrl: true };
  }
  return null;
}

Upvotes: 7

bryan60
bryan60

Reputation: 29335

you add form group level validators like this using FormBuilder service:

this.myFormGroup = this.formBuilder.group({ 
                     ... my group info ... 
                   }, {validators: [... validators ... ]);

the custom validator acts like any other, but the abstract control in this case is a FormGroup that can be treated like any other form group.

something like:

function allOrNoneRequired(): ValidatorFn {
  return (ctrl: AbstractControl): ValidationErrors | null => {
    const fg = ctrl as FormGroup;
    const controls = Object.values(fg.controls);
    return (controls.every(fc => !fc.value) || controls.every(fc => !!fc.value))  
             ? null 
             : {allOrNoneRequired: true};
  };
}

then

this.myFormGroup = this.formBuilder.group({ 
                     ... my group info ... 
                   }, {validators: [allOrNoneRequired()]);

Upvotes: 4

Related Questions