3

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 Answers 5

6

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;
            }
        }
}
Sign up to request clarification or add additional context in comments.

3 Comments

The idea here is that I want to be able to validate the group, not the individual control. The group validator can access multiple controls to perform the validation. When setting it up with new FormGroup(..., the validator accesses everything correctly and correctly validates. I'm not looking to validate a single control.
but group validation is not good idea. you can not categorise the individual custom validation.
Why is group validation not a good idea? It is part of the official angular docs: angular.io/guide/form-validation#cross-field-validation
4

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 });

Comments

1

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>

Comments

0

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);
  }
}

Comments

-4

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

1 Comment

The question was adding custom validators

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.