Kyan
Kyan

Reputation: 505

Date picker value not updating in the view until calendar is opened

I have two date pickers startDate and endDate. I am trying to implement basic date validation where the start date cannot be after the end date.

I need to ensure that if the user selects end date which is before the start date - then the start date should change to the selected end date.

I am using (dateChange) event emitter and it changes the value of startDatein the model, however, the field value in the actual view does not update until I interact with the startDate date picker element.

HTML

<mat-form-field>
    <mat-label>Start date</mat-label>
    <input matInput [matDatepicker]="fromDate" [value]="startDate"
        (dateChange)="changeStartDate($event)" [matDatepickerFilter]="startDateFilter">
    <mat-datepicker-toggle matSuffix [for]="fromDate">
        <mat-icon matDatepickerToggleIcon>keyboard_arrow_down</mat-icon>
    </mat-datepicker-toggle>
    <mat-datepicker #fromDate></mat-datepicker>
</mat-form-field>
<mat-form-field>
    <mat-label>End date</mat-label>
    <input matInput [matDatepicker]="toDate" [value]="endDate"
        (dateChange)="changeEndDate($event)" [matDatepickerFilter]="endDateFilter">
    <mat-datepicker-toggle matSuffix [for]="toDate">
        <mat-icon matDatepickerToggleIcon>keyboard_arrow_down</mat-icon>
    </mat-datepicker-toggle>
    <mat-datepicker #toDate></mat-datepicker>
</mat-form-field>

COMPONENT

startDateFilter = (selectedDate: Date | null): boolean => {
  return selectedDate < new Date()  && selectedDate < this.endDate;
}

endDateFilter = (selectedDate: Date | null): boolean => {
  return selectedDate < new Date();
}

changeStartDate(event) {
  this.startDate = event.value;
}

changeEndDate(event) {
  if (event.value < this.startDate) {
    this.startDate.setTime(event.value.getTime());
  }
  this.endDate = event.value;
}

EDIT - variable declarations

endDate = new Date();
startDate = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate()-7);

Upvotes: 1

Views: 2749

Answers (1)

Martin Parenteau
Martin Parenteau

Reputation: 73731

The correction to startDate is not picked up immediately by data binding because the bound value, which is the Date object reference, does not change. You can make sure that the change is detected by creating a new Date object:

changeEndDate(event) {
  if (event.value < this.startDate) {
    this.startDate = new Date(event.value);  // <-- create new Date object
  }
  this.endDate = event.value;
}

See this stackblitz for a demo.

Upvotes: 3

Related Questions