Red
Red

Reputation: 45

Angular Material date picker format when entered via keyboard only works in Chrome

I'm using the date picker component provided by Angular Material and I've encountered the following issue: if I want to type the date instead of selecting in the following format: "2019.12.20", then it only works in Chrome. I tried it on Edge and Firefox, and the date value is null if I use this format. HOWEVER if I use "-" or "/" instead of " . " so e.g "2019-12-20" then it works without any problems.

I've set my providers to:

providers: [
  { provide: MAT_DATE_LOCALE, useValue: 'hu' },
  { provide: DateAdapter, useClass: AppDateAdapter },
  { provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS }            
]

My DateAdapter is the following:

import { NativeDateAdapter } from '@angular/material';


export class AppDateAdapter extends NativeDateAdapter {

  format(date: Date, displayFormat: Object): string {

    if (displayFormat === 'input') {

      const day = date.getDate();
      const month = date.getMonth() + 1;
      const year = date.getFullYear();

      return `${year}.${month}.${day}`;
    }

    return date.toDateString();
  }
}

export const APP_DATE_FORMATS =
  {
    parse: {
      dateInput: { month: 'short', year: 'numeric', day: 'numeric' },
    },
    display: {
      dateInput: 'input',
      monthYearLabel: { year: 'numeric', month: 'numeric' },
      dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric' },
      monthYearA11yLabel: { year: 'numeric', month: 'long' },
    }
  };

Any idea what's wrong? Please tell me if you need any more information regarding this issue.

Upvotes: 1

Views: 2692

Answers (1)

ic_paty
ic_paty

Reputation: 432

Seems that the problem is with NativeDateAdapter in Edge and IE. Try to use MomentDateAdapter instead.

So quick explanation: use MomentDateAdapter in provider as mentionned in the code below:

TS file

import {Component} from '@angular/core';
import {FormControl} from '@angular/forms';
import {MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS} from '@angular/material-moment-adapter';
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core';

import * as _moment from 'moment';

const moment = _moment;

export const MY_FORMATS = {
  parse: {
    dateInput: ['YYYY.MM.DD', 'YYYY-MM-DD', 'YYYY/MM/DD', 'YYYY MM DD']
  },
  display: {
    dateInput: 'YYYY MMM DD',
    monthYearLabel: 'MMM YYYY',
    dateA11yLabel: 'LL',
    monthYearA11yLabel: 'MMMM YYYY',
  },
};

/** @title Datepicker with custom formats */
@Component({
  selector: 'datepicker-formats-example',
  templateUrl: 'datepicker-formats-example.html',
  styleUrls: ['datepicker-formats-example.css'],
  providers: [
     { provide: MAT_DATE_LOCALE, useValue: 'hu' },
    {
      provide: DateAdapter,
      useClass: MomentDateAdapter,
      deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS]
    },
    {provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
  ],
})
export class DatepickerFormatsExample {
  date = new FormControl(moment());
}

HTML file

<mat-form-field>
  <input matInput [matDatepicker]="dp" placeholder="Verbose datepicker" [formControl]="date">
  <mat-datepicker-toggle matSuffix [for]="dp"></mat-datepicker-toggle>
  <mat-datepicker #dp></mat-datepicker>
</mat-form-field>

In this example above, the date field accepts the following formats as input ['YYYY.MM.DD', 'YYYY-MM-DD', 'YYYY/MM/DD', 'YYYY MM DD'] and then will display them in this format YYYY MMM DD.

Upvotes: 1

Related Questions