Shkelqim Maxharraj
Shkelqim Maxharraj

Reputation: 115

How to require at least one input on Reactive Form Angular

I'm trying to require at least one of inputs, so if a user fills one input remove error from both inputs. This is my HTML

<form [formGroup]=form>

<input formControlName="firstName" matInput required>
<mat-error *ngIf="firstNameControl.hasError('required')"> 
    Name can't be empty
</mat-error>

<input formControlName="lastName" matInput required>
<mat-error *ngIf="lastNameControl.hasError('required')"> 
    Last Name can't be empty
</mat-error>

</form>

And this is my Angular Code

  private buildForm(): void {
    this.form = this.formBuilder.group({
        firstName: [null, Validators.required],
        lastName: [null, Validators.required]
      }
    );
  }


  get firstNameControl(): AbstractControl {
    return this.form.get('firstName');
  }

  get lastNameControl(): AbstractControl {
    return this.form.get('lastName');
  }

I tried clearValidators but for some reason won't work

Upvotes: 3

Views: 4449

Answers (1)

G&#233;r&#244;me Grignon
G&#233;r&#244;me Grignon

Reputation: 4228

clearValidators won't help you as it removes the existing validators of your form.

You need to test the validation of your whole form rather than the validation of each individual formControl (and displaying a message for both might be misleading if only one is required).

Here you need to test if at least one of your formcontrols has a value. As there is not existing built-in validator, you need to create one :

function requireOneControl() {
  return formGroup => {
    if (formGroup.get('firstname').value === '' && formGroup.get('lastname').value === '') {
      return {required: 'at least one of the items is required'}
    }
    return null;
  } 
}

and use it on your formGroup :

form: FormGroup = new FormGroup({
    firstname: new FormControl(''),
    lastname: new FormControl('')
  }, requireOneControl());

using your formGroup in order to test it, you need to check if both controls are empty :

  • if true, there is an error and you return a custom object in order to display a message
  • if false, at least one control has a value and you return null as a successful validation

you can then use it to display an error message inside your template :

<p *ngIf="form.errors">{{form.errors.required}}</p>

Here is a working example : https://stackblitz.com/edit/angular-ivy-yramox?file=src%2Fapp%2Fapp.component.ts

Upvotes: 3

Related Questions