I'm working with a dynamic reactive form that takes a json input and builds out a form. I also wrote a custom date validator to check if a date is older than another given date (the date is passed in to the validator) .. and returns an error when the input date by the user is older than the given date. Because of the way the form is built... I'm adding or removing the validator based on a user's prior selection while going through the form (to make the form valid).
This is the code block of me adding the form control and the validator.
`
var newdate = new Date();
this.dynamicForm.addControl(control.name, this.formBuilder.control(control.value, this.beforeDateValidator(newdate)));
`
And this is what the validator looks like...
`
beforeDateValidator(dateValue: Date): ValidatorFn {
console.log('im firing');
return(control: AbstractControl) : ValidationErrors | null => {
const value: Date = control.value;
// console.log(value);
if(!value) {
return null;
}
if (dateValue=== null) {
return null;
}
if (value < dateValue) {
return { beforeDateValidator: 'Invalid Date' }
} else {
return null;
}
}
}
`
The issue is... the validator doesn't fire when the user selects the right values and inputs the date value that's supposed to trigger the invalid date message.
CodePudding user response:
Seem like you try to create new FormControl
with the same name that already exist this.dynamicForm.addControl(control.name ....
.
Solution 1 You may change to use addValidator
to the remain control instead of create new one.
this.form.controls["dynamicForm"].addValidators([this.beforeDateValidator(newdate)]);
Solution 2 Create new one with the name that not exist.
.ts
Object.keys(this.dynamicForm.controls).forEach((control) => {
this.dynamicForm.addControl(
control 'a',
formBuilder.control('', [this.beforeDateValidator(newdate)])
);
});
.html - ensure formControlName
contain the right name as well.
<form [formGroup]="dynamicForm" (ngSubmit)="onSubmit()">
<label for="first-name">First Name: </label>
<input id="first-name" type="text" formControlName="control1a" />
<label for="last-name">Last Name: </label>
<input id="last-name" type="text" formControlName="control2a" />
<button type="submit">Submit</button>
</form>
example: Stackblitz
CodePudding user response:
The custom validator will be triggered, but the problem is the control.value
return a string
value and you compare it with a Date
value. Hence it leads to an unexpected value that the error is not returned which is used to assign the error to the form control.
Place a console.log()
as below and you will find that it prints as string
.
console.log(typeof value);
Hence make sure that you need to convert the control.value
to Date
type before comparing:
if (new Date(value) < dateValue) {
...
}
Note that your current way to add new form control and assign value with a Date, is not working correctly, the form control will not show the assigned date.
You need to format the date from ISOString to "yyyy-MM-dd" format as below:
import { formatDate } from '@angular/common';
this.dynamicForm.addControl(
control.name,
this.formBuilder.control('', this.beforeDateValidator(newdate))
);
this.dynamicForm.controls[control.name].patchValue(
formatDate(control.value, 'yyyy-MM-dd', 'en')
);