Reputation: 14404
i'm creating a form with FormBuilder
and i want to add a Validator
to a formGroup
.
Here is my code:
this.myForm = fb.group({
'name': ['', [Validators.maxLength(50), Validators.required]],
'surname': ['', [Validators.maxLength(50), Validators.required]],
'address': fb.group({
'street': ['', Validators.maxLength(300)],
'place': [''],
'postalcode': ['']
}),
'phone': ['', [Validators.maxLength(25), phoneValidator]],
'email': ['', emailValidator]
});
I would like to conditionally add validators to some of the address's formControls on certain conditions.
So I added a validator
in the following way:
'address': fb.group({
'street': ['', Validators.maxLength(300)],
'place': [''],
'postalcode': ['']
}), { validator: fullAddressValidator })
Then i started to create a validator for the address FormGroup
:
export const fullAddressValidator = (control:FormGroup) => {
var street:FormControl = control.controls.street;
var place:FormControl = control.controls.place;
var postalcode:FormControl = control.controls.postalcode;
if (my conditions are ok) {
return null;
} else {
return { valid: false };
}
};
I need to add the following conditions:
place
is instance of country (instead of city) the postalcode
is optionalpostalcode
is filled in then the zipValidator
must beSo, it is possible to add Angular2 Validators
to a FormGroup
on certain conditions?
If it does, how to implement my conditions? Can i use setValidators()
and updateValueAndValidity()
in the source code of another validator?
Upvotes: 1
Views: 4332
Reputation: 14404
Yes, it's possible to set FormControl
validators inside a FormGroup
custom validator. Here is the solution to my needs:
export const fullAddressValidator = (control:FormGroup):any => {
var street:FormControl = control.controls.street;
var place:FormControl = control.controls.place;
var postalcode:FormControl = control.controls.postalcode;
if (!street.value && !place.value && !postalcode.value) {
street.setValidators(null);
street.updateValueAndValidity({onlySelf: true});
place.setValidators(null);
place.updateValueAndValidity({onlySelf: true});
postalcode.setValidators(null);
postalcode.updateValueAndValidity({onlySelf: true});
return null;
} else {
street.setValidators([Validators.required, Validators.maxLength(300)]);
street.updateValueAndValidity({onlySelf: true});
place.setValidators([Validators.required]);
place.updateValueAndValidity({onlySelf: true});
if (place.value instanceof Country) {
postalcode.setValidators(Validators.maxLength(5));
postalcode.updateValueAndValidity({onlySelf: true});
} else {
postalcode.setValidators([zipValidator()]);
postalcode.updateValueAndValidity({onlySelf: true});
}
}
if (street.invalid || place.invalid || postalcode.invalid) {
return {valid: false};
} else {
return null;
}
};
Upvotes: 0
Reputation: 658225
Create a function that takes a parameter and returns a validator function
export const fullAddressValidator = (condition) => (control:FormGroup) => {
var street:FormControl = control.controls.street;
var place:FormControl = control.controls.place;
var postalcode:FormControl = control.controls.postalcode;
if (my conditions are ok) {
return null;
} else {
return { valid: false };
}
};
and use it like
'address': fb.group({
'street': ['', Validators.maxLength(300)],
'place': [''],
'postalcode': ['']
}), { validator: () => fullAddressValidator(condition) })
Upvotes: 2