Home > Back-end >  Add validators in second input field only if first input field is not empty
Add validators in second input field only if first input field is not empty

Time:08-26

I'm working on a form with Angular Forms and I have hit a deadend where I want to add validation to a second input field only if the first is not empty.

Let's say I have two input fields: name and age. So when something is typed into name, only then age will be set to required. I'm using FormGroup and FormControl for my form and this is how the component file looks like now without validators for age:

class Component implements OnChanges {
  @Input() name: string;
  @Input() age: string; 

  form = new FormGroup({
    name: new FormControl(''),
    age: new FormControl('')
  });

  ngOnChanges(changes) {

    if (changes.name?.currentValue !== changes.name?.previousValue) {
      this.setName(changes.name.currentValue);
    }

    if (changes.age?.currentValue !== changes.age?.previousValue) {
      this.setAge(changes.age.currentValue);
    }
  }

  setName(name) {

    this.form.patchValue({
      name,
    });

    if (name) {
      this.form.get('age').setValidators([
         Validators.required,
         this.form.get('age').validator
      ]);
    } 
    
  }

  setAge(age) {
    this.form.patchValue({
      age,
    });
  }

}

Here's the template:

<custom-input
      label="Name"
      placeholder="name"
      name="name"
      formControlName="name"
></custom-input>

<custom-input
      label="Age"
      placeholder="age"
      name="age"
      formControlName="age"
></custom-input>

CodePudding user response:

You can use the below method!

listen to change event of the form fields you want,then check if the field is filled, then we can toggle the required with the command setValidators then after its updated we can ensure the form is in sync by running the updateValueAndValidity which will revalidate the form!

ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import {
  FormBuilder,
  FormControl,
  FormGroup,
  Validators,
} from '@angular/forms';
import { Subscription } from 'rxjs';
import { pairwise, startWith } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit, OnDestroy {
  name = 'Angular';

  form: FormGroup;
  subscription: Subscription;

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit(): void {
    this.form = this.formBuilder.group({
      control1: [''],
      control2: [''],
    });
  }
  control1Change() {
    const control1 = <FormControl>this.form.get('control1');
    const control2 = <FormControl>this.form.get('control2');
    if (control1.value) {
      control2.setValidators([Validators.required]);
    } else {
      control2.setValidators(null);
    }

    control2.updateValueAndValidity();
  }
  control2Change() {
    const control1 = <FormControl>this.form.get('control1');
    const control2 = <FormControl>this.form.get('control2');
    if (control2.value) {
      control1.setValidators([Validators.required]);
    } else {
      control1.setValidators(null);
    }

    control1.updateValueAndValidity();
  }

  ngOnDestroy(): void {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
}

HTML

<hello name="{{ name }}"></hello>
<form [formGroup]="form">
  <div style="margin-bottom: 1rem">
    <label for="control1">Make Field 2 required</label>
    <input
      id="control1"
      type="text"
      formControlName="control1"
      (change)="control1Change()"
    />
    <span
      *ngIf="form.controls.control1.hasError('required')"
      style="color: red; display: block; margin-top: 0.25rem;"
      >Field 2 is required</span
    >
  </div>
  <div style="margin-bottom: 1rem">
    <label for="control2"> Field 2 </label>
    <input
      id="control2"
      type="text"
      formControlName="control2"
      (change)="control2Change()"
    />
    <span
      *ngIf="form.controls.control2.hasError('required')"
      style="color: red; display: block; margin-top: 0.25rem;"
      >Field 2 is required</span
    >
  </div>
  <div>
    <button type="submit" [disabled]="!form.valid">
      Only enabled when form is valid
    </button>
  </div>
</form>

forked stackblitz

  • Related