-
Notifications
You must be signed in to change notification settings - Fork 6.8k
docs(datepicker): update docs and add examples #7837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,10 @@ | ||
The datepicker allows users to enter a date either through text input, or by choosing a date from | ||
the calendar. It is made up of several components and directives that work together: | ||
the calendar. It is made up of several components and directives that work together. | ||
|
||
<!-- example(datepicker-overview) --> | ||
|
||
### Current state | ||
Currently the datepicker is in the beginning stages and supports basic date selection functionality. | ||
There are many more features that will be added in future iterations, including: | ||
* Support for datetimes (e.g. May 2, 2017 at 12:30pm) and month + year only (e.g. May 2017) | ||
* Support for selecting and displaying date ranges | ||
* Support for custom time zones | ||
* Infinite scrolling through calendar months | ||
* Built in support for [Moment.js](https://momentjs.com/) dates | ||
|
||
### Connecting a datepicker to an input | ||
|
||
A datepicker is composed of a text input and a calendar pop-up, connected via the `matDatepicker` | ||
property on the text input. | ||
|
||
|
@@ -41,19 +33,44 @@ can easily be used as a prefix or suffix on the material input: | |
``` | ||
|
||
### Setting the calendar starting view | ||
|
||
By default the calendar will open in month view, this can be changed by setting the `startView` | ||
property of `mat-datepicker` to `"year"`. In year view the user will see all months of the year and | ||
property of `<mat-datepicker>` to `year`. In year view the user will see all months of the year and | ||
then proceed to month view after choosing a month. | ||
|
||
The month or year that the calendar opens to is determined by first checking if any date is | ||
currently selected, if so it will open to the month or year containing that date. Otherwise it will | ||
open to the month or year containing today's date. This behavior can be overridden by using the | ||
`startAt` property of `mat-datepicker`. In this case the calendar will open to the month or year | ||
`startAt` property of `<mat-datepicker>`. In this case the calendar will open to the month or year | ||
containing the `startAt` date. | ||
|
||
<!-- example(datepicker-start-view) --> | ||
|
||
### Setting the selected date | ||
|
||
The type of values that the datepicker expects actually depends on the particular `DateAdapter` that | ||
you're using in your app. For example, when using the `NativeDateAdapter` the datepicker expects | ||
`Date` objects, and when using the `MomentDateAdapter` it expects `Moment` objects. You can also | ||
create your own `DateAdapter` that works with whatever date type you want. (For more information | ||
about this, see the section on | ||
[choosing a date implementation](#choosing-a-date-implementation-and-date-format-settings)). | ||
|
||
Depending on the `DateAdapter` you're using, the datepicker may automatically deserialize certain | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Depending on the |
||
date formats for you as well. For example, both the `NativeDateAdapter` and `MomentDateAdapter` | ||
allow [ISO 8601](https://tools.ietf.org/html/rfc3339) strings to be passed to the datepicker and | ||
automatically converted to the proper object type. This can be convenient when binding data directly | ||
from your backend to the datepicker. However, when possible, you should pass the appropriate object | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If we officially support it should we need to recommend against it? |
||
type. The datepicker will not accept date strings formatted in user format such as `"1/2/2017"` as | ||
this is ambiguous and will mean different things depending on the locale of the browser running the | ||
code. | ||
|
||
As with other types of `<input>`, the datepicker works with `@angular/forms` directives such as | ||
`formGroup`, `formControl`, `ngModel`, etc. | ||
|
||
<!-- example(datepicker-value) --> | ||
|
||
### Date validation | ||
|
||
There are three properties that add date validation to the datepicker input. The first two are the | ||
`min` and `max` properties. In addition to enforcing validation on the input, these properties will | ||
disable all dates on the calendar popup before or after the respective values and prevent the user | ||
|
@@ -84,38 +101,54 @@ Each validation property has a different error that can be checked: | |
* A value that violates the `matDatepickerFilter` property will have a `matDatepickerFilter` error. | ||
|
||
### Input and change events | ||
The input's native `input` and `change` events will only trigger due to user interaction with the | ||
input element; they will not fire when the user selects a date from the calendar popup. Because of | ||
this limitation, the datepicker input also has support for `dateInput` and `dateChange` events. | ||
These trigger when the user interacts with either the input or the popup. | ||
|
||
```html | ||
<input [matDatepicker]="d" (dateInput)="onInput($event)" (dateChange)="onChange($event)"> | ||
<mat-datepicker #d></mat-datepicker> | ||
``` | ||
|
||
The input's native `(input)` and `(change)` events will only trigger due to user interaction with | ||
the input element; they will not fire when the user selects a date from the calendar popup. Because | ||
of this limitation, the datepicker input also has support for `(dateInput)` and `(dateChange)` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't use the word "limitation", since that's the expected native behavior. |
||
events. These trigger when the user interacts with either the input or the popup. | ||
|
||
The `(dateInput)` event will fire whenever the value changes due to the user typing or selecting a | ||
date from the calendar. The `(dateChange)` event will fire whenever the user finishes typing input | ||
(on `<input>` blur), or when the user chooses a date from the calendar. | ||
|
||
<!-- example(datepicker-events) --> | ||
|
||
### Disabling parts of the datepicker | ||
|
||
As with any standard `<input>`, it is possible to disable the datepicker input by adding the | ||
`disabled` property. By default, the `<mat-datepicker>` and `<mat-datepicker-toggle>` will inherit | ||
their disabled state from the `<input>`, but this can be overridden by setting the `disabled` | ||
property on the datepicker or toggle elements. This can be useful if you want to disable text input | ||
but allow selection via the calendar or vice-versa. | ||
|
||
<!-- example(datepicker-disabled) --> | ||
|
||
### Touch UI mode | ||
|
||
The datepicker normally opens as a popup under the input. However this is not ideal for touch | ||
devices that don't have as much screen real estate and need bigger click targets. For this reason | ||
`mat-datepicker` has a `touchUi` property that can be set to `true` in order to enable a more touch | ||
friendly UI where the calendar opens in a large dialog. | ||
`<mat-datepicker>` has a `touchUi` property that can be set to `true` in order to enable a more | ||
touch friendly UI where the calendar opens in a large dialog. | ||
|
||
<!-- example(datepicker-touch) --> | ||
|
||
### Manually opening and closing the calendar | ||
|
||
The calendar popup can be programmatically controlled using the `open` and `close` methods on the | ||
`mat-datepicker`. It also has an `opened` property that reflects the status of the popup. | ||
`<mat-datepicker>`. It also has an `opened` property that reflects the status of the popup. | ||
|
||
<!-- example(datepicker-api) --> | ||
|
||
### Internationalization | ||
|
||
In order to support internationalization, the datepicker supports customization of the following | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While you're here, change this to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, it's odd that the headers directly under this list don't align with the points here. |
||
three pieces via injection: | ||
1. The date implementation that the datepicker accepts. | ||
2. The display and parse formats used by the datepicker. | ||
3. The message strings used in the datepicker's UI. | ||
|
||
#### Setting the locale code | ||
|
||
By default, the `MAT_DATE_LOCALE` injection token will use the existing `LOCALE_ID` locale code | ||
from `@angular/core`. If you want to override it, you can provide a new value for the | ||
`MAT_DATE_LOCALE` token: | ||
|
@@ -131,28 +164,19 @@ export class MyApp {} | |
|
||
It's also possible to set the locale at runtime using the `setLocale` method of the `DateAdapter`. | ||
|
||
```ts | ||
import { DateAdapter, NativeDateAdapter } from '@angular/material'; | ||
|
||
@Component({ | ||
selector: 'foo', | ||
template: '' | ||
}) | ||
export class FooComponent { | ||
constructor(dateAdapter: DateAdapter<NativeDateAdapter>) { | ||
dateAdapter.setLocale('de-DE'); | ||
} | ||
} | ||
``` | ||
<!-- example(datepicker-locale) --> | ||
|
||
#### Choosing a date implementation and date format settings | ||
|
||
The datepicker was built to be date implementation agnostic. This means that it can be made to work | ||
with a variety of different date implementations. However it also means that developers need to make | ||
sure to provide the appropriate pieces for the datepicker to work with their chosen implementation. | ||
The easiest way to ensure this is just to import one of the pre-made modules (currently | ||
`MatNativeDateModule` is the only implementation that ships with material, but there are plans to add | ||
a module for Moment.js support): | ||
* `MatNativeDateModule` - support for native JavaScript Date object | ||
The easiest way to ensure this is just to import one of the pre-made modules: | ||
|
||
|Module |Date type|Supported locales |Dependencies |Import from | | ||
|---------------------|---------|-----------------------------------------------------------------------|----------------------------------|----------------------------------| | ||
|`MatNativeDateModule`|`Date` |en-US |None |`@angular/material` | | ||
|`MatMomentDateModule`|`Moment` |[See project](https://github.com/moment/moment/tree/develop/src/locale)|[Moment.js](https://momentjs.com/)|`@angular/material-moment-adapter`| | ||
|
||
These modules include providers for `DateAdapter` and `MAT_DATE_FORMATS` | ||
|
||
|
@@ -177,10 +201,16 @@ export class MyComponent { | |
|
||
*Please note: `MatNativeDateModule` is based off of the functionality available in JavaScript's | ||
native `Date` object, and is thus not suitable for many locales. One of the biggest shortcomings of | ||
the native `Date` object is the inability to set the parse format. We highly recommend using a | ||
custom `DateAdapter` that works with the formatting/parsing library of your choice.* | ||
the native `Date` object is the inability to set the parse format. We highly recommend using the | ||
`MomentDateAdapter` or a custom `DateAdapter` that works with the formatting/parsing library of your | ||
choice.* | ||
|
||
<!-- example(datepicker-moment) --> | ||
|
||
#### Customizing the date implementation | ||
|
||
<!-- TODO(mmalerba): Add a guide about this --> | ||
|
||
The datepicker does all of its interaction with date objects via the `DateAdapter`. Making the | ||
datepicker work with a different date implementation is as easy as extending `DateAdapter`, and | ||
using your subclass as the provider. You will also want to make sure that the `MAT_DATE_FORMATS` | ||
|
@@ -198,24 +228,30 @@ export class MyApp {} | |
``` | ||
|
||
#### Customizing the parse and display formats | ||
|
||
The `MAT_DATE_FORMATS` object is just a collection of formats that the datepicker uses when parsing | ||
and displaying dates. These formats are passed through to the `DateAdapter` so you will want to make | ||
sure that the format objects you're using are compatible with the `DateAdapter` used in your app. | ||
This example shows how to use the native `Date` implementation from material, but with custom | ||
formats. | ||
|
||
If you want use one of the `DateAdapters` that ships with Angular Material, but use your own | ||
`MAT_DATE_FORMATS`, you can import the `NativeDateModule` or `MomentDateModule`. These modules are | ||
identical to the "Mat"-prefixed versions (`MatNativeDateModule` and `MatMomentDateModule`) except | ||
they do not include the default formats. For example: | ||
|
||
```ts | ||
@NgModule({ | ||
imports: [MatDatepickerModule], | ||
imports: [MatDatepickerModule, NativeDateModule], | ||
providers: [ | ||
{provide: DateAdapter, useClass: NativeDateAdapter}, | ||
{provide: MAT_DATE_FORMATS, useValue: MY_NATIVE_DATE_FORMATS}, | ||
], | ||
}) | ||
export class MyApp {} | ||
``` | ||
|
||
<!-- example(datepicker-formats) --> | ||
|
||
#### Localizing labels and messages | ||
|
||
The various text strings used by the datepicker are provided through `MatDatepickerIntl`. | ||
Localization of these messages can be done by providing a subclass with translated values in your | ||
application root module. | ||
|
@@ -229,7 +265,9 @@ application root module. | |
}) | ||
export class MyApp {} | ||
``` | ||
|
||
### Accessibility | ||
|
||
The `MatDatepickerInput` directive adds `aria-haspopup` attribute to the native input element, and it | ||
triggers a calendar dialog with `role="dialog"`. | ||
|
||
|
@@ -238,6 +276,7 @@ should have a placeholder or be given a meaningful label via `aria-label`, `aria | |
`MatDatepickerIntl`. | ||
|
||
#### Keyboard shortcuts | ||
|
||
The keyboard shortcuts to handle datepicker are: | ||
|
||
| Shortcut | Action | | ||
|
@@ -278,3 +317,41 @@ In year view: | |
| `PAGE_DOWN` | Go to next year | | ||
| `ALT` + `PAGE_DOWN` | Go to next 10 years | | ||
| `ENTER` | Select current month | | ||
|
||
### Future work | ||
|
||
Currently the datepicker supports basic date selection functionality. There are more features that | ||
will be added in future iterations, including: | ||
* Support for datetimes (e.g. May 2, 2017 at 12:30pm) and month + year only (e.g. May 2017) | ||
* Support for selecting and displaying date ranges | ||
* Support for custom time zones | ||
* Infinite scrolling through calendar months | ||
* Easier year selection | ||
* Custom views for the calendar popup | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would omit the future work section here; we don't include it in any of the other docs. Do we have issues to track these? |
||
|
||
### Troubleshooting | ||
|
||
#### Error: MatDatepicker: No provider found for DateAdapter/MAT_DATE_FORMATS | ||
|
||
This error is thrown if you have not provided all of the injectables the datepicker needs to work. | ||
The easiest way to resolve this is to import the `MatNativeDateModule` or `MatMomentDateModule` in | ||
your application's root module. See the section on | ||
[choosing a date implementation](#choosing-a-date-implementation-and-date-format-settings)) for more | ||
information. | ||
|
||
#### Error: A MatDatepicker can only be associated with a single input | ||
|
||
This error is thrown if more than one `<input>` tries to claim ownership over the same | ||
`<mat-datepicker>` (via the `matDatepicker` attribute on the input). A datepicker can only be | ||
associated with a single input. | ||
|
||
#### Error: Attempted to open an MatDatepicker with no associated input. | ||
|
||
This error occurs if your `<mat-datepicker>` is not associated with any `<input>`. To associate an | ||
input with your datepicker, create a template reference for the datepicker and assign it to the | ||
`matDatepicker` attribute on the input: | ||
|
||
```html | ||
<input [matDatepicker]="picker"> | ||
<mat-datepicker #picker></mat-datepicker> | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,9 @@ | ||
import {Component} from '@angular/core'; | ||
|
||
/** | ||
* @title Datepicker API | ||
*/ | ||
/** @title Datepicker open method */ | ||
@Component({ | ||
selector: 'datepicker-api-example', | ||
templateUrl: 'datepicker-api-example.html', | ||
styleUrls: ['datepicker-api-example.css'], | ||
}) | ||
export class DatepickerApiExample { | ||
} | ||
export class DatepickerApiExample {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/** No CSS for this example */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.