3
votes

I have a custom validator function named productionControlValidator.

If I set up the form like this, everything works:

this.validTest = new FormGroup({
    isdrawing: new FormControl(true),
    inventoryControl: new FormControl(null)
}, { validators: productionControlValidator });

However, if I set up the form using a form builder like this:

this.validTest = this.fb.group({
    isdrawing: true,
    inventoryControl: null
}, { validators: productionControlValidator });

where fb is defined in the constructor as private fb: FormBuilder, then the validation does not work. By "does not work", I mean that the valid property of the form is not correct, and in the console I don't see the output I expect (which does show using the first method).

Am I not defining the validator correctly in the second method (and if that is the case, how should it be defined), or is there something about FormBuilder that makes the custom validator not usable?

5

5 Answers

4
votes

Try validator instead of validators for custom validators Documentation:https://angular.io/api/forms/AbstractControl#root

(validator ValidatorFn | null) The function that determines the synchronous validity of this control.

this.validTest = this.fb.group({
    isdrawing: true,
    inventoryControl: null
}, { validator: productionControlValidator });
6
votes

For more info ---> DEMO

Use custom validation service in component

import {CustomValidationService } from './custom.service'

this.validTest = this.fb.group({
    name: [null, [Validators.required, CustomValidationService.nameValidator],
    inventoryControl: [null, [CustomValidation]]
});

You can create custom-validation-service as:

@Injectable()
export class CustomValidationService {
    // Name validation 
        static nameValidator(control: FormControl) {
            if (control.value) {
                const matches = control.value.match(/^[A-Za-z\s]+$/);
                return matches ? null : { 'invalidName': true };
            } else {
                return null;
            }
        }
}
1
votes

Form validation triggers when valueChanges in the formGroup.

Here is the example : Reactive form custom validators

We can trigger a form validation for the entire form once changing the values of the form.

Here is the example class:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';

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

  validTest: FormGroup;
  hasError = false;

  constructor(private fb: FormBuilder) {
  }

  ngOnInit() {
    this.validTest = this.fb.group ({
      isdrawing: [true, [Validators.required]],
      inventoryControl: ['10', [Validators.required, Validators.pattern('[0-9]*')]]
    });

    this.validTest.valueChanges.subscribe(form => {
      if(form) {
        this.productionControlValidator(form);
      }
    });
  }

  private productionControlValidator(form) {
    // custom validations for form controls

    if(form) {
      this.hasError = this.validTest.invalid;
    }
  }
}

Example html template:

<form [formGroup]="validTest">
  <input 
    type="checkbox"
    formControlName="isdrawing"/>

    <input
      type="text"
      formControlName="inventoryControl"
    />

    <div *ngIf="hasError">Form contains errors !!!</div>
</form>
0
votes

If you want group validation method try this as

 validateAllFormFields(formGroup: any) {         //{1}
    Object.keys(formGroup.controls).forEach(field => {  //{2}
      const control = formGroup.get(field);             //{3}
        if (control instanceof FormControl) {             //{4}
         control.markAsDirty({ onlySelf: true });
         } else if (control instanceof FormGroup) {        //{5}
         this.validateAllFormFields(control);            //{6}
      }
   });
}



save(data: any) {
    if (this.validTest.valid) {

    } else {
     this.validateAllFormFields(this.validTest);
  }
}
0
votes

Basically in Angular form Validations are Easy Part.

in app.component.ts file:

you need to add

import { FormGroup, FormBuilder, Validators } from '@angular/forms';

After That

ngOnInit() {

this.registerForm = this.formBuilder.group({

  email: ['', [Validators.required, Validators.email]],

  firstName: ['', Validators.required],

  lastName:['', Validators.required],

  address: ['', Validators.required],

})

}

That's it. Happy coding