Я столкнулся с проблемой, когда мой валидатор даты окончания не работает должным образом. Оно отображает сообщение об ошибке, но только в тех случаях, когда конечная дата меньше, чем минимальная конечная дата, инициализированная при запуске.
Например, у меня минимальная дата окончания текущей даты + 1 месяц (2/24/2020), поэтому ошибка появится только под полем ввода материала Angular, если дата выбрана до 2/24/2020. Однако я хочу, чтобы он отображался только тогда, когда выбранная дата предшествует текущей выбранной дате начала, поскольку у меня отключена функция выбора даты для любых дат до минимальной даты начала. Поэтому правильное поведение будет таким: пользователь выбирает дату начала 26.02.2020, а затем дату окончания 2/24/2020 -> должно быть выдано сообщение об ошибке.
В качестве примечания по порядку чтобы появилось сообщение об ошибке, я должен вручную ввести дату до даты, предшествующей минимальной дате окончания.
Я в растерянности, поэтому я просто собираюсь включить фрагменты кода, которые, по моему мнению, имеют отношение к этой проблеме.
Настраиваемое сопоставление состояния ошибки:
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
return control.parent.invalid && control.touched;
}
}
Пользовательский валидатор:
export function EndDateAfterSelectedStartDate(group: FormGroup) {
const startDate = group.get('startDate').value;
console.log('startDate:', startDate);
const endDate = group.get('endDate').value;
console.log('endDate:', endDate);
if (endDate < startDate) {
console.log('Invalid End Date!');
}
return group.get('endDate').value < group.get('startDate').value ? { EndDateBeforeSelectedStartDate: true } : null;
}
HTML Шаблон:
<div class="ui-g ui-fluid" formGroupName="date">
<div class="ui-g-3"></div>
<!--DATE: START AND END-->
<mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto">
<mat-label>Start Date</mat-label>
<input matInput formControlName="startDate" [min]="minStartDate" [max]="maxStartDate" [matDatepicker]="startPicker">
<mat-error>{{getErrorMessage('startDate')}}</mat-error>
<mat-datepicker-toggle matSuffix [for]="startPicker"></mat-datepicker-toggle>
<mat-datepicker touchUi="true" #startPicker></mat-datepicker>
</mat-form-field>
<mat-form-field class="ui-g-3" appearance="outline" floatLabel="auto">
<mat-label>End Date</mat-label>
<input matInput formControlName="endDate" [min]="minEndDate" [max]="maxEndDate" [matDatepicker]="endPicker">
<mat-error>{{getErrorMessage('endDate')}}</mat-error>
<mat-datepicker-toggle matSuffix [for]="endPicker"></mat-datepicker-toggle>
<mat-datepicker touchUi="true" #endPicker></mat-datepicker>
</mat-form-field>
<p>End Date: {{addPersonForm.get('room').get('date').get('endDate').value}}</p>
<br>
<p>Start Date: {{addPersonForm.get('room').get('date').get('startDate').value}}</p>
<div class="ui-g-3"></div>
</div>
Инициализация минимальных / максимальных дат при запуске:
this.minStartDate = new Date();
this.maxStartDate = new Date(this.minStartDate.getFullYear() + 2, this.minStartDate.getMonth(), this.minStartDate.getDate());
this.minEndDate = new Date(this.minStartDate.getFullYear(), this.minStartDate.getMonth() + 1, this.minStartDate.getDate());
this.maxEndDate = new Date(this.minEndDate.getFullYear() + 3, this.minEndDate.getMonth(), this.minEndDate.getDate());
Инициализация группы форм:
date: this.fb.group({
startDate: ['', [Validators.required]],
endDate: ['', [Validators.required]],
}, {validator: this.endDateAfter}),
GetErrorMessage ():
case 'endDate':
// TODO: Right now, this error is thrown when end date goes below minEndDate
if (room.get('date').hasError('EndDateBeforeSelectedStartDate')) {
return 'End date must be after start date';
}
if (room.get('date').get('endDate').hasError('required')) {
return 'End date / move-out must be provided';
}
break;