Angular - assign custom validator to a FormGroup
Solution 1
I've created a stackblitz take a look.
In the component.ts file
import { Component } from '@angular/core';
import {FormBuilder,FormGroup, ValidationErrors, ValidatorFn} from '@angular/forms'
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
myForm: FormGroup;
defaultValue = 20;
constructor(private formBuilder: FormBuilder) {
this.myForm = this.formBuilder.group({
myControl1: this.defaultValue,
myControl2: this.defaultValue
});
debugger
this.myForm.setValidators(this.comparisonValidator())
}
public comparisonValidator() : ValidatorFn{
return (group: FormGroup): ValidationErrors => {
const control1 = group.controls['myControl1'];
const control2 = group.controls['myControl2'];
if (control1.value !== control2.value) {
control2.setErrors({notEquivalent: true});
} else {
control2.setErrors(null);
}
return;
};
}
}
In the component.html file
<div>
<form [formGroup]="myForm">
<input formControlName="myControl1" type="number">
<input formControlName="myControl2" type="number">
<br>Errors: {{myForm.get('myControl2').errors | json}}
</form>
</div>
Solution 2
For setting any validators (predefined or customs) after the instantiating the formGroup, you will need to use the setValiators() method of FormGroup. For Ex:
let myFormGroup = this. _fb.group({
control1: new FormControl('1', [])
});
myFormGroup.setValidators(this.customValidators());
customValidators(): ValidatorFn {
let myFun = (cc: FormGroup): ValidationErrors => {
if(cc.valid) return null;
else return {something: 'someError'};
};
return myFun;
}
Solution 3
Thanks to @Anuradha Gunasekara - his answer is the most correct and complete solution. A 'quick fix' for my error was just to add a return type of any
on the validator. I can still assign the custom validator to the FormGroup
, and the FormGroup
will be passed implicitly as the argument to my custom validator. This code will work:
let myForm : FormGroup;
myForm = this.formBuilder.group({
myControl1: defaultValue,
myControl2: defaultValue
})
this.myForm.validator = this.comparisonValidator;
comparisonValidator(g: FormGroup) : any {
if (g.get('myControl1').value > g.get('myControl2'.value)) {
g.controls['myControl1'].setErrors({ 'value2GreaterThanValue1': true });
}
}
Solution 4
Remove all form control white space form Form Group
custom validator :
export function formGroupRemoveWhitespaceValidator(form: FormGroup): ValidationErrors | null {
const keys: string[] = Object.keys(form.controls);
if (keys.length) {
keys.forEach(k => {
let control = form.controls[k];
if (control && control.value && !control.value.replace(/\s/g, '').length) {
control.setValue('');
}
});
}
return null;
}
component :
let myForm : FormGroup;
myForm = this.formBuilder.group({
myControl1: defaultValue,
myControl2: defaultValue
}, { validators: formGroupRemoveWhitespaceValidator });
Related videos on Youtube
Comments
-
Chris Halcrow about 2 years
I need to assign a custom validator to a FormGroup. I can do this at the time the FormGroup is created like this:
let myForm : FormGroup; myForm = this.formBuilder.group({ myControl1: defaultValue, myControl2: defaultValue }, { validator: this.comparisonValidator }) comparisonValidator(g: FormGroup) { if (g.get('myControl1').value > g.get('myControl2'.value)) { g.controls['myControl1'].setErrors({ 'value2GreaterThanValue1': true }); return; } }
I have a situation though where I need to add the custom validator after I've instantiated the FormGroup, so I'm trying to do this after instantiating
myForm
, instead of adding the validator when the form is instantiated:let myForm : FormGroup; myForm = this.formBuilder.group({ myControl1: defaultValue, myControl2: defaultValue }) this.myForm.validator = this.comparisonValidator;
This gives me a compiler error:
Type '(g: FormGroup) => void' is not assignable to type 'ValidatorFn'. Type 'void' is not assignable to type 'ValidationErrors'.
How do I assign a validator to my
FormGroup
so that theformGroup
is passed as the argument to mycomparisonValidator
function?Update - I've added a line showing where I'm doing a
setErrors
in mycomparisonValidator
, to make it clearer exactly how I'm trying to set a validation error.-
Keshan Nageswaran almost 6 yearsAdding dynamic validator can be done using setValidators(). but specific for a particular control you can update at a time
-
Crisu83 almost 4 yearsYou get this error because you return
void
from yourcomparisonValidator
function. Change the function to returnnull
on the last line (not inside the if-statement) and the error should be gone.
-
-
Chris Halcrow almost 6 yearsThanks Anuradha. To clarify what I'm asking, I'm trying to only add the validator after the
FormGroup
is instantiated, instead of adding it when the form is instantiated. I've edited the question a little to make it clearer. -
Abhishek Jaiswal almost 6 yearsBetter solution than returning any from validator.
-
Anuradha Gunasekara almost 6 years@ChrisHalcrow I've updated the ansewer take alook. nd You can find a working example in here.