angularangular-materialangular-material-datetimepicker

Can I add accelerators to enter a date in a Angular Material Datepicker field?


I am working on a web application using Angular. Is there a way to add shortcuts/accelerators to the date input? For example, a user should be able to type "+1" and have the input resolve to tomorrow's date. At the very least I would like to be able to set an input of "6-18" to 6-18-2020 instead of 6-18-2001.

I am using Angular 9 and Material 8.


Solution

  • Here is how I solved this in case anyone else has the same issue. This enables dates to be entered via +1 (tomorrow), -1 (yesterday), etc.

    I created a directive...

     export class DateEntryShortcutsDirective {
    // form control bound to datepicker input
      @Input() control: FormControl;
    
      constructor() {}
    
    // listen for change events on the datepicker input
      @HostListener('change', ['$event']) onChange(event: any) {
        this.setDate(event.target.value);
      }
    
      setDate(data) {
        if (typeof data === 'string' && data.length) {
    // if values begins with '+' 
          if (data.substring(0, 1) === '+') {
    // get current date and advance by however many days requested
            const dayDiff = +data.substring(1);
            const date = new Date(
              new Date().getTime() + dayDiff * 24 * 60 * 60 * 1000
            );
    // set the control value to date 
            if (this.control) {
              this.control.setValue(date);
            }
          } else if (data.substring(0, 1) === '-') {
    // if value begins with '-'
    // get current day and subtract days 
            const dayDiff = +data.substring(1);
            const date = new Date(
              new Date().getTime() - dayDiff * 24 * 60 * 60 * 1000
            );
    // set control to date
            if (this.control) {
              this.control.setValue(date);
            }
          }
        }
      }
    }
    

    The directive is then used like so...

    <mat-form-field class="mat-form-field date items">
        <mat-label>Deliver NLT</mat-label>
        <input
          tabindex="{{ 80 + index * 1500 }}"
          matInput
          autocomplete="off"
          [matDatepicker]="receiverNLTDate"
          placeholder="Date NLT"
          formControlName="receiverNoLaterThanDate"
          (dateChange)="onReceiverNoLaterThanChanges()"
          [min]="
            this.data.reference.freightUnits[this.index]
              .receiverRequestedDeliveryDate
          "
          appDateEntryShortcuts
          [control]="receiverNoLaterThanDate"
          />
        <mat-datepicker-toggle
          matSuffix
          [for]="receiverNLTDate"
        ></mat-datepicker-toggle>
        <mat-datepicker #receiverNLTDate></mat-datepicker>
    

    EDIT

    After gaining some more understanding, I now extend Native Date Adapter and override its parse function with my own.