Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement MD_DATE_FORMATS for datepicker?

I'm trying to implement my own date format for shiny new datepicker from material2. According to documentation i have to provide my version of MD_DATE_FORMATS:

providers: [
  {provide: DateAdapter, useValue: NativeDateAdapter },
  {provide: MD_DATE_FORMATS, useValue: MY_DATE_FORMATS },
],

When I use default implementation:

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

I get an error that date input is null. But what type it really is? Documentation says any.

If i try to put some dummy function there i get error: _dateAdapter.parse is not a function.

function dateInput() {
    return 'ddd';
}
const MY_DATE_FORMATS: MdDateFormats = Object.assign({}, MD_NATIVE_DATE_FORMATS, {parse: dateInput });

How to make it work?

like image 979
charlie_pl Avatar asked May 26 '17 11:05

charlie_pl


3 Answers

Many thanks to @MariusR who pushed the solution. As stated you need to provide your own date adapter. From the plunkr, this is as simple as follows:

export class OurDateAdapter extends NativeDateAdapter {
  parse(value: any): Date | null {
    if ((typeof value === 'string') && (value.indexOf('/') > -1)) {
      const str = value.split('/');
      return new Date(Number(str[2]), Number(str[1])-1, Number(str[0]), 12);
    }
    const timestamp = typeof value === 'number' ? value : Date.parse(value);
    return isNaN(timestamp) ? null : new Date(timestamp);
  }
}

This can be any of your TS files and just needs to be provided in the module of your component with the date picker:

  providers: [
    {provide: DateAdapter, useClass: OurDateAdapter}
  ]

In your component you need to use it in the constructor:

  constructor(private dateAdapter: DateAdapter<Date>) {
    this.dateAdapter.setLocale('en-GB');
  }

The list of locales can be gathered here, the plunkr example uses Portuguese, mine is UK English.

http://www.i18nguy.com/unicode/language-identifiers.html

MariusR, take a bow, why can't the official docs have this?

like image 105
PeterS Avatar answered Oct 10 '22 12:10

PeterS


Angular implementation uses Javascript date implementation by default, which means that you probably would like to create your own MdDateFormats and DateAdapter implementation in order to get a custom representation of the date. As @MariusR said:

In your code you should replace the

{provide: DateAdapter, useValue: NativeDateAdapter }, with

{provide: DateAdapter, useClass: NativeDateAdapter },

I've made a project showing how to implement custom MdDateFormats and DateAdapter (implementing dates to fit 'es-UY' locale). It uses Moment.js to represent other date formats, and the implementation it's fully customizable to fit your needs. Custom locale files are here.

like image 45
Ignacio Rossi Avatar answered Oct 10 '22 11:10

Ignacio Rossi


In your code you should replace the

{provide: DateAdapter, useValue: NativeDateAdapter },

with

{provide: DateAdapter, useClass: NativeDateAdapter },

as the NativeDateAdapter is a class and not a constant.

This should resolve your problem with the .parse is not a function error.

I couldn't replicate the date input is null error though. Could be due to the same useClass problem but if you still encounter an error you could define the dateInput like

parse: {
  dateInput: {year: 'numeric', month: 'numeric', day: 'numeric'},
},

or a variation of

parse: {
  dateInput: 'YYYY-MM-DD',
},
like image 1
MariusR Avatar answered Oct 10 '22 12:10

MariusR