forked from predixdesignsystem/px-datetime-picker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpx-datetime-picker.html
256 lines (236 loc) · 8.08 KB
/
px-datetime-picker.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
<!--
Relative paths assume component is being run from inside an app or another component, where dependencies are flat
siblings. When this component is run from its own repo (e.g. ui tests, examples), we assume the server is started with
'grunt depserve' (or similar server setup) to enable correct finding of bower dependencies for local runs.
-->
<link rel="import" href="../polymer/polymer.html"/>
<link rel="import" href="../px-datetime-field/px-datetime-field.html"/>
<link rel="import" href="../px-calendar-picker/px-calendar-picker.html"/>
<link rel="import" href="../px-datetime-common/px-datetime-imports.html"/>
<link rel="import" href="../px-datetime-common/px-datetime-behavior.html"/>
<link rel="import" href="../px-datetime-common/px-datetime-buttons.html"/>
<link rel="import" href="../px-datetime-common/px-datetime-button-behavior.html"/>
<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
<!--
The datetime components rely on <a href="https://momentjs.com/" target="_blank">Moment.js</a> and <a href="https://momentjs.com/timezone/" target="_blank">Moment Timezone</a>.
#### Usage
<px-datetime-picker></px-datetime-picker>
#### Styling
The following custom properties are available for styling. Please also refer to px-forms-design and px-buttons-design for additional style variables used by this component.
Custom property | Description | Default
----------------|-------------|----------
`--px-datetime-picker-background-color` | Text color for the "Today" link | `$primary-blue`
`--px-datetime-picker-background-color--hover` | Text color for the "Today" link when hovered | `$primary-blue-hover`
`--px-datetime-picker-background-color--pressed` | Text color for the "Today" link when pressed | `$primary-blue-pressed`
`--px-datetime-picker-overlay-color` | Overlay color for the rest of the screen when the picker is invoked | `rgba($black, 0.1)`
@element px-datetime-picker
@blurb Element allowing to pick a date using a calendar or by typing it
@homepage index.html
@demo demo.html
-->
<link rel="import" href="css/px-datetime-picker-styles.html">
<dom-module id="px-datetime-picker">
<template>
<style include="px-datetime-picker-styles"></style>
<div id="overlay" class="overlay visuallyhidden" on-tap="_processClose"></div>
<div class="inline--flex flex--col">
<px-datetime-field
class="field"
id="field"
time-zone="{{timeZone}}"
moment-obj="{{momentObj}}"
hide-time={{hideTime}}
show-time-zone="{{showTimeZone}}"
date-format="{{dateFormat}}"
time-format="{{timeFormat}}"
is-selected=[[_opened]]
prevent-notification-on-change
block-future-dates="{{blockFutureDates}}"
block-past-dates="{{blockPastDates}}">
</px-datetime-field>
<div id="box" class="visuallyhidden container">
<div class="container__box flex--col">
<px-calendar-picker
id="calendar"
class="u-m+"
block-future-dates="{{blockFutureDates}}"
block-past-dates="{{blockPastDates}}"
prevent-range-selection
from-moment="{{momentObj}}"
base-date="[[momentObj]]"
time-zone="{{timeZone}}">
</px-calendar-picker>
<div class="flex__item--middle today u-mb-" on-tap="_todayClicked">Today</div>
<template is="dom-if" if={{showButtons}}>
<px-datetime-buttons
class="flex__item--bottom u-m-"
is-submit-button-valid
submit-text="Apply">
</px-datetime-buttons>
</template>
</div>
</div>
</div>
</template>
</dom-module>
<script>
Polymer({
is: 'px-datetime-picker',
behaviors:[
pxDatetimeBehavior,
pxDatetimeButtonBehavior,
Polymer.IronA11yKeysBehavior
],
/**
* Properties block, expose attribute values to the DOM via 'notify'
*
* @property properties
* @type Object
*/
properties: {
/**
* Whether the Calendar box is opened
*/
_opened: {
type: Boolean,
value: false
},
/**
*
* Can be set to show the timezone in the field. Can have 2 values:
* 'dropdown': shows the time zone as a dropdown which the user can use to
* select a different time zone. Only contains a subset of all timezones
* 'extendedDropdown': shows the time zone as a dropdown which the user can use to
* select a different time zone. Contains all existing timezones (588)
* 'text': shows the time zone as text, non editable
* 'abbreviatedText': shows the time zone as an abbreviated text, non editable (such as PST, EST...)
*/
showTimeZone: {
type: String,
value: ''
},
/**
* Whether this date picker should allow to pick time as well.
*
*/
hideTime: {
type: Boolean,
value: false
},
/**
* Moment format used for the date
*
*/
dateFormat: {
type: String,
value: 'MM/DD/YYYY'
},
/**
* Moment format used for the time
*
*/
timeFormat: {
type: String,
value: 'HH:mm A'
}
},
listeners: {
'px-datetime-entry-icon-clicked':'_iconClicked',
'px-datetime-button-clicked': '_buttonClicked'
},
observers: [
'_momentChanged(momentObj)'
],
/**
* Key bindings for iron-a11y-keys-behavior
*/
keyBindings: {
'esc' : '_onEsc',
'enter': '_onEnter'
},
attached: function() {
this._isAttached = true;
},
/*
* 'Today' button/text has been clicked
*/
_todayClicked: function(evt) {
this.set('momentObj', this._preserveTime(this.momentObj, Px.moment.tz(Px.moment(), this.timeZone)));
if(!this.showButtons) {
this._close();
}
},
_onEsc: function(evt) {
this._applyCurrentValues(false);
this._close();
},
_onEnter: function(evt) {
this._applyCurrentValues(this.$.field.isValid);
this._close();
},
/**
* Opens the calendar
*/
_open: function() {
this.toggleClass('visuallyhidden', false, this.$.box);
this.toggleClass('visuallyhidden', false, this.$.overlay);
this.toggleClass('aboveOverlay', true, this.$.field);
this.set('_opened', true);
},
/**
* Closes the calendar
*/
_close: function() {
this.toggleClass('visuallyhidden', true, this.$.box);
this.toggleClass('visuallyhidden', true, this.$.overlay);
this.toggleClass('aboveOverlay', false, this.$.field);
this.set('_opened', false);
},
/**
* Opens the calendar if closed, closes it if opened
*/
_toggleBoxOpen: function() {
if(this._opened) {
this._close();
} else {
this._open();
}
},
_processClose: function() {
//If we show buttons don't validate
this._applyCurrentValues(!this.showButtons);
this._close();
},
_momentChanged: function(momentObj) {
if(this._isAttached) {
if(this._opened) {
if(this.$.calendar.fromMoment.toISOString() === this.momentObj.toISOString()) {
//changes comes from calendar (not from field). If it comes from field
//do nothing as we're open (the calendar moment will be updated through binding)
//if we don't show buttons close on selection
if(!this.showButtons) {
this._applyCurrentValues(this.$.field.isValid);
this._close();
}
}
}
//we're closed, moment has changed by user changing the input fields.
else {
if(this.$.field.isValid) {
this._applyCurrentValues(true);
}
}
}
},
_buttonClicked: function(evt) {
var canApplyValue = evt.detail.action && this.$.field.isValid;
this._applyCurrentValues(canApplyValue);
this._close();
},
_iconClicked: function(evt) {
if(evt.detail.dateOrTime === "Date") {
this._toggleBoxOpen();
}
}
});
</script>