Currently in Angular 11, I am utilizing reactive forms along with a custom validator. My goal is to trigger an error at the form level whenever a user chooses an EndDate
that precedes the selected StartDate
. This form-level error will serve two purposes: displaying error text on the template and disabling the form submission button.
There are a couple of issues that I am facing:
1. Despite setting an error using the customValidator on the form, the form.status
remains as VALID
, even when there are form.errors
. Why is this happening?
2. When checking for the form's errors in the template, it doesn't seem to work properly. I have a mat-error
element with form.hasErrors('endDateTooSoon')
, but this error message never appears. What could be causing this unexpected behavior?
This is how the form is initialized:
shiftEditorForm = new FormGroup({
shiftTitle: new FormControl('', Validators.required),
shiftStartDate: new FormControl('', Validators.required),
shiftStartTime: new FormControl('', Validators.required),
shiftEndDate: new FormControl('', Validators.required),
shiftEndTime: new FormControl('', Validators.required),
}, DateValidators.compareDates('shiftStartDate', 'shiftEndDate', { endDateTooSoon: true})
);
The following code snippet represents the validator being used:
static compareDates = (
dateField1: string,
dateField2: string,
validatorField: { [key: string]: boolean }): ValidatorFn => {
return (control: AbstractControl): { [key: string]: boolean } | null => {
const date1 = control.get(dateField1)?.value;
const date2 = control.get(dateField2)?.value;
if (date1 && date2 && date1 > date2) {
return validatorField;
}
return null;
};
}
When the validator is functioning correctly, the form should look like this:
https://i.sstatic.net/wiypQ.png
I'm encountering issues with the template block defining the shiftStartDate
formControl:
<mat-form-field class="date-selection"
appearance="outline">
<input matInput
[matDatepicker]="startDate"
formControlName="shiftStartDate">
<mat-datepicker-toggle matSuffix [for]="startDate"></mat-datepicker-toggle>
<mat-datepicker #startDate></mat-datepicker>
<mat-error *ngIf="shiftStartDate?.touched && !shiftStartDate?.value">
Shift start date is required.
</mat-error>
<mat-error *ngIf="shiftEditorForm?.hasError('endDateTooSoon')">
End date must be after start date.
</mat-error>
</mat-form-field>
Even though I am checking with
*ngIf="shiftEditorForm.hasError()
, the error is not being displayed as intended.
A similar template block exists for the shiftEndDate
formControl as well, but unfortunately, the error does not display correctly when the shiftEndDate
is set before the shiftStartDate
:
https://i.sstatic.net/6cSTt.png
Update: Upon further investigation, I discovered another issue: while the formGroup indicates a status of VALID
, the submit button's state (disabled
attribute) is indeed being toggled based on the validity check related to the dates. The
[disabled]="this.shiftEditorForm.invalid"
attribute on the button seems to work despite the contradictory status of the form. Quite perplexing!