1
1
The datepicker allows users to enter a date either through text input, or by choosing a date from
2
- the calendar. It is made up of several components and directives that work together:
2
+ the calendar. It is made up of several components and directives that work together.
3
3
4
4
<!-- example(datepicker-overview) -->
5
5
6
- ### Current state
7
- Currently the datepicker is in the beginning stages and supports basic date selection functionality.
8
- There are many more features that will be added in future iterations, including:
9
- * Support for datetimes (e.g. May 2, 2017 at 12:30pm) and month + year only (e.g. May 2017)
10
- * Support for selecting and displaying date ranges
11
- * Support for custom time zones
12
- * Infinite scrolling through calendar months
13
- * Built in support for [ Moment.js] ( https://momentjs.com/ ) dates
14
-
15
6
### Connecting a datepicker to an input
7
+
16
8
A datepicker is composed of a text input and a calendar pop-up, connected via the ` matDatepicker `
17
9
property on the text input.
18
10
@@ -41,19 +33,44 @@ can easily be used as a prefix or suffix on the material input:
41
33
```
42
34
43
35
### Setting the calendar starting view
36
+
44
37
By default the calendar will open in month view, this can be changed by setting the ` startView `
45
- property of ` mat-datepicker ` to ` " year" ` . In year view the user will see all months of the year and
38
+ property of ` < mat-datepicker> ` to ` year ` . In year view the user will see all months of the year and
46
39
then proceed to month view after choosing a month.
47
40
48
41
The month or year that the calendar opens to is determined by first checking if any date is
49
42
currently selected, if so it will open to the month or year containing that date. Otherwise it will
50
43
open to the month or year containing today's date. This behavior can be overridden by using the
51
- ` startAt ` property of ` mat-datepicker ` . In this case the calendar will open to the month or year
44
+ ` startAt ` property of ` < mat-datepicker> ` . In this case the calendar will open to the month or year
52
45
containing the ` startAt ` date.
53
46
54
47
<!-- example(datepicker-start-view) -->
55
48
49
+ ### Setting the selected date
50
+
51
+ The type of values that the datepicker expects depends on the type of ` DateAdapter ` provided in your
52
+ application. The ` NativeDateAdapter ` , for example, works directly with plain JavaScript ` Date `
53
+ objects. When using the ` MomentDateAdapter ` , however, the values will all be Moment.js instances.
54
+ This use of the adapter pattern allows the datepicker component to work with any arbitrary date
55
+ representation with a custom ` DateAdapter ` .
56
+ See [ _ Choosing a date implementation_ ] ( #choosing-a-date-implementation-and-date-format-settings )
57
+ for more information.
58
+
59
+ Depending on the ` DateAdapter ` being used, the datepicker may automatically deserialize certain date
60
+ formats for you as well. For example, both the ` NativeDateAdapter ` and ` MomentDateAdapter ` allow
61
+ [ ISO 8601] ( https://tools.ietf.org/html/rfc3339 ) strings to be passed to the datepicker and
62
+ automatically converted to the proper object type. This can be convenient when binding data directly
63
+ from your backend to the datepicker. However, the datepicker will not accept date strings formatted
64
+ in user format such as ` "1/2/2017" ` as this is ambiguous and will mean different things depending on
65
+ the locale of the browser running the code.
66
+
67
+ As with other types of ` <input> ` , the datepicker works with ` @angular/forms ` directives such as
68
+ ` formGroup ` , ` formControl ` , ` ngModel ` , etc.
69
+
70
+ <!-- example(datepicker-value) -->
71
+
56
72
### Date validation
73
+
57
74
There are three properties that add date validation to the datepicker input. The first two are the
58
75
` min ` and ` max ` properties. In addition to enforcing validation on the input, these properties will
59
76
disable all dates on the calendar popup before or after the respective values and prevent the user
@@ -64,8 +81,8 @@ from advancing the calendar past the `month` or `year` (depending on current vie
64
81
65
82
The second way to add date validation is using the ` matDatepickerFilter ` property of the datepicker
66
83
input. This property accepts a function of ` <D> => boolean ` (where ` <D> ` is the date type used by
67
- the datepicker, see section on
68
- [ choosing a date implementation ] ( #choosing-a-date-implementation-and-date-format-settings ) ).
84
+ the datepicker, see
85
+ [ _ Choosing a date implementation _ ] ( #choosing-a-date-implementation-and-date-format-settings ) ).
69
86
A result of ` true ` indicates that the date is valid and a result of ` false ` indicates that it is
70
87
not. Again this will also disable the dates on the calendar that are invalid. However, one important
71
88
difference between using ` matDatepickerFilter ` vs using ` min ` or ` max ` is that filtering out all
@@ -84,38 +101,54 @@ Each validation property has a different error that can be checked:
84
101
* A value that violates the ` matDatepickerFilter ` property will have a ` matDatepickerFilter ` error.
85
102
86
103
### Input and change events
87
- The input's native ` input ` and ` change ` events will only trigger due to user interaction with the
88
- input element; they will not fire when the user selects a date from the calendar popup. Because of
89
- this limitation, the datepicker input also has support for ` dateInput ` and ` dateChange ` events.
90
- These trigger when the user interacts with either the input or the popup.
91
-
92
- ``` html
93
- <input [matDatepicker] =" d" (dateInput) =" onInput($event)" (dateChange) =" onChange($event)" >
94
- <mat-datepicker #d ></mat-datepicker >
95
- ```
104
+
105
+ The input's native ` (input) ` and ` (change) ` events will only trigger due to user interaction with
106
+ the input element; they will not fire when the user selects a date from the calendar popup.
107
+ Therefore, the datepicker input also has support for ` (dateInput) ` and ` (dateChange) ` events. These
108
+ trigger when the user interacts with either the input or the popup.
109
+
110
+ The ` (dateInput) ` event will fire whenever the value changes due to the user typing or selecting a
111
+ date from the calendar. The ` (dateChange) ` event will fire whenever the user finishes typing input
112
+ (on ` <input> ` blur), or when the user chooses a date from the calendar.
113
+
114
+ <!-- example(datepicker-events) -->
115
+
116
+ ### Disabling parts of the datepicker
117
+
118
+ As with any standard ` <input> ` , it is possible to disable the datepicker input by adding the
119
+ ` disabled ` property. By default, the ` <mat-datepicker> ` and ` <mat-datepicker-toggle> ` will inherit
120
+ their disabled state from the ` <input> ` , but this can be overridden by setting the ` disabled `
121
+ property on the datepicker or toggle elements. This can be useful if you want to disable text input
122
+ but allow selection via the calendar or vice-versa.
123
+
124
+ <!-- example(datepicker-disabled) -->
96
125
97
126
### Touch UI mode
127
+
98
128
The datepicker normally opens as a popup under the input. However this is not ideal for touch
99
129
devices that don't have as much screen real estate and need bigger click targets. For this reason
100
- ` mat-datepicker ` has a ` touchUi ` property that can be set to ` true ` in order to enable a more touch
101
- friendly UI where the calendar opens in a large dialog.
130
+ ` < mat-datepicker> ` has a ` touchUi ` property that can be set to ` true ` in order to enable a more
131
+ touch friendly UI where the calendar opens in a large dialog.
102
132
103
133
<!-- example(datepicker-touch) -->
104
134
105
135
### Manually opening and closing the calendar
136
+
106
137
The calendar popup can be programmatically controlled using the ` open ` and ` close ` methods on the
107
- ` mat-datepicker ` . It also has an ` opened ` property that reflects the status of the popup.
138
+ ` < mat-datepicker> ` . It also has an ` opened ` property that reflects the status of the popup.
108
139
109
140
<!-- example(datepicker-api) -->
110
141
111
142
### Internationalization
112
- In order to support internationalization, the datepicker supports customization of the following
113
- three pieces via injection:
114
- 1 . The date implementation that the datepicker accepts.
115
- 2 . The display and parse formats used by the datepicker.
116
- 3 . The message strings used in the datepicker's UI.
143
+
144
+ Internationalization of the datepicker is configured via four aspects:
145
+ 1 . The date locale.
146
+ 2 . The date implementation that the datepicker accepts.
147
+ 3 . The display and parse formats used by the datepicker.
148
+ 4 . The message strings used in the datepicker's UI.
117
149
118
150
#### Setting the locale code
151
+
119
152
By default, the ` MAT_DATE_LOCALE ` injection token will use the existing ` LOCALE_ID ` locale code
120
153
from ` @angular/core ` . If you want to override it, you can provide a new value for the
121
154
` MAT_DATE_LOCALE ` token:
@@ -131,28 +164,25 @@ export class MyApp {}
131
164
132
165
It's also possible to set the locale at runtime using the ` setLocale ` method of the ` DateAdapter ` .
133
166
134
- ``` ts
135
- import { DateAdapter , NativeDateAdapter } from ' @angular/material' ;
136
-
137
- @Component ({
138
- selector: ' foo' ,
139
- template: ' '
140
- })
141
- export class FooComponent {
142
- constructor (dateAdapter : DateAdapter <NativeDateAdapter >) {
143
- dateAdapter .setLocale (' de-DE' );
144
- }
145
- }
146
- ```
167
+ <!-- example(datepicker-locale) -->
147
168
148
169
#### Choosing a date implementation and date format settings
170
+
149
171
The datepicker was built to be date implementation agnostic. This means that it can be made to work
150
172
with a variety of different date implementations. However it also means that developers need to make
151
173
sure to provide the appropriate pieces for the datepicker to work with their chosen implementation.
152
- The easiest way to ensure this is just to import one of the pre-made modules (currently
153
- ` MatNativeDateModule ` is the only implementation that ships with material, but there are plans to add
154
- a module for Moment.js support):
155
- * ` MatNativeDateModule ` - support for native JavaScript Date object
174
+ The easiest way to ensure this is just to import one of the pre-made modules:
175
+
176
+ | Module | Date type| Supported locales | Dependencies | Import from |
177
+ | ---------------------| ---------| -----------------------------------------------------------------------| ----------------------------------| ----------------------------------|
178
+ | ` MatNativeDateModule ` | ` Date ` | en-US | None | ` @angular/material ` |
179
+ | ` MatMomentDateModule ` | ` Moment ` | [ See project] ( https://github.com/moment/moment/tree/develop/src/locale ) | [ Moment.js] ( https://momentjs.com/ ) | ` @angular/material-moment-adapter ` |
180
+
181
+ * Please note: ` MatNativeDateModule ` is based off of the functionality available in JavaScript's
182
+ native ` Date ` object, and is thus not suitable for many locales. One of the biggest shortcomings of
183
+ the native ` Date ` object is the inability to set the parse format. We highly recommend using the
184
+ ` MomentDateAdapter ` or a custom ` DateAdapter ` that works with the formatting/parsing library of your
185
+ choice.*
156
186
157
187
These modules include providers for ` DateAdapter ` and ` MAT_DATE_FORMATS `
158
188
@@ -175,16 +205,14 @@ export class MyComponent {
175
205
}
176
206
```
177
207
178
- * Please note: ` MatNativeDateModule ` is based off of the functionality available in JavaScript's
179
- native ` Date ` object, and is thus not suitable for many locales. One of the biggest shortcomings of
180
- the native ` Date ` object is the inability to set the parse format. We highly recommend using a
181
- custom ` DateAdapter ` that works with the formatting/parsing library of your choice.*
208
+ <!-- example(datepicker-moment) -->
182
209
183
- #### Customizing the date implementation
184
- The datepicker does all of its interaction with date objects via the ` DateAdapter ` . Making the
185
- datepicker work with a different date implementation is as easy as extending ` DateAdapter ` , and
186
- using your subclass as the provider. You will also want to make sure that the ` MAT_DATE_FORMATS `
187
- provided in your app are formats that can be understood by your date implementation.
210
+ It is also possible to create your own ` DateAdapter ` that works with any date format your app
211
+ requires. This is accomplished by subclassing ` DateAdapter ` and providing your subclass as the
212
+ ` DateAdapter ` implementation. You will also want to make sure that the ` MAT_DATE_FORMATS ` provided
213
+ in your app are formats that can be understood by your date implementation. See
214
+ [ _ Customizing the parse and display formats_ ] ( #customizing-the-parse-and-display-formats ) for more
215
+ information about ` MAT_DATE_FORMATS ` . <!-- TODO(mmalerba): Add a guide about this -->
188
216
189
217
``` ts
190
218
@NgModule ({
@@ -198,24 +226,30 @@ export class MyApp {}
198
226
```
199
227
200
228
#### Customizing the parse and display formats
229
+
201
230
The ` MAT_DATE_FORMATS ` object is just a collection of formats that the datepicker uses when parsing
202
231
and displaying dates. These formats are passed through to the ` DateAdapter ` so you will want to make
203
232
sure that the format objects you're using are compatible with the ` DateAdapter ` used in your app.
204
- This example shows how to use the native ` Date ` implementation from material, but with custom
205
- formats.
233
+
234
+ If you want use one of the ` DateAdapters ` that ships with Angular Material, but use your own
235
+ ` MAT_DATE_FORMATS ` , you can import the ` NativeDateModule ` or ` MomentDateModule ` . These modules are
236
+ identical to the "Mat"-prefixed versions (` MatNativeDateModule ` and ` MatMomentDateModule ` ) except
237
+ they do not include the default formats. For example:
206
238
207
239
``` ts
208
240
@NgModule ({
209
- imports: [MatDatepickerModule ],
241
+ imports: [MatDatepickerModule , NativeDateModule ],
210
242
providers: [
211
- {provide: DateAdapter , useClass: NativeDateAdapter },
212
243
{provide: MAT_DATE_FORMATS , useValue: MY_NATIVE_DATE_FORMATS },
213
244
],
214
245
})
215
246
export class MyApp {}
216
247
```
217
248
249
+ <!-- example(datepicker-formats) -->
250
+
218
251
#### Localizing labels and messages
252
+
219
253
The various text strings used by the datepicker are provided through ` MatDatepickerIntl ` .
220
254
Localization of these messages can be done by providing a subclass with translated values in your
221
255
application root module.
@@ -229,7 +263,9 @@ application root module.
229
263
})
230
264
export class MyApp {}
231
265
```
266
+
232
267
### Accessibility
268
+
233
269
The ` MatDatepickerInput ` directive adds ` aria-haspopup ` attribute to the native input element, and it
234
270
triggers a calendar dialog with ` role="dialog" ` .
235
271
@@ -238,6 +274,7 @@ should have a placeholder or be given a meaningful label via `aria-label`, `aria
238
274
` MatDatepickerIntl ` .
239
275
240
276
#### Keyboard shortcuts
277
+
241
278
The keyboard shortcuts to handle datepicker are:
242
279
243
280
| Shortcut | Action |
@@ -278,3 +315,30 @@ In year view:
278
315
| ` PAGE_DOWN ` | Go to next year |
279
316
| ` ALT ` + ` PAGE_DOWN ` | Go to next 10 years |
280
317
| ` ENTER ` | Select current month |
318
+
319
+ ### Troubleshooting
320
+
321
+ #### Error: MatDatepicker: No provider found for DateAdapter/MAT_DATE_FORMATS
322
+
323
+ This error is thrown if you have not provided all of the injectables the datepicker needs to work.
324
+ The easiest way to resolve this is to import the ` MatNativeDateModule ` or ` MatMomentDateModule ` in
325
+ your application's root module. See
326
+ [ _ Choosing a date implementation_ ] ( #choosing-a-date-implementation-and-date-format-settings ) ) for
327
+ more information.
328
+
329
+ #### Error: A MatDatepicker can only be associated with a single input
330
+
331
+ This error is thrown if more than one ` <input> ` tries to claim ownership over the same
332
+ ` <mat-datepicker> ` (via the ` matDatepicker ` attribute on the input). A datepicker can only be
333
+ associated with a single input.
334
+
335
+ #### Error: Attempted to open an MatDatepicker with no associated input.
336
+
337
+ This error occurs if your ` <mat-datepicker> ` is not associated with any ` <input> ` . To associate an
338
+ input with your datepicker, create a template reference for the datepicker and assign it to the
339
+ ` matDatepicker ` attribute on the input:
340
+
341
+ ``` html
342
+ <input [matDatepicker] =" picker" >
343
+ <mat-datepicker #picker ></mat-datepicker >
344
+ ```
0 commit comments