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.
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.
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.
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;
}
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()]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With