3

I'm trying to set user form validation, user must enter either of two fields, mobile or email fields

Add Guest reaction form Html:

<form class="new_guest" id="new_guest" [formGroup]="addGuestForm" (ngSubmit)="onSubmit()">
            <div class="form-group">
                <input placeholder="Enter guest name" class="add-guests form-control ui-autocomplete-input" type="text" formControlName="name"
                    id="guest_name" autocomplete="off">
            </div>
            <div class="form-group">
                <input placeholder="Enter guest email" class="add-guests form-control ui-autocomplete-input" type="text" formControlName="email"
                    id="guest_email" autocomplete="off">
            </div>
            <div class="form-group">
                <input placeholder="Mobile Number, If any" class="add-guests form-control ui-autocomplete-input" type="text" formControlName="mobile"
                    id="guest_mobile" autocomplete="off">
            </div>
            <input type="submit" class="btn btn-default btn-block" id="add_guest" value="ADD GUEST" [disabled]="!addGuestForm.valid">
        </form

AddGuest init:

this.addGuestForm = new FormGroup({
  'name': new FormControl(null, Validators.required),
  'email': new FormControl(null, Validators.email),
  'mobile': new FormControl(null)
})

Can anyone help?

3 Answers3

6

You can use form builder and provide customized validation for example:

this.addGuestForm = this.formBuilder.group({
'name': new FormControl(null, Validators.required),
  'email': '',
  'mobile': ''
}, {
      validator: (formControl) => {
        var emailCtrl = formControl.controls.email;
        var mobileCtrl = formControl.controls.mobile;


        if (emailCtrl != undefined && mobileCtrl != undefined)
             if(!(emailCtrl.value.length || mobileCtrl.value.length ))
                    return {invalid: true};
}
});

additionally you can also check for regex for email field define a variable regexPattern for email pattern check and use below in the custom validator if condition

regexPattern.test(emailCtrl.value)
Sheetal
  • 1,368
  • 1
  • 9
  • 15
1

I had the same problem, my solution is a writing a custom validator:

export function oneOfControlRequired(...controls: AbstractControl[]): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
        for (const aControl of controls) {
          if (!Validators.required(aControl)) {
            return null;
          }
        }
        return { oneOfRequired: true };
     };
}

and you could use like that:

this.addGuestForm.setValidators([
  oneOfControlRequired(
      this.addGuestForm.get('email'),
      this.addGuestForm.get('mobile'),
  )
]);

maybe you want to slightly modify the oneOfControlRequired function to take controlNames: string[] as input param not AbstractControl[]

you can check the working example here.

pogiaron
  • 332
  • 3
  • 5
0

I've slightly changed the answer of @pogiaron So you can set the error key returned.

static oneControlRequired(errorKey: string, ...controls: AbstractControl[]) {
    return (control: AbstractControl): ValidationErrors | null => {
        for (const aControl of controls) {
          if (!Validators.required(aControl)) {
            return null;
          }
        }
        return { [errorKey]: true };
     };
}
Bas van Dijk
  • 9,933
  • 10
  • 55
  • 91