Manoj Ghediya
Manoj Ghediya

Reputation: 597

How to validate email or phone fields in form array in angular 5?

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

Answers (2)

programoholic
programoholic

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

Abhishek Ekaanth
Abhishek Ekaanth

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

Related Questions