Reputation: 229
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
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
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