ske
ske

Reputation: 5234

How to compose a validation to check if one of two fields is not empty?

So, in myForm, there are 2 fields name and email, I want to add the validation to check if the user input either one of them, it would pass the validation; if both fields are null or empty, it fails.

How to compose such validators to meet my scenario?

<form [formGroup]="myForm" novalidate (ngSubmit)="submit(myForm.value)">
<div class="row">
    <div class="col-md-2"></div>
    <div class="col-md-8">
        <div class="card">
            <div class="card-header my-contact-info">
                My Contact Info
            </div>
            <div class="card-block">
                <div class="row">
                    <div class="col-md-6">
                        <div class="form-group">
                            <label>Name:</label>
                            <small class="alert" *ngIf="!myForm.controls['name'].valid && myForm.controls['name'].touched">This field is required.</small>
                            <input type="text" class="form-control" formControlName="name">
                        </div>
                        <div class="form-group">
                            <label>Email:</label>
                            <small class="alert" *ngIf="!myForm.controls['email'].valid && myForm.controls['email'].touched">This field is required. Please input a valid email.</small>
                            <input type="text" class="form-control" formControlName="email">
                        </div>
                    </div>
                    <div class="col-md-6">

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

    buildForm(): void {
    this.myForm = this._fb.group({
        'name': [null, Validators.compose([Validators.required, Validators.minLength(3)])],
        'email': [null, Validators.compose([Validators.required, Validators.email])]
    });
}

Upvotes: 2

Views: 9180

Answers (1)

Chrillewoodz
Chrillewoodz

Reputation: 28318

I would create a custom validator for this, something like:

import {FormControl, FormGroup, ValidatorFn} from '@angular/forms';
import {Observable} from 'rxjs/Observable';

export const OneFilledOutValidator = (): ValidatorFn => {

  return (group: FormGroup): {[key: string]: boolean} => {

    const fields = [];

    for (const field in group.controls) {

      if (group.controls.hasOwnProperty(field)) {
        fields.push(group.get(field).value);
      }
    };

    const result = fields.filter(field => !!field);

    const valid = result.length !== 0;

    return valid ? null : {
      oneFilledOut: true
    };
  };
};

This basically takes a form group and checks if any of the controls has a value.

this.myForm = this._fb.group({
    'name': [null, [Validators.minLength(3)]],
    'email': [null, [Validators.email]]
}, OneFilledOutValidator); // I would wrap this in a CustomValidators constant

Upvotes: 6

Related Questions