2

I'm building an Angular 5 form. I have a requirement for contact information on my form (email or phone). Either an email address OR a phone number is required, but not both. How would I create a custom validator for this scenario? From the docs it seems that validators are responsible for just one control, whereas my validator would need to be aware of multiple controls to check all their values.

ngOnInit() {
   this.form = this.formBuilder.group({
       'name': [null, [Validators.required]],
       'email': [null, []], // A user can provide email OR phone, but
       'phone': [null, []], // both are not required. How would you do this?
   });
}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
Matt
  • 6,264
  • 10
  • 54
  • 82
  • You'd use the same custom validator for each, but you'd use a reference to each control and return true if one or the other was used. Here's a good example: https://stackoverflow.com/questions/43487413/password-and-confirm-password-field-validation-angular2-reactive-forms that uses the same idea to validate a password. Still, two form controls are checked to create a group validator. – Z. Bagley Dec 23 '17 at 02:01
  • not completely working yet, try to enhance this: https://stackblitz.com/edit/angular-9effym?file=app%2Fapp.component.ts – HDJEMAI Dec 23 '17 at 04:54

1 Answers1

10

One possible solution is declaring a function that takes as an argument the form itself, for example:

    export function emailAndPhone() {
      return (form: FormGroup): {[key: string]: any} => {
        return (form.value.phone && form.value.email) ||
               (!form.value.phone && !form.value.email) 
                  ? { emailAndPhoneError : true } 
                  : null;
      };
    }

Set the validator function to your form definition using the validator extras:

ngOnInit() {
   this.form = this.formBuilder.group({
       'name': [null, [Validators.required]],
       'email': [null, []], // A user can provide email OR phone, but
       'phone': [null, []], // both are not required. How would you do this?
   }, { validator: emailAndPhone() });
}

If you need to recognize when the validation has detected an invalid input just make sure that emailAndPhoneError that was defined earlier is present on the form error list. Like this

*ngIf="myForm.hasError('emailAndPhoneError')" //true means invalid
Daniel C.
  • 5,418
  • 3
  • 23
  • 26