Miomir Dancevic
Miomir Dancevic

Reputation: 6852

ReactiveForms Angular validation

I have some reactive form like this:

this.form = this.formBuilder.group({
      filter: [''],
      filterReason: [''],
      documentsRequired: [''],
      urgencyReason: [''],
      reportRequestedDate: [''],
      urgencyDate: [''],
      urgencyRemarks: ['']
    });

And some value like this:

validation = false;

The problem I have is that i need to toggle value of that validation in html, and based on that if validation = true i need to add validation to some field that will look like this:

this.form = this.formBuilder.group({
      filter: [''],
      filterReason: [''],
      documentsRequired: [''],
      urgencyReason: [''],
      reportRequestedDate: ['', Validation.required],
      urgencyDate: ['', Validation.required],
      urgencyRemarks: ['', Validation.required]
    });

How to do that even i have init form on rendering the component?

Upvotes: 1

Views: 134

Answers (3)

jo_va
jo_va

Reputation: 13983

Here is a complete StackBlitz with ReactiveForms and dynamic validation.

The idea is to have a setter on the validation property so you can toggle the validators each time the property is set using myControl.setValidators(validate ? [Validators.required] : null) and then updating its validity state by calling myControl.updateValueAndValidity()

Two methods are important on your FormControl here:

  • setValidators()
  • updateValueAndValidity()
import { Component } from '@angular/core';
import { FormBuilder, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  form: any;
  private _validation = true;

  constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.group({
        filter: ['Hello'],
        filterReason: ['Test'],
        documentsRequired: ['Document'],
        urgencyReason: ['Nothing'],
        reportRequestedDate: [''],
        urgencyDate: ['Today'],
        urgencyRemarks: ['']
      });
      this.setValidators(this.validation);
  }

  set validation(validate: boolean) {
    this._validation = validate;
    this.setValidators(validate);
  }
  get validation(): boolean {
    return this._validation;
  }

  setValidators(validate: boolean): void {
    this.reportRequestedDate.setValidators(validate ? [Validators.required] : null);
    this.reportRequestedDate.updateValueAndValidity();

    this.urgencyDate.setValidators(validate ? [Validators.required] : null);
    this.reportRequestedDate.updateValueAndValidity();

    this.urgencyRemarks.setValidators(validate ? [Validators.required] : null);
    this.urgencyRemarks.updateValueAndValidity();
  }

  onSubmit(): void {
    if (this.form.valid) {
      console.log(this.form.value);
    }
  }

  get reportRequestedDate(): FormControl {
    return this.form.get('reportRequestedDate') as FormControl;
  }

  get urgencyDate(): FormControl {
    return this.form.get('urgencyDate') as FormControl;
  }

  get urgencyRemarks(): FormControl {
    return this.form.get('urgencyRemarks') as FormControl;
  }
}

Hope that helps!

Upvotes: 1

Bar Gans
Bar Gans

Reputation: 1683

in your html:

<button  (click)="toggleValidation();">toggle validation

</button>

in your ts:

    toggleValidation(validation : boolean)
Object.keys(this.form).forEach(key=> {
this.form.get(key).setValidators(validation && key.*your condition* ? Validators.required : null); });}

Upvotes: 0

yurzui
yurzui

Reputation: 214315

Angular exposes us setValidators method on AbstractControl so you can change validators set based on your condition:

onValidationChanged(validation: boolean) {
  ['reportRequestedDate', 'urgencyDate', 'urgencyRemarks'].forEach(name => {
    this.form.get(name).setValidators(validation ? Validators.required : null);
  });
}

Upvotes: 3

Related Questions