Reputation: 597
I have two fields
Email & Phone
It's multiple fields. Add new contact with add more button so I have used FormArray.
But point is that only one field is required email or phone
So how to validate one field is required in FormArray?
Below is my latest code.
this.form = this.fb.group({
contact: this.fb.array([this.addNewContact()]),
});
public addNewContact() {
return this.fb.group({
department: [''],
phone: [''],
email: [
'',
Validators.compose([
Validators.pattern(/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,15})$/)
])
],
},
this.emailOrPhone());
}
public emailOrPhone() {
return (form: FormGroup): { [key: string]: any } => {
console.log(form);
return (!form.value.phone && !form.value.email) ? { isEmailOrMobile: true } : null;
};
}
I have worked on angular 5.
Upvotes: 2
Views: 1949
Reputation: 5194
You might have to use Custom validator.
Create A directive like below :
import {
FormGroup,
ValidationErrors,
ValidatorFn,
Validators,
} from '@angular/forms';
export const atLeastOne = (validator: ValidatorFn, controls:string[] = null) => (
group: FormGroup,
): ValidationErrors | null => {
if(!controls){
controls = Object.keys(group.controls)
}
const hasAtLeastOne = group && group.controls && controls
.some(k => !validator(group.controls[k]));
return hasAtLeastOne ? null : {
atLeastOne: true,
};
};
the formBuilder should look like below :
return this.fb.group({
department: [''],
phone: [''],
email: [
'',
Validators.compose([
Validators.pattern(/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,15})$/)
])
],
}, { validator: atLeastOne(Validators.required, ['email','phone']) })
Using this directive you can check either of them are valid or not .
This can be reused to any other forms as well. Here is a sample working example of the validator : Working demo of atleast one validator
You can modify this according to your requirement.
Upvotes: 2
Reputation: 2567
A sort way would be, add both the validation with the change in one of the forms you can disable the other one and vice-versa.
public addNewContact() {
return this.fb.group({
department: [''],
phone: ['', Validators.compose([Validators.required])],
email: [
'',
Validators.compose([Validators.required,
Validators.pattern(/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,15})$/)
])
],
},
}
then monitor the change on each field and remove the validation accordingly
this.form.get('phone').removeValidator('required');
or
this.form.get('email').removeValidator('required');
Upvotes: 1