I am using angular material 2 Date-Picker component
The only string input it understands is in ISO date format
Ex. "2017-11-13T10:39:28.300Z"
But i want to patch my form control with locale date value
Ex. "11/13/2017, 4:09:46 PM"
So that it output the later format and even expects this format.
How can i do this? Is there a way to not use ISO but custom formats?
Some Thoughts:
Should i write customDateAdaptor?
Update:
https://stackblitz.com/edit/angular-material-moment-adapter-example-bqvm2f
i have tried to implement custom dateAdaptor by extending nativeDateAdaptor
You need to create a class extending NativeDateAdapter (from "@angular/material/core")
If you override the format function you will change the way the date is displayed on the input after selecting a date. The parse function is called when you edit the input value manually, to display a valid date.
See the 2nd comment for more details: https://github.com/angular/material2/issues/5722
EDIT:
I couldn't find a way to format the output so I've wrapped the material datepicker component to a custom component.
This custom component has a 2 way binding on a property to get the date:
@Input() selectedValue
and@Output() selectedValueChange: EventEmitter<any> = new EventEmitter<any>();
A
private _selectedValue;
is set on ngInit, it will contain the datepicker date.Then in the template, the html datepicker input element has
[(ngModel)]="_selectedValue" (dateChange)="onChange($event)"
The
onChange
function gets the datepicker value_selectedValue
, formats it and emit it toselectedValueChange
.The final component looks like this:
you can call Emitter of this module (for example click event) and change model binded to this module to secondary model.
First import moment and set format . https://momentjs.com/
Not sure, if you are already doing this but I found some information that might give you some idea on your implementation.
As of today the
Angular Material Date Module
supports two ways of providing a date valueMatNativeDateModule
andMatMomentDateModule
. TheMatNativeDateModule
acceptsISO 8601
format by default. But since you don't want to useISO
format, I would suggest usingMatMomentDateModule
(Moment.js implementation).When we use the
MatMomentDateModule
the date object is not anymore a JavaScriptDate
object but instead is aMoment.js instance
(take advantage of methods available to a Moment js instance likeformat()
). There are basic to intermediate examples available on Material Date Picker docs page using the Moment.js. Also, once your date is a Moment.js instance, you could overwrite the methods(format, parse.) from MomentDateAdapter instead of native date adapter.You probably need to write a completely new adapter or use the moment adapter.
@angular/material-moment-adapter:5.0.0-rc0
. The moment adapter uses momentjs and allows you much more control on the output format.Moment is also able to parse different input formats.
The
NativeDateAdapter
uses the Intl API to format the output date. You can try to provide a custom MAT_NATIVE_DATE_FORMATS instance but I am not sure how far this gets you.EDIT
You are currently using 2.0.0-beta12 of angular/material, that doesn't fit with your code based on 5.0.0-rc0/master. There are changes in the codebase, especially the deserialize function which is not present in 2.0.0-beta12, that's why it is not being called. If you can't update to angular 5 then look at
MatDatepickerInput.setValue/coerceDateProperty
which sets the date into yourFormControl
.The best solution would be to use ControlValueAccessor and make a custom input component, this will have you in control of input and output of the component.
update:
Here is the reference implementation using this approach reproduced by Moutaz-homsi
https://stackblitz.com/edit/angular-dlxnmx?file=app%2Fcva-date.component.ts