Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 297
irudji Avatar asked Jul 11 '19 18:07

irudji


People also ask

How will you create custom validator for a reactive forms?

When using Reactive Forms in Angular, you define custom validators with functions. If the validator does not need to be reused, it can exist as a function in a component file directly. Otherwise, if the validator needs to be reused in other components, it can exist in a separate file.

How can you add the validator function into the reactive forms?

A validator function returns true if the form field is valid according to the validator rules, or false otherwise. A validator can be plugged in directly into a reactive form simply by adding it to the validators list. Each form field has its own list of separate validators.


2 Answers

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;
}
like image 88
Omar Hasan Avatar answered Sep 23 '22 01:09

Omar Hasan


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()]);
like image 38
bryan60 Avatar answered Sep 23 '22 01:09

bryan60