Search code examples
angularangular5angular6angular-forms

How to write mulliple validators function in one form (Reactive Forms) in angular?


I am using Reactive forms

My form is like this

this.fb.group({
            percentAllocation: [''],
            constantPercent: [''],
            allocStartDate: [''],
            allocEndDate: [''],
                   },  { validator: this.percentageValidator('percentAllocation', 'constantPercent'))

I need to two types of validation

1) allocStartDate < allocEndDate

2)percentAllocation > constantPercent

Thease two above validations are dependeing two form controles each other. I try to write validation like this

 percentageValidator(rowPercentage, constantPercent) {
    return (group: FormGroup): { [key: string]: any } => {
        let r = group.controls[rowPercentage];
        let c = group.controls[constantPercent]
        if (r.value > c.value) {
            return {
                percentage: true
            };
        }
        return {};
    }
}

dateLessThan(from: string, to: string) {

    console.log(from, to)
    return (group: FormGroup): { [key: string]: any } => {
        let f = group.controls[from];
        let t = group.controls[to];
        if (f.value > t.value) {
            return {
                dates: true
            };
        }
        return {};
    }
}

Please help me to put multiple for validation , and error message should be through form ts only


Solution

  • Why go for the complicated solution when there exists an easier and better one.

    I prefer the below approach To Compare two controls inside Custom Validator

    Component

      constructor(private fb: FormBuilder) { }
      public myForm: FormGroup;
      ngOnInit() {
        this.myForm = new FormGroup({
          percentAllocation: new FormControl('21'),
          constantPercent: new FormControl('26', this.percentageValidator),
          allocStartDate: new FormControl('', this.dateLessThan),
          allocEndDate: new FormControl(''),
        })
        this.myForm.statusChanges.subscribe(val => console.log(val))
      }
    
      percentageValidator(control: FormControl): { [key: string]: boolean } {
        if (control.parent) {
          let c = Number(control.parent.value['percentAllocation']);
          let r = Number(control.value);
          if (r > c) {
            return {
              'percentage': true
            };
          }
          else return null;
        }
      }
    
      dateLessThan(control: FormControl): { [key: string]: boolean } {
        if (control.parent) {
          let f = control.parent.value['allocEndDate']
          let t = control.value
          if (new Date(f) < new Date(t)) {
            return {
              'dates': true
            };
          }
          else
            return null;
     }
      }
    }
    

    HTML

    <div class="container">
    <form [formGroup]="myForm">
        <div class="form-group">
           <label for="peralloc">percentAllocation</label>
      <input type="text" 
       class="form-control" formControlName="percentAllocation">
        </div>
        <div class="form-group">
           <label for="conper">constantPercent</label>
      <input type="text"  class="form-control" 
      formControlName="constantPercent">
        </div>
        <div class="form-group">
          <label for="allocstart">allocStartDate</label>
      <input type="date"  class="form-control" 
      formControlName="allocStartDate">
        </div>
        <div class="form-group">
            <label for="allocEnd">allocEndDate</label>
     <input  class="form-control" type="date" 
     formControlName="allocEndDate">
        </div>
     <div *ngIf="myForm.get('constantPercent').errors && myForm?.get('constantPercent')?.errors?.percentage">
        😢 percentAllocation should be greater than constantPercent
      </div>
      <div *ngIf="myForm.get('allocStartDate').errors && myForm?.get('allocStartDate')?.errors?.date ">
        😢 end Date should be greater than start Date
      </div>
    </form>
    </div>
    

    Added Bit of Bootstrap ;)

    Live Demo