amp-date-picker
Introduction
amp-date-picker
is an AMP component which allows to select a single date or a range of dates. Its implementation is based on react-dates
Setup
Include the amp-date-picker
component.
<script async custom-element="amp-date-picker" src="https://cdn.ampproject.org/v0/amp-date-picker-0.1.js"></script>
Include the amp-bind
component to set variables based on the selected date.
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
Include the amp-mustache
component to display an info panel below the date picker.
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
Include the amp-lightbox
component to display a date picker inside a fullscreen lightbox view.
<script async custom-element="amp-lightbox" src="https://cdn.ampproject.org/v0/amp-lightbox-0.1.js"></script>
Include the amp-form
component for creating forms.
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
In order to personalize amp-date-picker
style, you can use classes such as CalendarMonth_caption
which are inherited from react-dates. amp-date-picker
also exposes CSS classes which you can use in CSS rule, like amp-date-picker-selecting
, which is applied to the date input the user is editing.
<style amp-custom>
:root {
--color-primary: #005AF0;
--color-text-light: #fff;
--color-bg-light: #FAFAFC;
--space-2: 1rem; /* 16px */
--space-1: 0.5rem; /* 8px */
}
.example-picker {
display: flex;
}
.example-picker[mode="overlay"] {
padding: var(--space-2);
}
.example-picker .CalendarMonth_caption {
color: var(--color-text-light);
}
.example-picker [type="range"] .amp-date-picker-selecting {
border-bottom-color: var(--color-primary);
color: var(--color-primary);
}
.space-between > * + * {
margin-left: var(--space-2);
}
#lb {
background: var(--color-bg-light);
}
#lb .align-content-center {
height: 100%;
}
.icon-input {
background-image: url('data:image/svg+xml,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1393.1 1500" style="enable-background:new 0 0 1393.1 1500;" xml:space="preserve"><path d="M107.2,1392.9h241.1v-241.1H107.2V1392.9z M401.9,1392.9h267.9v-241.1H401.9V1392.9z M107.2,1098.2h241.1V830.4H107.2 V1098.2z M401.9,1098.2h267.9V830.4H401.9V1098.2z M107.2,776.8h241.1V535.7H107.2V776.8z M723.4,1392.9h267.9v-241.1H723.4V1392.9z M401.9,776.8h267.9V535.7H401.9V776.8z M1044.8,1392.9H1286v-241.1h-241.1V1392.9z M723.4,1098.2h267.9V830.4H723.4V1098.2z M428.7,375V133.9c0-7.3-2.7-13.5-8-18.8c-5.3-5.3-11.6-8-18.8-8h-53.6c-7.3,0-13.5,2.7-18.8,8c-5.3,5.3-8,11.6-8,18.8V375 c0,7.3,2.7,13.5,8,18.8c5.3,5.3,11.6,8,18.8,8h53.6c7.3,0,13.5-2.7,18.8-8C426,388.5,428.7,382.3,428.7,375z M1044.8,1098.2H1286 V830.4h-241.1V1098.2z M723.4,776.8h267.9V535.7H723.4V776.8z M1044.8,776.8H1286V535.7h-241.1V776.8z M1071.6,375V133.9 c0-7.3-2.7-13.5-8-18.8c-5.3-5.3-11.6-8-18.8-8h-53.6c-7.3,0-13.5,2.7-18.8,8c-5.3,5.3-8,11.6-8,18.8V375c0,7.3,2.7,13.5,8,18.8 c5.3,5.3,11.6,8,18.8,8h53.6c7.3,0,13.5-2.7,18.8-8C1069,388.5,1071.6,382.3,1071.6,375z M1393.1,321.4v1071.4 c0,29-10.6,54.1-31.8,75.3c-21.2,21.2-46.3,31.8-75.3,31.8H107.2c-29,0-54.1-10.6-75.3-31.8C10.6,1447,0,1421.9,0,1392.9V321.4 c0-29,10.6-54.1,31.8-75.3s46.3-31.8,75.3-31.8h107.2v-80.4c0-36.8,13.1-68.4,39.3-94.6S311.4,0,348.3,0h53.6 c36.8,0,68.4,13.1,94.6,39.3c26.2,26.2,39.3,57.8,39.3,94.6v80.4h321.5v-80.4c0-36.8,13.1-68.4,39.3-94.6 C922.9,13.1,954.4,0,991.3,0h53.6c36.8,0,68.4,13.1,94.6,39.3s39.3,57.8,39.3,94.6v80.4H1286c29,0,54.1,10.6,75.3,31.8 C1382.5,267.3,1393.1,292.4,1393.1,321.4z"/></svg>');
background-repeat: no-repeat;
flex-shrink: 0;
height: 28px;
margin-top: var(--space-1);
width: 27px;
}
</style>
Single date picker
amp-date-picker
with type=single
can be used for selecting a single date.
You can use amp-mustache
with info-template
attribute to show an info-panel below the calendar, here we are showing the date that you just selected. info-template
also enables AMP binding making available variables which have been set with AMP.setState
.
A placeholder is required for the component. For a single date, this can take the form:
<input amp-date-placeholder placeholder="Pick a date">
. amp-date-picker
introduces the clear
and today
actions. clear
can be called after clicking on a button to clear the date selection. The today
action allows users to quickly select the current date, and its offset
argument chooses how many days from today to set the date.
<amp-date-picker id="simple-date-picker" type="single" mode="overlay" layout="container" on="select:AMP.setState({date1: event.date, dateType1: event.id})" format="YYYY-MM-DD" open-after-select input-selector="[name=date1]" class="example-picker space-between">
<div class="icon-input"></div>
<input name="date1" placeholder="Pick a date">
<button on="tap: simple-date-picker.clear">Clear</button>
<button on="tap: simple-date-picker.today">Today</button>
<button on="tap: simple-date-picker.today(offset=1)">Tomorrow</button>
<template type="amp-mustache" info-template>
<span [text]="date1 != null ? 'You picked ' + date1 + '.' : 'You will see your chosen date here.'">You will see your chosen date here.</span>
</template>
</amp-date-picker>
Custom date markup
In addition, you can also use amp-mustache
to create templates for custom date markup, such as an icon instead of the number of the month. Here we are using a taco icon in place of the number of the month with a frequency of 2 weeks every Tuesday. Common use cases could be dates of the month where the price of an item is fixed to a specific number.
<amp-date-picker id="simple-date-picker-2" type="single" mode="overlay" layout="container" on="select:AMP.setState({date2: event.date, dateType2: event.id})" locale="en" format="YYYY-MM-DD" open-after-select input-selector="[name=date2]" class="example-picker space-between">
<input class="border-none p0" name="date2" placeholder="Pick a date">
<button on="tap: simple-date-picker-2.clear">Clear</button>
<template type="amp-mustache" date-template dates="FREQ=WEEKLY;DTSTART=20180101T000000Z;INTERVAL=2;WKST=SU;BYDAY=TU" id="tacos2">
<span>🌮</span>
<span class="taco-tuesday"></span>
</template>
<template type="amp-mustache" info-template>
<span [text]="date2 ? 'You picked ' + date2 + '.' +
(dateType2 == 'tacos2' ? ' Happy Taco Tuesday!' : '') : ''">You will see your chosen date here.</span>
</template>
</amp-date-picker>
Date Range Picker
amp-date-picker
with type=range
can be used for selecting a date range.
By default, amp-date-picker
disables past dates, use min
attribute to enable them.
<amp-date-picker type="range" mode="overlay" id="range-date-picker" on="
select:
AMP.setState({
dates: event.dates,
startDate: event.start,
endDate: event.end
})" format="YYYY-MM-DD" open-after-select min="2017-10-26" start-input-selector="#range-start" end-input-selector="#range-end" class="example-picker space-between">
<input id="range-start" placeholder="Start date">
<input id="range-end" placeholder="End date">
<button on="tap:range-date-picker.clear">Clear</button>
<template type="amp-mustache" info-template>
<span [text]="(startDate && endDate ?
'You picked ' + startDate.date + ' as start date and ' + endDate.date + ' as end date.' :
'You will see your chosen dates here.')">
You will see your chosen dates here.
</span>
</template>
</amp-date-picker>
External Configuration
It's possible to configure the amp-date-picker
preferences by using an external json. We use the following JSON at the URL /json/amp-date-picker.json
:
{ "templates": [{ "id": "spooky", "dates": [ "FREQ=WEEKLY;DTSTART=20180101T160000Z;BYDAY=MO", "FREQ=YEARLY;DTSTART=20180101T160000Z;WKST=SU;BYMONTH=10;BYMONTHDAY=31", "FREQ=MONTHLY;DTSTART=20180101T160000Z;WKST=SU;BYDAY=FR;BYMONTHDAY=13" ] }] }
For dates that match the list of dates in the JSON blob, the template with id="spooky"
will be used to render that day in the calendar. In this case, these dates are Mondays, Friday the 13ths, and Halloween.
<amp-date-picker id="src-picker" type="single" mode="overlay" layout="container" format="YYYY-MM-DD" src="/static/samples/json/amp-date-picker.json" input-selector="#src-input" class="example-picker space-between">
<input id="src-input" placeholder="Pick a date">
<button on="tap: src-picker.clear">Clear</button>
<template type="amp-mustache" date-template id="spooky">
<span>🙀</span>
</template>
</amp-date-picker>
Static date picker
amp-date-picker
with mode="static" can display a calendar view. The static picker can be used with or without an attached input.
<amp-date-picker id="static-picker" type="single" mode="static" layout="fixed-height" height="360" format="YYYY-MM-DD" input-selector="#static-picker-input">
</amp-date-picker>
Highlighted and blocked attributes
amp-date-picker
supports a range of attributes, for example highlighted
and blocked
. Find the complete list in the official doc.
The blocked
attribute allows to specify a space separated list of ISO 8601 dates and RFC 5545 RRULEs specifying disallowed dates.
The highlighted
attributes a space separated list of ISO 8601 dates and RFC 5545 RRULEs specifying dates displayed with a highlight style.
Here every Thursday is highlighted
, while every weekend is blocked
.
<amp-date-picker id="simple-date-picker-3" type="single" mode="static" layout="fixed-height" height="360" on="select:AMP.setState({date3: event.date ? event.date : ''})" locale="en" format="YYYY-MM-DD" highlighted="FREQ=WEEKLY;WKST=SU;BYDAY=TH" blocked="FREQ=WEEKLY;WKST=SU;BYDAY=SA,SU">
</amp-date-picker>
Allow-blocked-dates attribute
If the date picker uses type="range"
and there are blocked dates that are allowed to be part of the range, the allow-blocked-dates
attribute allows users to select ranges that include blocked dates.
<amp-date-picker id="simple-date-picker-4" type="range" mode="static" layout="fixed-height" height="360" on="select:AMP.setState({date4: event.date ? event.date : ''})" locale="en" format="YYYY-MM-DD" allow-blocked-ranges highlighted="FREQ=WEEKLY;WKST=SU;BYDAY=TH" blocked="FREQ=WEEKLY;WKST=SU;BYDAY=SA,SU">
</amp-date-picker>
Lightbox date picker
amp-date-picker
can display inside a modal lightbox. The activate
event opens the lightbox if the user focuses the picker's connected input elements and presses the down arrow key. deactivate
is triggered when the user presses escape when interacting with the calendar view. For a touch-only interface box, the on="tap:..."
attribute opens the picker when the user taps on the input.
Choose your travel dates
<p>Choose your travel dates</p>
<input id="lb-start" placeholder="Start date" on="tap:lb.open" role="textbox" tabindex="0">
<input id="lb-end" placeholder="End date" on="tap:lb.open" role="textbox" tabindex="0">
<button on="tap:lb-picker.clear">Clear</button>
<amp-lightbox id="lb" layout="nodisplay">
<button on="tap:lb.close" tabindex="0">Close</button>
<div class="align-content-center">
<amp-date-picker id="lb-picker" type="range" mode="static" layout="fixed-height" height="360" format="MM/DD/YYYY" on="activate: lb.open;
deactivate: lb.close;" start-input-selector="#lb-start" end-input-selector="#lb-end"></amp-date-picker>
</div>
</amp-lightbox>
Fullscreen lightbox date picker
amp-date-picker
can also display as a fullscreen view inside a lightbox. The fullscreen
attribute tells the date picker to take up the space in its container and allow its content to scroll vertically.
Choose your travel dates
<p>Choose your travel dates</p>
<input id="lb-fullscreen-start" placeholder="Start date" on="tap:lb-fullscreen.open" role="textbox" tabindex="0">
<input id="lb-fullscreen-end" placeholder="End date" on="tap:lb-fullscreen.open" role="textbox" tabindex="0">
<button on="tap:lb-fullscreen-picker.clear">Clear</button>
<amp-lightbox id="lb-fullscreen" layout="nodisplay" scrollable>
<button on="tap:lb-fullscreen.close" tabindex="0">Close</button>
<amp-date-picker id="lb-fullscreen-picker" fullscreen layout="fill" mode="static" type="range" number-of-months="12" format="MM/DD/YYYY" on="activate: lb-fullscreen.open;
deactivate: lb-fullscreen.close;" start-input-selector="#lb-fullscreen-start" end-input-selector="#lb-fullscreen-end"></amp-date-picker>
</amp-lightbox>
Date picker in a form
amp-date-picker
integrates with AMP forms. If you don't provide an input for a static picker, it will create a hidden input to submit in the form.
<form method="post" action-xhr="/documentation/examples/api/submit-form-xhr" target="_top">
<amp-date-picker id="form-picker" type="single" mode="static" layout="fixed-height" height="360" format="YYYY-MM-DD">
</amp-date-picker>
<input type="submit">
<div submit-success>
<template type="amp-mustache">
Success! Thanks for trying the <code>amp-form</code> demo!
</template>
</div>
<div submit-error>
<template type="amp-mustache">
Error!
</template>
</div>
</form>
Date picker with amp-bind
amp-date-picker
integrates with amp-bind
. The min
and max
attributes can be used to update the min and max date.
<amp-state id="binding">
<script type="application/json">
{"min": "", "max": ""}
</script>
</amp-state>
<input on="change:AMP.setState({binding: {min: event.value}})" placeholder="Minimum date">
<input on="change:AMP.setState({binding: {max: event.value}})" placeholder="Maximum date">
<amp-date-picker id="bind-picker" type="single" mode="static" layout="fixed-height" height="360" format="MM/DD/YYYY" [min]="binding.min" [max]="binding.max">
</amp-date-picker>
如果此页面上的说明未能涵盖您的所有问题,欢迎与其他 AMP 用户取得联系,讨论您的具体用例。
前往 Stack Overflow 一项无法解释的功能?AMP 项目强烈鼓励您参与并做出贡献!我们希望您能成为我们开放源代码社区的持续参与者,但我们也欢迎您对所热衷问题做出一次性贡献。
编辑 GitHub 上的示例-
Written by @kul3r4