20
votes

I am using angular material datepicker directive and I have few problems.

1. When I open date picker dialog and select any date, date shows up in input text box, but I want to call a function when ever any change occur in input text box.

Right now if I manually enter any value in input text box, I am triggering function using (input) directive and it is working fine as shown in code. I want to trigger same function when date gets change using date picker dialog.

2. I also want to change the format of date from mm/dd/yyyy to dd/mm/yyyy when selected from date picker dialog. Here mm/dd/yyyy is set by default in this directive.

<input matInput [matDatepicker]="organizationValue" formControlName="organizationValue" (input)="orgValueChange(i)">
<mat-datepicker-toggle matSuffix [for]="organizationValue"></mat-datepicker-toggle>                 
<mat-datepicker #organizationValue></mat-datepicker>
5
Please close your question by clicking the checkmark to the left of the answer that helped you mostVikas

5 Answers

32
votes

from docs you can use one of the below events based on your requirement

@Output()
dateChange(): EventEmitter<MatDatepickerInputEvent<D>>

Emits when a change event is fired on this .

@Output()
dateInput(): EventEmitter<MatDatepickerInputEvent<D>>

Emits when an input event is fired on this .

For example:

<input matInput #ref [matDatepicker]="organizationValue" formControlName="organizationValue" (dateChange)="orgValueChange(ref.value)">

or

 <input matInput #ref [matDatepicker]="organizationValue" formControlName="organizationValue" (dateInput)="orgValueChange(ref.value)">
12
votes
  1. In your html you can use (ngModelChange)="functionName()" to trigger any function with the change of the date and declare the function in your ts.

  2. To change the format of the date :

Add this to app.module.ts:

import{MatDateFormats, MAT_DATE_FORMATS, NativeDateAdapter, DateAdapter} from '@angular/material';

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

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 `${day}/${month}/${year}`;
        } else {
            return date.toDateString();
        }
    }
}

Add the below in providers of app.module.ts:

{provide: DateAdapter, useClass: AppDateAdapter},  
{provide: MAT_DATE_FORMATS, useValue: MY_DATE_FORMATS}
7
votes

I am working in Angular 7 and implementation is as follows.

Declare an event in your class:

@Output() 
dateChange:EventEmitter< MatDatepickerInputEvent< any>>;

Remember you should have the material module already installed. Create one method in typescript file as follows.

someMethodName(date: any) {  
    // your code here
}

Your html file matInput will be:

<input matInput [matDatepicker]="enddate" placeholder="" 
(dateChange)="someMethodName($event)" formControlName="EndDate">
2
votes

Here is what I did, Angular 9 :

html:

  <input
    matInput
    [matDatepicker]="picker"
    (dateChange)="onDateChange()"
  />

ts:

@Output()
dateChange: EventEmitter<MatDatepickerInputEvent<any>> = new EventEmitter();

onDateChange(): void {
    this.dateChange.emit();
}
0
votes

There seems to be a deficiency in the MatDatePicker, so that if you first clear the date (if it has a value), go to another field, then edit the field with manual input (without using the date picker), and leave the field, the month and the day are switched. In order to correct this behaviour, you have to define the "parse" method in addition to the "format" method in the AppDateAdapter class (see the answer of Rak2018):

parse(value: any): Date | null {
    const vals = value.split('.'); // or '-' if you use - as separator
    if (vals.length !== 3 || parseInt(vals[2] < 1900) return null;
    return new Date(parseInt(vals[2]), parseInt(vals[1]) - 1, parseInt(vals[0]));
}

What I mean by deficiency is that normally, you could define in providers something like

{ provide: MAT_DATE_LOCALE, useValue: 'de' }

and that works except in the case described above. So the problem is that the default "parse" method does not obey this MAT_DATE_LOCALE setting.

See also How to implement MD_DATE_FORMATS for datepicker?