Дата окончания до даты начала Проверка не работает должным образом в Angular Project - PullRequest
0 голосов
/ 24 января 2020

Я столкнулся с проблемой, когда мой валидатор даты окончания не работает должным образом. Оно отображает сообщение об ошибке, но только в тех случаях, когда конечная дата меньше, чем минимальная конечная дата, инициализированная при запуске.

Например, у меня минимальная дата окончания текущей даты + 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;
...