materialize-sass 0.99.0 → 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +2 -2
- data/app/assets/javascripts/materialize.js +6015 -5060
- data/app/assets/javascripts/materialize/animation.js +4 -5
- data/app/assets/javascripts/materialize/buttons.js +24 -38
- data/app/assets/javascripts/materialize/cards.js +13 -21
- data/app/assets/javascripts/materialize/carousel.js +122 -110
- data/app/assets/javascripts/materialize/character_counter.js +14 -22
- data/app/assets/javascripts/materialize/chips.js +41 -44
- data/app/assets/javascripts/materialize/collapsible.js +41 -46
- data/app/assets/javascripts/materialize/date_picker/picker.date.js +965 -1167
- data/app/assets/javascripts/materialize/date_picker/picker.js +546 -634
- data/app/assets/javascripts/materialize/date_picker/picker.time.js +166 -212
- data/app/assets/javascripts/materialize/dropdown.js +53 -68
- data/app/assets/javascripts/materialize/extras/nouislider.js +3 -1
- data/app/assets/javascripts/materialize/extras/nouislider.min.js +1 -1
- data/app/assets/javascripts/materialize/forms.js +156 -154
- data/app/assets/javascripts/materialize/global.js +34 -43
- data/app/assets/javascripts/materialize/hammer.min.js +424 -1
- data/app/assets/javascripts/materialize/initial.js +3 -3
- data/app/assets/javascripts/materialize/jquery.easing.1.4.js +120 -142
- data/app/assets/javascripts/materialize/jquery.hammer.js +9 -9
- data/app/assets/javascripts/materialize/materialbox.js +81 -107
- data/app/assets/javascripts/materialize/modal.js +373 -162
- data/app/assets/javascripts/materialize/parallax.js +11 -15
- data/app/assets/javascripts/materialize/pushpin.js +2 -5
- data/app/assets/javascripts/materialize/scrollFire.js +9 -11
- data/app/assets/javascripts/materialize/scrollspy.js +84 -92
- data/app/assets/javascripts/materialize/sideNav.js +128 -139
- data/app/assets/javascripts/materialize/slider.js +83 -112
- data/app/assets/javascripts/materialize/tabs.js +196 -196
- data/app/assets/javascripts/materialize/tapTarget.js +170 -173
- data/app/assets/javascripts/materialize/toasts.js +330 -112
- data/app/assets/javascripts/materialize/tooltip.js +134 -145
- data/app/assets/javascripts/materialize/transitions.js +43 -49
- data/app/assets/javascripts/materialize/velocity.min.js +623 -2
- data/app/assets/javascripts/materialize/waves.js +42 -47
- data/app/assets/stylesheets/materialize/components/_buttons.scss +1 -1
- data/app/assets/stylesheets/materialize/components/_carousel.scss +4 -5
- data/app/assets/stylesheets/materialize/components/_chips.scss +1 -0
- data/app/assets/stylesheets/materialize/components/_collapsible.scss +4 -7
- data/app/assets/stylesheets/materialize/components/_color.scss +1 -1
- data/app/assets/stylesheets/materialize/components/_global.scss +8 -14
- data/app/assets/stylesheets/materialize/components/_navbar.scss +0 -1
- data/app/assets/stylesheets/materialize/components/_tabs.scss +1 -7
- data/app/assets/stylesheets/materialize/components/_toast.scss +6 -12
- data/app/assets/stylesheets/materialize/components/_variables.scss +55 -43
- data/app/assets/stylesheets/materialize/components/date_picker/_default.scss +1 -0
- data/app/assets/stylesheets/materialize/components/forms/_checkboxes.scss +2 -12
- data/app/assets/stylesheets/materialize/components/forms/_file-input.scss +6 -0
- data/app/assets/stylesheets/materialize/components/forms/_input-fields.scss +67 -37
- data/app/assets/stylesheets/materialize/components/forms/_radio-buttons.scss +1 -3
- data/app/assets/stylesheets/materialize/components/forms/_select.scss +72 -11
- data/app/assets/stylesheets/materialize/components/forms/_switches.scss +2 -4
- data/app/assets/stylesheets/materialize/extras/nouislider.css +8 -1
- data/lib/materialize-sass/version.rb +1 -1
- metadata +2 -5
- data/app/assets/javascripts/materialize/init.js +0 -214
- data/app/assets/javascripts/materialize/jquery.timeago.min.js +0 -1
- data/app/assets/javascripts/materialize/prism.js +0 -8
@@ -5,60 +5,47 @@
|
|
5
5
|
* Licensed under MIT
|
6
6
|
*/
|
7
7
|
|
8
|
-
(function (
|
8
|
+
(function (factory) {
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
define( 'picker', ['jquery'], factory )
|
10
|
+
Materialize.Picker = factory(jQuery);
|
11
|
+
})(function ($) {
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
var $window = $(window);
|
14
|
+
var $document = $(document);
|
15
|
+
var $html = $(document.documentElement);
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
var $window = $( window )
|
24
|
-
var $document = $( document )
|
25
|
-
var $html = $( document.documentElement )
|
26
|
-
|
27
|
-
|
28
|
-
/**
|
29
|
-
* The picker constructor that creates a blank picker.
|
30
|
-
*/
|
31
|
-
function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
|
32
|
-
|
33
|
-
// If there’s no element, return the picker constructor.
|
34
|
-
if ( !ELEMENT ) return PickerConstructor
|
17
|
+
/**
|
18
|
+
* The picker constructor that creates a blank picker.
|
19
|
+
*/
|
20
|
+
function PickerConstructor(ELEMENT, NAME, COMPONENT, OPTIONS) {
|
35
21
|
|
22
|
+
// If there’s no element, return the picker constructor.
|
23
|
+
if (!ELEMENT) return PickerConstructor;
|
36
24
|
|
37
|
-
|
38
|
-
IS_DEFAULT_THEME = false,
|
25
|
+
var IS_DEFAULT_THEME = false,
|
39
26
|
|
40
27
|
|
41
28
|
// The state of the picker.
|
42
29
|
STATE = {
|
43
|
-
id: ELEMENT.id || 'P' + Math.abs(
|
30
|
+
id: ELEMENT.id || 'P' + Math.abs(~~(Math.random() * new Date()))
|
44
31
|
},
|
45
32
|
|
46
33
|
|
47
34
|
// Merge the defaults and options passed.
|
48
|
-
SETTINGS = COMPONENT ? $.extend(
|
35
|
+
SETTINGS = COMPONENT ? $.extend(true, {}, COMPONENT.defaults, OPTIONS) : OPTIONS || {},
|
49
36
|
|
50
37
|
|
51
38
|
// Merge the default classes with the settings classes.
|
52
|
-
CLASSES = $.extend(
|
39
|
+
CLASSES = $.extend({}, PickerConstructor.klasses(), SETTINGS.klass),
|
53
40
|
|
54
41
|
|
55
42
|
// The element node wrapper into a jQuery object.
|
56
|
-
$ELEMENT = $(
|
43
|
+
$ELEMENT = $(ELEMENT),
|
57
44
|
|
58
45
|
|
59
46
|
// Pseudo picker constructor.
|
60
|
-
PickerInstance = function() {
|
61
|
-
return this.start()
|
47
|
+
PickerInstance = function () {
|
48
|
+
return this.start();
|
62
49
|
},
|
63
50
|
|
64
51
|
|
@@ -69,56 +56,46 @@ function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
|
|
69
56
|
|
70
57
|
$node: $ELEMENT,
|
71
58
|
|
72
|
-
|
73
59
|
/**
|
74
60
|
* Initialize everything
|
75
61
|
*/
|
76
|
-
start: function() {
|
62
|
+
start: function () {
|
77
63
|
|
78
64
|
// If it’s already started, do nothing.
|
79
|
-
if (
|
80
|
-
|
65
|
+
if (STATE && STATE.start) return P;
|
81
66
|
|
82
67
|
// Update the picker states.
|
83
|
-
STATE.methods = {}
|
84
|
-
STATE.start = true
|
85
|
-
STATE.open = false
|
86
|
-
STATE.type = ELEMENT.type
|
87
|
-
|
68
|
+
STATE.methods = {};
|
69
|
+
STATE.start = true;
|
70
|
+
STATE.open = false;
|
71
|
+
STATE.type = ELEMENT.type;
|
88
72
|
|
89
73
|
// Confirm focus state, convert into text input to remove UA stylings,
|
90
74
|
// and set as readonly to prevent keyboard popup.
|
91
|
-
ELEMENT.autofocus = ELEMENT == getActiveElement()
|
92
|
-
ELEMENT.readOnly = !SETTINGS.editable
|
93
|
-
ELEMENT.id = ELEMENT.id || STATE.id
|
94
|
-
if (
|
95
|
-
ELEMENT.type = 'text'
|
75
|
+
ELEMENT.autofocus = ELEMENT == getActiveElement();
|
76
|
+
ELEMENT.readOnly = !SETTINGS.editable;
|
77
|
+
ELEMENT.id = ELEMENT.id || STATE.id;
|
78
|
+
if (ELEMENT.type != 'text') {
|
79
|
+
ELEMENT.type = 'text';
|
96
80
|
}
|
97
81
|
|
98
|
-
|
99
82
|
// Create a new picker component with the settings.
|
100
|
-
P.component = new COMPONENT(P, SETTINGS)
|
101
|
-
|
83
|
+
P.component = new COMPONENT(P, SETTINGS);
|
102
84
|
|
103
85
|
// Create the picker root with a holder and then prepare it.
|
104
|
-
P.$root = $(
|
105
|
-
prepareElementRoot()
|
106
|
-
|
86
|
+
P.$root = $(PickerConstructor._.node('div', createWrappedComponent(), CLASSES.picker, 'id="' + ELEMENT.id + '_root" tabindex="0"'));
|
87
|
+
prepareElementRoot();
|
107
88
|
|
108
89
|
// If there’s a format for the hidden input element, create the element.
|
109
|
-
if (
|
110
|
-
prepareElementHidden()
|
90
|
+
if (SETTINGS.formatSubmit) {
|
91
|
+
prepareElementHidden();
|
111
92
|
}
|
112
93
|
|
113
|
-
|
114
94
|
// Prepare the input element.
|
115
|
-
prepareElement()
|
116
|
-
|
95
|
+
prepareElement();
|
117
96
|
|
118
97
|
// Insert the root as specified in the settings.
|
119
|
-
if (
|
120
|
-
else $ELEMENT.after( P.$root )
|
121
|
-
|
98
|
+
if (SETTINGS.container) $(SETTINGS.container).append(P.$root);else $ELEMENT.before(P.$root);
|
122
99
|
|
123
100
|
// Bind the default component and settings events.
|
124
101
|
P.on({
|
@@ -135,123 +112,116 @@ function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
|
|
135
112
|
open: SETTINGS.onOpen,
|
136
113
|
close: SETTINGS.onClose,
|
137
114
|
set: SETTINGS.onSet
|
138
|
-
})
|
139
|
-
|
115
|
+
});
|
140
116
|
|
141
117
|
// Once we’re all set, check the theme in use.
|
142
|
-
IS_DEFAULT_THEME = isUsingDefaultTheme(
|
143
|
-
|
118
|
+
IS_DEFAULT_THEME = isUsingDefaultTheme(P.$root.children()[0]);
|
144
119
|
|
145
120
|
// If the element has autofocus, open the picker.
|
146
|
-
if (
|
147
|
-
P.open()
|
121
|
+
if (ELEMENT.autofocus) {
|
122
|
+
P.open();
|
148
123
|
}
|
149
124
|
|
150
|
-
|
151
125
|
// Trigger queued the “start” and “render” events.
|
152
|
-
return P.trigger(
|
126
|
+
return P.trigger('start').trigger('render');
|
153
127
|
}, //start
|
154
128
|
|
155
129
|
|
156
130
|
/**
|
157
131
|
* Render a new picker
|
158
132
|
*/
|
159
|
-
render: function(
|
133
|
+
render: function (entireComponent) {
|
160
134
|
|
161
135
|
// Insert a new component holder in the root or box.
|
162
|
-
if (
|
163
|
-
else P.$root.find( '.' + CLASSES.box ).html( P.component.nodes( STATE.open ) )
|
136
|
+
if (entireComponent) P.$root.html(createWrappedComponent());else P.$root.find('.' + CLASSES.box).html(P.component.nodes(STATE.open));
|
164
137
|
|
165
138
|
// Trigger the queued “render” events.
|
166
|
-
return P.trigger(
|
139
|
+
return P.trigger('render');
|
167
140
|
}, //render
|
168
141
|
|
169
142
|
|
170
143
|
/**
|
171
144
|
* Destroy everything
|
172
145
|
*/
|
173
|
-
stop: function() {
|
146
|
+
stop: function () {
|
174
147
|
|
175
148
|
// If it’s already stopped, do nothing.
|
176
|
-
if (
|
149
|
+
if (!STATE.start) return P;
|
177
150
|
|
178
151
|
// Then close the picker.
|
179
|
-
P.close()
|
152
|
+
P.close();
|
180
153
|
|
181
154
|
// Remove the hidden field.
|
182
|
-
if (
|
183
|
-
P._hidden.parentNode.removeChild(
|
155
|
+
if (P._hidden) {
|
156
|
+
P._hidden.parentNode.removeChild(P._hidden);
|
184
157
|
}
|
185
158
|
|
186
159
|
// Remove the root.
|
187
|
-
P.$root.remove()
|
160
|
+
P.$root.remove();
|
188
161
|
|
189
162
|
// Remove the input class, remove the stored data, and unbind
|
190
163
|
// the events (after a tick for IE - see `P.close`).
|
191
|
-
$ELEMENT.removeClass(
|
192
|
-
setTimeout(
|
193
|
-
$ELEMENT.off(
|
194
|
-
}, 0)
|
164
|
+
$ELEMENT.removeClass(CLASSES.input).removeData(NAME);
|
165
|
+
setTimeout(function () {
|
166
|
+
$ELEMENT.off('.' + STATE.id);
|
167
|
+
}, 0);
|
195
168
|
|
196
169
|
// Restore the element state
|
197
|
-
ELEMENT.type = STATE.type
|
198
|
-
ELEMENT.readOnly = false
|
170
|
+
ELEMENT.type = STATE.type;
|
171
|
+
ELEMENT.readOnly = false;
|
199
172
|
|
200
173
|
// Trigger the queued “stop” events.
|
201
|
-
P.trigger(
|
174
|
+
P.trigger('stop');
|
202
175
|
|
203
176
|
// Reset the picker states.
|
204
|
-
STATE.methods = {}
|
205
|
-
STATE.start = false
|
177
|
+
STATE.methods = {};
|
178
|
+
STATE.start = false;
|
206
179
|
|
207
|
-
return P
|
180
|
+
return P;
|
208
181
|
}, //stop
|
209
182
|
|
210
183
|
|
211
184
|
/**
|
212
185
|
* Open up the picker
|
213
186
|
*/
|
214
|
-
open: function(
|
187
|
+
open: function (dontGiveFocus) {
|
215
188
|
|
216
189
|
// If it’s already open, do nothing.
|
217
|
-
if (
|
190
|
+
if (STATE.open) return P;
|
218
191
|
|
219
192
|
// Add the “active” class.
|
220
|
-
$ELEMENT.addClass(
|
221
|
-
aria(
|
193
|
+
$ELEMENT.addClass(CLASSES.active);
|
194
|
+
aria(ELEMENT, 'expanded', true);
|
222
195
|
|
223
196
|
// * A Firefox bug, when `html` has `overflow:hidden`, results in
|
224
197
|
// killing transitions :(. So add the “opened” state on the next tick.
|
225
198
|
// Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
|
226
|
-
setTimeout(
|
199
|
+
setTimeout(function () {
|
227
200
|
|
228
201
|
// Add the “opened” class to the picker root.
|
229
|
-
P.$root.addClass(
|
230
|
-
aria(
|
231
|
-
|
232
|
-
}, 0 )
|
202
|
+
P.$root.addClass(CLASSES.opened);
|
203
|
+
aria(P.$root[0], 'hidden', false);
|
204
|
+
}, 0);
|
233
205
|
|
234
206
|
// If we have to give focus, bind the element and doc events.
|
235
|
-
if (
|
207
|
+
if (dontGiveFocus !== false) {
|
236
208
|
|
237
209
|
// Set it as open.
|
238
|
-
STATE.open = true
|
210
|
+
STATE.open = true;
|
239
211
|
|
240
212
|
// Prevent the page from scrolling.
|
241
|
-
if (
|
242
|
-
$html.
|
243
|
-
css( 'overflow', 'hidden' ).
|
244
|
-
css( 'padding-right', '+=' + getScrollbarWidth() )
|
213
|
+
if (IS_DEFAULT_THEME) {
|
214
|
+
$html.css('overflow', 'hidden').css('padding-right', '+=' + getScrollbarWidth());
|
245
215
|
}
|
246
216
|
|
247
217
|
// Pass focus to the root element’s jQuery object.
|
248
218
|
// * Workaround for iOS8 to bring the picker’s root into view.
|
249
|
-
P.$root.eq(0).focus()
|
219
|
+
P.$root.eq(0).focus();
|
250
220
|
|
251
221
|
// Bind the document events.
|
252
|
-
$document.on(
|
222
|
+
$document.on('click.' + STATE.id + ' focusin.' + STATE.id, function (event) {
|
253
223
|
|
254
|
-
var target = event.target
|
224
|
+
var target = event.target;
|
255
225
|
|
256
226
|
// If the target of the event is not the element, close the picker picker.
|
257
227
|
// * Don’t worry about clicks or focusins on the root because those don’t bubble up.
|
@@ -260,335 +230,321 @@ function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
|
|
260
230
|
// * In Firefox stopPropagation() doesn’t prevent right-click events from bubbling,
|
261
231
|
// which causes the picker to unexpectedly close when right-clicking it. So make
|
262
232
|
// sure the event wasn’t a right-click.
|
263
|
-
if (
|
233
|
+
if (target != ELEMENT && target != document && event.which != 3) {
|
264
234
|
|
265
235
|
// If the target was the holder that covers the screen,
|
266
236
|
// keep the element focused to maintain tabindex.
|
267
|
-
P.close(
|
237
|
+
P.close(target === P.$root.children()[0]);
|
268
238
|
}
|
269
|
-
|
270
|
-
}).on( 'keydown.' + STATE.id, function( event ) {
|
239
|
+
}).on('keydown.' + STATE.id, function (event) {
|
271
240
|
|
272
241
|
var
|
273
|
-
|
274
|
-
|
242
|
+
// Get the keycode.
|
243
|
+
keycode = event.keyCode,
|
244
|
+
|
275
245
|
|
276
|
-
|
277
|
-
|
246
|
+
// Translate that to a selection change.
|
247
|
+
keycodeToMove = P.component.key[keycode],
|
278
248
|
|
279
|
-
// Grab the target.
|
280
|
-
target = event.target
|
281
249
|
|
250
|
+
// Grab the target.
|
251
|
+
target = event.target;
|
282
252
|
|
283
253
|
// On escape, close the picker and give focus.
|
284
|
-
if (
|
285
|
-
P.close(
|
254
|
+
if (keycode == 27) {
|
255
|
+
P.close(true);
|
286
256
|
}
|
287
257
|
|
288
|
-
|
289
258
|
// Check if there is a key movement or “enter” keypress on the element.
|
290
|
-
else if (
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
259
|
+
else if (target == P.$root[0] && (keycodeToMove || keycode == 13)) {
|
260
|
+
|
261
|
+
// Prevent the default action to stop page movement.
|
262
|
+
event.preventDefault();
|
263
|
+
|
264
|
+
// Trigger the key movement action.
|
265
|
+
if (keycodeToMove) {
|
266
|
+
PickerConstructor._.trigger(P.component.key.go, P, [PickerConstructor._.trigger(keycodeToMove)]);
|
267
|
+
}
|
268
|
+
|
269
|
+
// On “enter”, if the highlighted item isn’t disabled, set the value and close.
|
270
|
+
else if (!P.$root.find('.' + CLASSES.highlighted).hasClass(CLASSES.disabled)) {
|
271
|
+
P.set('select', P.component.item.highlight);
|
272
|
+
if (SETTINGS.closeOnSelect) {
|
273
|
+
P.close(true);
|
274
|
+
}
|
275
|
+
}
|
303
276
|
}
|
304
|
-
}
|
305
|
-
|
306
277
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
})
|
278
|
+
// If the target is within the root and “enter” is pressed,
|
279
|
+
// prevent the default action and trigger a click on the target instead.
|
280
|
+
else if ($.contains(P.$root[0], target) && keycode == 13) {
|
281
|
+
event.preventDefault();
|
282
|
+
target.click();
|
283
|
+
}
|
284
|
+
});
|
314
285
|
}
|
315
286
|
|
316
287
|
// Trigger the queued “open” events.
|
317
|
-
return P.trigger(
|
288
|
+
return P.trigger('open');
|
318
289
|
}, //open
|
319
290
|
|
320
291
|
|
321
292
|
/**
|
322
293
|
* Close the picker
|
323
294
|
*/
|
324
|
-
close: function(
|
295
|
+
close: function (giveFocus) {
|
325
296
|
|
326
297
|
// If we need to give focus, do it before changing states.
|
327
|
-
if (
|
298
|
+
if (giveFocus) {
|
328
299
|
// ....ah yes! It would’ve been incomplete without a crazy workaround for IE :|
|
329
300
|
// The focus is triggered *after* the close has completed - causing it
|
330
301
|
// to open again. So unbind and rebind the event at the next tick.
|
331
|
-
P.$root.off(
|
332
|
-
setTimeout(
|
333
|
-
P.$root.on(
|
334
|
-
}, 0
|
302
|
+
P.$root.off('focus.toOpen').eq(0).focus();
|
303
|
+
setTimeout(function () {
|
304
|
+
P.$root.on('focus.toOpen', handleFocusToOpenEvent);
|
305
|
+
}, 0);
|
335
306
|
}
|
336
307
|
|
337
308
|
// Remove the “active” class.
|
338
|
-
$ELEMENT.removeClass(
|
339
|
-
aria(
|
309
|
+
$ELEMENT.removeClass(CLASSES.active);
|
310
|
+
aria(ELEMENT, 'expanded', false);
|
340
311
|
|
341
312
|
// * A Firefox bug, when `html` has `overflow:hidden`, results in
|
342
313
|
// killing transitions :(. So remove the “opened” state on the next tick.
|
343
314
|
// Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
|
344
|
-
setTimeout(
|
315
|
+
setTimeout(function () {
|
345
316
|
|
346
317
|
// Remove the “opened” and “focused” class from the picker root.
|
347
|
-
P.$root.removeClass(
|
348
|
-
aria(
|
349
|
-
|
350
|
-
}, 0 )
|
318
|
+
P.$root.removeClass(CLASSES.opened + ' ' + CLASSES.focused);
|
319
|
+
aria(P.$root[0], 'hidden', true);
|
320
|
+
}, 0);
|
351
321
|
|
352
322
|
// If it’s already closed, do nothing more.
|
353
|
-
if (
|
323
|
+
if (!STATE.open) return P;
|
354
324
|
|
355
325
|
// Set it as closed.
|
356
|
-
STATE.open = false
|
326
|
+
STATE.open = false;
|
357
327
|
|
358
328
|
// Allow the page to scroll.
|
359
|
-
if (
|
360
|
-
$html.
|
361
|
-
css( 'overflow', '' ).
|
362
|
-
css( 'padding-right', '-=' + getScrollbarWidth() )
|
329
|
+
if (IS_DEFAULT_THEME) {
|
330
|
+
$html.css('overflow', '').css('padding-right', '-=' + getScrollbarWidth());
|
363
331
|
}
|
364
332
|
|
365
333
|
// Unbind the document events.
|
366
|
-
$document.off(
|
334
|
+
$document.off('.' + STATE.id);
|
367
335
|
|
368
336
|
// Trigger the queued “close” events.
|
369
|
-
return P.trigger(
|
337
|
+
return P.trigger('close');
|
370
338
|
}, //close
|
371
339
|
|
372
340
|
|
373
341
|
/**
|
374
342
|
* Clear the values
|
375
343
|
*/
|
376
|
-
clear: function(
|
377
|
-
return P.set(
|
344
|
+
clear: function (options) {
|
345
|
+
return P.set('clear', null, options);
|
378
346
|
}, //clear
|
379
347
|
|
380
348
|
|
381
349
|
/**
|
382
350
|
* Set something
|
383
351
|
*/
|
384
|
-
set: function(
|
352
|
+
set: function (thing, value, options) {
|
385
353
|
|
386
|
-
var thingItem,
|
387
|
-
|
388
|
-
|
354
|
+
var thingItem,
|
355
|
+
thingValue,
|
356
|
+
thingIsObject = $.isPlainObject(thing),
|
357
|
+
thingObject = thingIsObject ? thing : {};
|
389
358
|
|
390
359
|
// Make sure we have usable options.
|
391
|
-
options = thingIsObject && $.isPlainObject(
|
360
|
+
options = thingIsObject && $.isPlainObject(value) ? value : options || {};
|
392
361
|
|
393
|
-
if (
|
362
|
+
if (thing) {
|
394
363
|
|
395
364
|
// If the thing isn’t an object, make it one.
|
396
|
-
if (
|
397
|
-
thingObject[
|
365
|
+
if (!thingIsObject) {
|
366
|
+
thingObject[thing] = value;
|
398
367
|
}
|
399
368
|
|
400
369
|
// Go through the things of items to set.
|
401
|
-
for (
|
370
|
+
for (thingItem in thingObject) {
|
402
371
|
|
403
372
|
// Grab the value of the thing.
|
404
|
-
thingValue = thingObject[
|
373
|
+
thingValue = thingObject[thingItem];
|
405
374
|
|
406
375
|
// First, if the item exists and there’s a value, set it.
|
407
|
-
if (
|
408
|
-
if (
|
409
|
-
P.component.set(
|
376
|
+
if (thingItem in P.component.item) {
|
377
|
+
if (thingValue === undefined) thingValue = null;
|
378
|
+
P.component.set(thingItem, thingValue, options);
|
410
379
|
}
|
411
380
|
|
412
381
|
// Then, check to update the element value and broadcast a change.
|
413
|
-
if (
|
414
|
-
$ELEMENT.
|
415
|
-
val( thingItem == 'clear' ? '' : P.get( thingItem, SETTINGS.format ) ).
|
416
|
-
trigger( 'change' )
|
382
|
+
if (thingItem == 'select' || thingItem == 'clear') {
|
383
|
+
$ELEMENT.val(thingItem == 'clear' ? '' : P.get(thingItem, SETTINGS.format)).trigger('change');
|
417
384
|
}
|
418
385
|
}
|
419
386
|
|
420
387
|
// Render a new picker.
|
421
|
-
P.render()
|
388
|
+
P.render();
|
422
389
|
}
|
423
390
|
|
424
391
|
// When the method isn’t muted, trigger queued “set” events and pass the `thingObject`.
|
425
|
-
return options.muted ? P : P.trigger(
|
392
|
+
return options.muted ? P : P.trigger('set', thingObject);
|
426
393
|
}, //set
|
427
394
|
|
428
395
|
|
429
396
|
/**
|
430
397
|
* Get something
|
431
398
|
*/
|
432
|
-
get: function(
|
399
|
+
get: function (thing, format) {
|
433
400
|
|
434
401
|
// Make sure there’s something to get.
|
435
|
-
thing = thing || 'value'
|
402
|
+
thing = thing || 'value';
|
436
403
|
|
437
404
|
// If a picker state exists, return that.
|
438
|
-
if (
|
439
|
-
return STATE[
|
405
|
+
if (STATE[thing] != null) {
|
406
|
+
return STATE[thing];
|
440
407
|
}
|
441
408
|
|
442
409
|
// Return the submission value, if that.
|
443
|
-
if (
|
444
|
-
if (
|
445
|
-
return P._hidden.value
|
410
|
+
if (thing == 'valueSubmit') {
|
411
|
+
if (P._hidden) {
|
412
|
+
return P._hidden.value;
|
446
413
|
}
|
447
|
-
thing = 'value'
|
414
|
+
thing = 'value';
|
448
415
|
}
|
449
416
|
|
450
417
|
// Return the value, if that.
|
451
|
-
if (
|
452
|
-
return ELEMENT.value
|
418
|
+
if (thing == 'value') {
|
419
|
+
return ELEMENT.value;
|
453
420
|
}
|
454
421
|
|
455
422
|
// Check if a component item exists, return that.
|
456
|
-
if (
|
457
|
-
if (
|
458
|
-
var thingValue = P.component.get(
|
459
|
-
return thingValue ?
|
460
|
-
PickerConstructor._.trigger(
|
461
|
-
P.component.formats.toString,
|
462
|
-
P.component,
|
463
|
-
[ format, thingValue ]
|
464
|
-
) : ''
|
423
|
+
if (thing in P.component.item) {
|
424
|
+
if (typeof format == 'string') {
|
425
|
+
var thingValue = P.component.get(thing);
|
426
|
+
return thingValue ? PickerConstructor._.trigger(P.component.formats.toString, P.component, [format, thingValue]) : '';
|
465
427
|
}
|
466
|
-
return P.component.get(
|
428
|
+
return P.component.get(thing);
|
467
429
|
}
|
468
430
|
}, //get
|
469
431
|
|
470
432
|
|
471
|
-
|
472
433
|
/**
|
473
434
|
* Bind events on the things.
|
474
435
|
*/
|
475
|
-
on: function(
|
436
|
+
on: function (thing, method, internal) {
|
476
437
|
|
477
|
-
var thingName,
|
478
|
-
|
479
|
-
|
438
|
+
var thingName,
|
439
|
+
thingMethod,
|
440
|
+
thingIsObject = $.isPlainObject(thing),
|
441
|
+
thingObject = thingIsObject ? thing : {};
|
480
442
|
|
481
|
-
if (
|
443
|
+
if (thing) {
|
482
444
|
|
483
445
|
// If the thing isn’t an object, make it one.
|
484
|
-
if (
|
485
|
-
thingObject[
|
446
|
+
if (!thingIsObject) {
|
447
|
+
thingObject[thing] = method;
|
486
448
|
}
|
487
449
|
|
488
450
|
// Go through the things to bind to.
|
489
|
-
for (
|
451
|
+
for (thingName in thingObject) {
|
490
452
|
|
491
453
|
// Grab the method of the thing.
|
492
|
-
thingMethod = thingObject[
|
454
|
+
thingMethod = thingObject[thingName];
|
493
455
|
|
494
456
|
// If it was an internal binding, prefix it.
|
495
|
-
if (
|
496
|
-
thingName = '_' + thingName
|
457
|
+
if (internal) {
|
458
|
+
thingName = '_' + thingName;
|
497
459
|
}
|
498
460
|
|
499
461
|
// Make sure the thing methods collection exists.
|
500
|
-
STATE.methods[
|
462
|
+
STATE.methods[thingName] = STATE.methods[thingName] || [];
|
501
463
|
|
502
464
|
// Add the method to the relative method collection.
|
503
|
-
STATE.methods[
|
465
|
+
STATE.methods[thingName].push(thingMethod);
|
504
466
|
}
|
505
467
|
}
|
506
468
|
|
507
|
-
return P
|
469
|
+
return P;
|
508
470
|
}, //on
|
509
471
|
|
510
472
|
|
511
|
-
|
512
473
|
/**
|
513
474
|
* Unbind events on the things.
|
514
475
|
*/
|
515
|
-
off: function() {
|
516
|
-
var i,
|
476
|
+
off: function () {
|
477
|
+
var i,
|
478
|
+
thingName,
|
517
479
|
names = arguments;
|
518
|
-
for (
|
519
|
-
thingName = names[i]
|
520
|
-
if (
|
521
|
-
delete STATE.methods[thingName]
|
480
|
+
for (i = 0, namesCount = names.length; i < namesCount; i += 1) {
|
481
|
+
thingName = names[i];
|
482
|
+
if (thingName in STATE.methods) {
|
483
|
+
delete STATE.methods[thingName];
|
522
484
|
}
|
523
485
|
}
|
524
|
-
return P
|
486
|
+
return P;
|
525
487
|
},
|
526
488
|
|
527
|
-
|
528
489
|
/**
|
529
490
|
* Fire off method events.
|
530
491
|
*/
|
531
|
-
trigger: function(
|
532
|
-
var _trigger = function(
|
533
|
-
var methodList = STATE.methods[
|
534
|
-
if (
|
535
|
-
methodList.map(
|
536
|
-
PickerConstructor._.trigger(
|
537
|
-
})
|
492
|
+
trigger: function (name, data) {
|
493
|
+
var _trigger = function (name) {
|
494
|
+
var methodList = STATE.methods[name];
|
495
|
+
if (methodList) {
|
496
|
+
methodList.map(function (method) {
|
497
|
+
PickerConstructor._.trigger(method, P, [data]);
|
498
|
+
});
|
538
499
|
}
|
539
|
-
}
|
540
|
-
_trigger(
|
541
|
-
_trigger(
|
542
|
-
return P
|
500
|
+
};
|
501
|
+
_trigger('_' + name);
|
502
|
+
_trigger(name);
|
503
|
+
return P;
|
543
504
|
} //trigger
|
544
|
-
|
505
|
+
//PickerInstance.prototype
|
545
506
|
|
546
507
|
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
508
|
+
/**
|
509
|
+
* Wrap the picker holder components together.
|
510
|
+
*/
|
511
|
+
};function createWrappedComponent() {
|
551
512
|
|
552
|
-
|
553
|
-
|
513
|
+
// Create a picker wrapper holder
|
514
|
+
return PickerConstructor._.node('div',
|
554
515
|
|
555
516
|
// Create a picker wrapper node
|
556
|
-
PickerConstructor._.node(
|
517
|
+
PickerConstructor._.node('div',
|
557
518
|
|
558
|
-
|
559
|
-
|
519
|
+
// Create a picker frame
|
520
|
+
PickerConstructor._.node('div',
|
560
521
|
|
561
|
-
|
562
|
-
|
522
|
+
// Create a picker box node
|
523
|
+
PickerConstructor._.node('div',
|
563
524
|
|
564
|
-
|
565
|
-
|
525
|
+
// Create the components nodes.
|
526
|
+
P.component.nodes(STATE.open),
|
566
527
|
|
567
|
-
|
568
|
-
|
569
|
-
),
|
528
|
+
// The picker box class
|
529
|
+
CLASSES.box),
|
570
530
|
|
571
|
-
|
572
|
-
|
573
|
-
),
|
531
|
+
// Picker wrap class
|
532
|
+
CLASSES.wrap),
|
574
533
|
|
575
|
-
|
576
|
-
|
577
|
-
),
|
534
|
+
// Picker frame class
|
535
|
+
CLASSES.frame),
|
578
536
|
|
579
537
|
// Picker holder class
|
580
|
-
CLASSES.holder
|
581
|
-
|
582
|
-
} //createWrappedComponent
|
538
|
+
CLASSES.holder); //endreturn
|
539
|
+
} //createWrappedComponent
|
583
540
|
|
584
541
|
|
542
|
+
/**
|
543
|
+
* Prepare the input element with all bindings.
|
544
|
+
*/
|
545
|
+
function prepareElement() {
|
585
546
|
|
586
|
-
|
587
|
-
* Prepare the input element with all bindings.
|
588
|
-
*/
|
589
|
-
function prepareElement() {
|
590
|
-
|
591
|
-
$ELEMENT.
|
547
|
+
$ELEMENT.
|
592
548
|
|
593
549
|
// Store the picker data by component name.
|
594
550
|
data(NAME, P).
|
@@ -600,79 +556,71 @@ function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
|
|
600
556
|
attr('tabindex', -1).
|
601
557
|
|
602
558
|
// If there’s a `data-value`, update the value of the element.
|
603
|
-
val(
|
604
|
-
P.get('select', SETTINGS.format) :
|
605
|
-
ELEMENT.value
|
606
|
-
)
|
607
|
-
|
559
|
+
val($ELEMENT.data('value') ? P.get('select', SETTINGS.format) : ELEMENT.value);
|
608
560
|
|
609
|
-
|
610
|
-
|
561
|
+
// Only bind keydown events if the element isn’t editable.
|
562
|
+
if (!SETTINGS.editable) {
|
611
563
|
|
612
|
-
|
564
|
+
$ELEMENT.
|
613
565
|
|
614
566
|
// On focus/click, focus onto the root to open it up.
|
615
|
-
on(
|
616
|
-
event.preventDefault()
|
617
|
-
P.$root.eq(0).focus()
|
567
|
+
on('focus.' + STATE.id + ' click.' + STATE.id, function (event) {
|
568
|
+
event.preventDefault();
|
569
|
+
P.$root.eq(0).focus();
|
618
570
|
}).
|
619
571
|
|
620
572
|
// Handle keyboard event based on the picker being opened or not.
|
621
|
-
on(
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
// Update the aria attributes.
|
626
|
-
aria(ELEMENT, {
|
627
|
-
haspopup: true,
|
628
|
-
expanded: false,
|
629
|
-
readonly: false,
|
630
|
-
owns: ELEMENT.id + '_root'
|
631
|
-
})
|
632
|
-
}
|
633
|
-
|
573
|
+
on('keydown.' + STATE.id, handleKeydownEvent);
|
574
|
+
}
|
634
575
|
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
576
|
+
// Update the aria attributes.
|
577
|
+
aria(ELEMENT, {
|
578
|
+
haspopup: true,
|
579
|
+
expanded: false,
|
580
|
+
readonly: false,
|
581
|
+
owns: ELEMENT.id + '_root'
|
582
|
+
});
|
583
|
+
}
|
639
584
|
|
640
|
-
|
585
|
+
/**
|
586
|
+
* Prepare the root picker element with all bindings.
|
587
|
+
*/
|
588
|
+
function prepareElementRoot() {
|
641
589
|
|
642
|
-
on({
|
590
|
+
P.$root.on({
|
643
591
|
|
644
592
|
// For iOS8.
|
645
593
|
keydown: handleKeydownEvent,
|
646
594
|
|
647
595
|
// When something within the root is focused, stop from bubbling
|
648
596
|
// to the doc and remove the “focused” state from the root.
|
649
|
-
focusin: function(
|
650
|
-
P.$root.removeClass(
|
651
|
-
event.stopPropagation()
|
597
|
+
focusin: function (event) {
|
598
|
+
P.$root.removeClass(CLASSES.focused);
|
599
|
+
event.stopPropagation();
|
652
600
|
},
|
653
601
|
|
654
602
|
// When something within the root holder is clicked, stop it
|
655
603
|
// from bubbling to the doc.
|
656
|
-
'mousedown click': function(
|
604
|
+
'mousedown click': function (event) {
|
657
605
|
|
658
|
-
var target = event.target
|
606
|
+
var target = event.target;
|
659
607
|
|
660
608
|
// Make sure the target isn’t the root holder so it can bubble up.
|
661
|
-
if (
|
609
|
+
if (target != P.$root.children()[0]) {
|
662
610
|
|
663
|
-
event.stopPropagation()
|
611
|
+
event.stopPropagation();
|
664
612
|
|
665
613
|
// * For mousedown events, cancel the default action in order to
|
666
614
|
// prevent cases where focus is shifted onto external elements
|
667
615
|
// when using things like jQuery mobile or MagnificPopup (ref: #249 & #120).
|
668
616
|
// Also, for Firefox, don’t prevent action on the `option` element.
|
669
|
-
if (
|
617
|
+
if (event.type == 'mousedown' && !$(target).is('input, select, textarea, button, option')) {
|
670
618
|
|
671
|
-
event.preventDefault()
|
619
|
+
event.preventDefault();
|
672
620
|
|
673
621
|
// Re-focus onto the root so that users can click away
|
674
622
|
// from elements focused within the picker.
|
675
|
-
P.$root.eq(0).focus()
|
623
|
+
P.$root.eq(0).focus();
|
676
624
|
}
|
677
625
|
}
|
678
626
|
}
|
@@ -680,443 +628,407 @@ function PickerConstructor( ELEMENT, NAME, COMPONENT, OPTIONS ) {
|
|
680
628
|
|
681
629
|
// Add/remove the “target” class on focus and blur.
|
682
630
|
on({
|
683
|
-
focus: function() {
|
684
|
-
$ELEMENT.addClass(
|
631
|
+
focus: function () {
|
632
|
+
$ELEMENT.addClass(CLASSES.target);
|
685
633
|
},
|
686
|
-
blur: function() {
|
687
|
-
$ELEMENT.removeClass(
|
634
|
+
blur: function () {
|
635
|
+
$ELEMENT.removeClass(CLASSES.target);
|
688
636
|
}
|
689
637
|
}).
|
690
638
|
|
691
639
|
// Open the picker and adjust the root “focused” state
|
692
|
-
on(
|
640
|
+
on('focus.toOpen', handleFocusToOpenEvent).
|
693
641
|
|
694
642
|
// If there’s a click on an actionable element, carry out the actions.
|
695
|
-
on(
|
643
|
+
on('click', '[data-pick], [data-nav], [data-clear], [data-close]', function () {
|
696
644
|
|
697
|
-
var $target = $(
|
645
|
+
var $target = $(this),
|
698
646
|
targetData = $target.data(),
|
699
|
-
targetDisabled = $target.hasClass(
|
647
|
+
targetDisabled = $target.hasClass(CLASSES.navDisabled) || $target.hasClass(CLASSES.disabled),
|
648
|
+
|
700
649
|
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
650
|
+
// * For IE, non-focusable elements can be active elements as well
|
651
|
+
// (http://stackoverflow.com/a/2684561).
|
652
|
+
activeElement = getActiveElement();
|
653
|
+
activeElement = activeElement && (activeElement.type || activeElement.href);
|
705
654
|
|
706
655
|
// If it’s disabled or nothing inside is actively focused, re-focus the element.
|
707
|
-
if (
|
708
|
-
P.$root.eq(0).focus()
|
656
|
+
if (targetDisabled || activeElement && !$.contains(P.$root[0], activeElement)) {
|
657
|
+
P.$root.eq(0).focus();
|
709
658
|
}
|
710
659
|
|
711
660
|
// If something is superficially changed, update the `highlight` based on the `nav`.
|
712
|
-
if (
|
713
|
-
P.set(
|
661
|
+
if (!targetDisabled && targetData.nav) {
|
662
|
+
P.set('highlight', P.component.item.highlight, { nav: targetData.nav });
|
714
663
|
}
|
715
664
|
|
716
665
|
// If something is picked, set `select` then close with focus.
|
717
|
-
else if (
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
P.clear().close( true )
|
724
|
-
}
|
725
|
-
|
726
|
-
else if ( targetData.close ) {
|
727
|
-
P.close( true )
|
728
|
-
}
|
729
|
-
|
730
|
-
}) //P.$root
|
666
|
+
else if (!targetDisabled && 'pick' in targetData) {
|
667
|
+
P.set('select', targetData.pick);
|
668
|
+
if (SETTINGS.closeOnSelect) {
|
669
|
+
P.close(true);
|
670
|
+
}
|
671
|
+
}
|
731
672
|
|
732
|
-
|
733
|
-
|
673
|
+
// If a “clear” button is pressed, empty the values and close with focus.
|
674
|
+
else if (targetData.clear) {
|
675
|
+
P.clear();
|
676
|
+
if (SETTINGS.closeOnSelect) {
|
677
|
+
P.close(true);
|
678
|
+
}
|
679
|
+
} else if (targetData.close) {
|
680
|
+
P.close(true);
|
681
|
+
}
|
682
|
+
}); //P.$root
|
734
683
|
|
684
|
+
aria(P.$root[0], 'hidden', true);
|
685
|
+
}
|
735
686
|
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
687
|
+
/**
|
688
|
+
* Prepare the hidden input element along with all bindings.
|
689
|
+
*/
|
690
|
+
function prepareElementHidden() {
|
740
691
|
|
741
|
-
|
692
|
+
var name;
|
742
693
|
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
typeof SETTINGS.hiddenSuffix == 'string' ? SETTINGS.hiddenSuffix : '_submit'
|
751
|
-
]
|
752
|
-
name = name[0] + ELEMENT.name + name[1]
|
753
|
-
}
|
694
|
+
if (SETTINGS.hiddenName === true) {
|
695
|
+
name = ELEMENT.name;
|
696
|
+
ELEMENT.name = '';
|
697
|
+
} else {
|
698
|
+
name = [typeof SETTINGS.hiddenPrefix == 'string' ? SETTINGS.hiddenPrefix : '', typeof SETTINGS.hiddenSuffix == 'string' ? SETTINGS.hiddenSuffix : '_submit'];
|
699
|
+
name = name[0] + ELEMENT.name + name[1];
|
700
|
+
}
|
754
701
|
|
755
|
-
|
756
|
-
'<input ' +
|
757
|
-
'type=hidden ' +
|
702
|
+
P._hidden = $('<input ' + 'type=hidden ' +
|
758
703
|
|
759
704
|
// Create the name using the original input’s with a prefix and suffix.
|
760
|
-
'name="' + name + '"' +
|
705
|
+
'name="' + name + '"' + (
|
761
706
|
|
762
707
|
// If the element has a value, set the hidden value as well.
|
763
|
-
(
|
764
|
-
$ELEMENT.data('value') || ELEMENT.value ?
|
765
|
-
' value="' + P.get('select', SETTINGS.formatSubmit) + '"' :
|
766
|
-
''
|
767
|
-
) +
|
768
|
-
'>'
|
769
|
-
)[0]
|
708
|
+
$ELEMENT.data('value') || ELEMENT.value ? ' value="' + P.get('select', SETTINGS.formatSubmit) + '"' : '') + '>')[0];
|
770
709
|
|
771
|
-
|
710
|
+
$ELEMENT.
|
772
711
|
|
773
712
|
// If the value changes, update the hidden input with the correct format.
|
774
|
-
on('change.' + STATE.id, function() {
|
775
|
-
P._hidden.value = ELEMENT.value ?
|
776
|
-
|
777
|
-
''
|
778
|
-
})
|
713
|
+
on('change.' + STATE.id, function () {
|
714
|
+
P._hidden.value = ELEMENT.value ? P.get('select', SETTINGS.formatSubmit) : '';
|
715
|
+
});
|
779
716
|
|
717
|
+
// Insert the hidden input as specified in the settings.
|
718
|
+
if (SETTINGS.container) $(SETTINGS.container).append(P._hidden);else $ELEMENT.before(P._hidden);
|
719
|
+
}
|
780
720
|
|
781
|
-
//
|
782
|
-
|
783
|
-
else $ELEMENT.after( P._hidden )
|
784
|
-
}
|
785
|
-
|
721
|
+
// For iOS8.
|
722
|
+
function handleKeydownEvent(event) {
|
786
723
|
|
787
|
-
|
788
|
-
function handleKeydownEvent( event ) {
|
724
|
+
var keycode = event.keyCode,
|
789
725
|
|
790
|
-
var keycode = event.keyCode,
|
791
726
|
|
792
727
|
// Check if one of the delete keys was pressed.
|
793
|
-
isKeycodeDelete = /^(8|46)$/.test(keycode)
|
728
|
+
isKeycodeDelete = /^(8|46)$/.test(keycode);
|
794
729
|
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
730
|
+
// For some reason IE clears the input value on “escape”.
|
731
|
+
if (keycode == 27) {
|
732
|
+
P.close();
|
733
|
+
return false;
|
734
|
+
}
|
800
735
|
|
801
|
-
|
802
|
-
|
736
|
+
// Check if `space` or `delete` was pressed or the picker is closed with a key movement.
|
737
|
+
if (keycode == 32 || isKeycodeDelete || !STATE.open && P.component.key[keycode]) {
|
803
738
|
|
804
|
-
|
805
|
-
|
806
|
-
|
739
|
+
// Prevent it from moving the page and bubbling to doc.
|
740
|
+
event.preventDefault();
|
741
|
+
event.stopPropagation();
|
807
742
|
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
743
|
+
// If `delete` was pressed, clear the values and close the picker.
|
744
|
+
// Otherwise open the picker.
|
745
|
+
if (isKeycodeDelete) {
|
746
|
+
P.clear().close();
|
747
|
+
} else {
|
748
|
+
P.open();
|
749
|
+
}
|
750
|
+
}
|
812
751
|
}
|
813
|
-
}
|
814
752
|
|
753
|
+
// Separated for IE
|
754
|
+
function handleFocusToOpenEvent(event) {
|
815
755
|
|
816
|
-
|
817
|
-
|
756
|
+
// Stop the event from propagating to the doc.
|
757
|
+
event.stopPropagation();
|
818
758
|
|
819
|
-
|
820
|
-
|
759
|
+
// If it’s a focus event, add the “focused” class to the root.
|
760
|
+
if (event.type == 'focus') {
|
761
|
+
P.$root.addClass(CLASSES.focused);
|
762
|
+
}
|
821
763
|
|
822
|
-
|
823
|
-
|
824
|
-
P.$root.addClass( CLASSES.focused )
|
764
|
+
// And then finally open the picker.
|
765
|
+
P.open();
|
825
766
|
}
|
826
767
|
|
827
|
-
//
|
828
|
-
|
829
|
-
}
|
830
|
-
|
831
|
-
|
832
|
-
// Return a new picker instance.
|
833
|
-
return new PickerInstance()
|
834
|
-
} //PickerConstructor
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
/**
|
839
|
-
* The default classes and prefix to use for the HTML classes.
|
840
|
-
*/
|
841
|
-
PickerConstructor.klasses = function( prefix ) {
|
842
|
-
prefix = prefix || 'picker'
|
843
|
-
return {
|
844
|
-
|
845
|
-
picker: prefix,
|
846
|
-
opened: prefix + '--opened',
|
847
|
-
focused: prefix + '--focused',
|
848
|
-
|
849
|
-
input: prefix + '__input',
|
850
|
-
active: prefix + '__input--active',
|
851
|
-
target: prefix + '__input--target',
|
852
|
-
|
853
|
-
holder: prefix + '__holder',
|
768
|
+
// Return a new picker instance.
|
769
|
+
return new PickerInstance();
|
770
|
+
} //PickerConstructor
|
854
771
|
|
855
|
-
frame: prefix + '__frame',
|
856
|
-
wrap: prefix + '__wrap',
|
857
772
|
|
858
|
-
|
859
|
-
|
860
|
-
|
773
|
+
/**
|
774
|
+
* The default classes and prefix to use for the HTML classes.
|
775
|
+
*/
|
776
|
+
PickerConstructor.klasses = function (prefix) {
|
777
|
+
prefix = prefix || 'picker';
|
778
|
+
return {
|
861
779
|
|
780
|
+
picker: prefix,
|
781
|
+
opened: prefix + '--opened',
|
782
|
+
focused: prefix + '--focused',
|
862
783
|
|
784
|
+
input: prefix + '__input',
|
785
|
+
active: prefix + '__input--active',
|
786
|
+
target: prefix + '__input--target',
|
863
787
|
|
864
|
-
|
865
|
-
* Check if the default theme is being used.
|
866
|
-
*/
|
867
|
-
function isUsingDefaultTheme( element ) {
|
788
|
+
holder: prefix + '__holder',
|
868
789
|
|
869
|
-
|
870
|
-
|
790
|
+
frame: prefix + '__frame',
|
791
|
+
wrap: prefix + '__wrap',
|
871
792
|
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
}
|
793
|
+
box: prefix + '__box'
|
794
|
+
};
|
795
|
+
}; //PickerConstructor.klasses
|
876
796
|
|
877
|
-
// For normal browsers.
|
878
|
-
else if ( window.getComputedStyle ) {
|
879
|
-
theme = getComputedStyle( element )[prop]
|
880
|
-
}
|
881
797
|
|
882
|
-
|
883
|
-
|
798
|
+
/**
|
799
|
+
* Check if the default theme is being used.
|
800
|
+
*/
|
801
|
+
function isUsingDefaultTheme(element) {
|
884
802
|
|
803
|
+
var theme,
|
804
|
+
prop = 'position';
|
885
805
|
|
806
|
+
// For IE.
|
807
|
+
if (element.currentStyle) {
|
808
|
+
theme = element.currentStyle[prop];
|
809
|
+
}
|
886
810
|
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
function getScrollbarWidth() {
|
811
|
+
// For normal browsers.
|
812
|
+
else if (window.getComputedStyle) {
|
813
|
+
theme = getComputedStyle(element)[prop];
|
814
|
+
}
|
892
815
|
|
893
|
-
|
894
|
-
return 0
|
816
|
+
return theme == 'fixed';
|
895
817
|
}
|
896
818
|
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
819
|
+
/**
|
820
|
+
* Get the width of the browser’s scrollbar.
|
821
|
+
* Taken from: https://github.com/VodkaBears/Remodal/blob/master/src/jquery.remodal.js
|
822
|
+
*/
|
823
|
+
function getScrollbarWidth() {
|
902
824
|
|
903
|
-
|
904
|
-
|
825
|
+
if ($html.height() <= $window.height()) {
|
826
|
+
return 0;
|
827
|
+
}
|
905
828
|
|
906
|
-
|
907
|
-
var $inner = $( '<div style="width:100%" />' ).appendTo( $outer )
|
829
|
+
var $outer = $('<div style="visibility:hidden;width:100px" />').appendTo('body');
|
908
830
|
|
909
|
-
|
910
|
-
|
831
|
+
// Get the width without scrollbars.
|
832
|
+
var widthWithoutScroll = $outer[0].offsetWidth;
|
911
833
|
|
912
|
-
|
913
|
-
|
834
|
+
// Force adding scrollbars.
|
835
|
+
$outer.css('overflow', 'scroll');
|
914
836
|
|
915
|
-
|
916
|
-
|
917
|
-
}
|
837
|
+
// Add the inner div.
|
838
|
+
var $inner = $('<div style="width:100%" />').appendTo($outer);
|
918
839
|
|
840
|
+
// Get the width with scrollbars.
|
841
|
+
var widthWithScroll = $inner[0].offsetWidth;
|
919
842
|
|
843
|
+
// Remove the divs.
|
844
|
+
$outer.remove();
|
920
845
|
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
PickerConstructor._ = {
|
846
|
+
// Return the difference between the widths.
|
847
|
+
return widthWithoutScroll - widthWithScroll;
|
848
|
+
}
|
925
849
|
|
926
850
|
/**
|
927
|
-
*
|
928
|
-
* `
|
929
|
-
{
|
930
|
-
min: {Integer},
|
931
|
-
max: {Integer},
|
932
|
-
i: {Integer},
|
933
|
-
node: {String},
|
934
|
-
item: {Function}
|
935
|
-
}
|
936
|
-
* `
|
851
|
+
* PickerConstructor helper methods.
|
937
852
|
*/
|
938
|
-
|
853
|
+
PickerConstructor._ = {
|
854
|
+
|
855
|
+
/**
|
856
|
+
* Create a group of nodes. Expects:
|
857
|
+
* `
|
858
|
+
{
|
859
|
+
min: {Integer},
|
860
|
+
max: {Integer},
|
861
|
+
i: {Integer},
|
862
|
+
node: {String},
|
863
|
+
item: {Function}
|
864
|
+
}
|
865
|
+
* `
|
866
|
+
*/
|
867
|
+
group: function (groupObject) {
|
939
868
|
|
940
|
-
|
869
|
+
var
|
941
870
|
// Scope for the looped object
|
942
871
|
loopObjectScope,
|
943
872
|
|
873
|
+
|
944
874
|
// Create the nodes list
|
945
875
|
nodesList = '',
|
946
876
|
|
947
|
-
// The counter starts from the `min`
|
948
|
-
counter = PickerConstructor._.trigger( groupObject.min, groupObject )
|
949
|
-
|
950
|
-
|
951
|
-
// Loop from the `min` to `max`, incrementing by `i`
|
952
|
-
for ( ; counter <= PickerConstructor._.trigger( groupObject.max, groupObject, [ counter ] ); counter += groupObject.i ) {
|
953
|
-
|
954
|
-
// Trigger the `item` function within scope of the object
|
955
|
-
loopObjectScope = PickerConstructor._.trigger( groupObject.item, groupObject, [ counter ] )
|
956
|
-
|
957
|
-
// Splice the subgroup and create nodes out of the sub nodes
|
958
|
-
nodesList += PickerConstructor._.node(
|
959
|
-
groupObject.node,
|
960
|
-
loopObjectScope[ 0 ], // the node
|
961
|
-
loopObjectScope[ 1 ], // the classes
|
962
|
-
loopObjectScope[ 2 ] // the attributes
|
963
|
-
)
|
964
|
-
}
|
965
|
-
|
966
|
-
// Return the list of nodes
|
967
|
-
return nodesList
|
968
|
-
}, //group
|
969
877
|
|
878
|
+
// The counter starts from the `min`
|
879
|
+
counter = PickerConstructor._.trigger(groupObject.min, groupObject);
|
970
880
|
|
971
|
-
|
972
|
-
|
973
|
-
*/
|
974
|
-
node: function( wrapper, item, klass, attribute ) {
|
975
|
-
|
976
|
-
// If the item is false-y, just return an empty string
|
977
|
-
if ( !item ) return ''
|
978
|
-
|
979
|
-
// If the item is an array, do a join
|
980
|
-
item = $.isArray( item ) ? item.join( '' ) : item
|
881
|
+
// Loop from the `min` to `max`, incrementing by `i`
|
882
|
+
for (; counter <= PickerConstructor._.trigger(groupObject.max, groupObject, [counter]); counter += groupObject.i) {
|
981
883
|
|
982
|
-
|
983
|
-
|
884
|
+
// Trigger the `item` function within scope of the object
|
885
|
+
loopObjectScope = PickerConstructor._.trigger(groupObject.item, groupObject, [counter]);
|
984
886
|
|
985
|
-
|
986
|
-
|
887
|
+
// Splice the subgroup and create nodes out of the sub nodes
|
888
|
+
nodesList += PickerConstructor._.node(groupObject.node, loopObjectScope[0], // the node
|
889
|
+
loopObjectScope[1], // the classes
|
890
|
+
loopObjectScope[2] // the attributes
|
891
|
+
);
|
892
|
+
}
|
987
893
|
|
988
|
-
|
989
|
-
|
990
|
-
|
894
|
+
// Return the list of nodes
|
895
|
+
return nodesList;
|
896
|
+
}, //group
|
991
897
|
|
992
898
|
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
return ( number < 10 ? '0': '' ) + number
|
998
|
-
},
|
899
|
+
/**
|
900
|
+
* Create a dom node string
|
901
|
+
*/
|
902
|
+
node: function (wrapper, item, klass, attribute) {
|
999
903
|
|
904
|
+
// If the item is false-y, just return an empty string
|
905
|
+
if (!item) return '';
|
1000
906
|
|
1001
|
-
|
1002
|
-
|
1003
|
-
*/
|
1004
|
-
trigger: function( callback, scope, args ) {
|
1005
|
-
return typeof callback == 'function' ? callback.apply( scope, args || [] ) : callback
|
1006
|
-
},
|
907
|
+
// If the item is an array, do a join
|
908
|
+
item = $.isArray(item) ? item.join('') : item;
|
1007
909
|
|
910
|
+
// Check for the class
|
911
|
+
klass = klass ? ' class="' + klass + '"' : '';
|
1008
912
|
|
1009
|
-
|
1010
|
-
|
1011
|
-
*/
|
1012
|
-
digits: function( string ) {
|
1013
|
-
return ( /\d/ ).test( string[ 1 ] ) ? 2 : 1
|
1014
|
-
},
|
913
|
+
// Check for any attributes
|
914
|
+
attribute = attribute ? ' ' + attribute : '';
|
1015
915
|
|
916
|
+
// Return the wrapped item
|
917
|
+
return '<' + wrapper + klass + attribute + '>' + item + '</' + wrapper + '>';
|
918
|
+
}, //node
|
1016
919
|
|
1017
|
-
/**
|
1018
|
-
* Tell if something is a date object.
|
1019
|
-
*/
|
1020
|
-
isDate: function( value ) {
|
1021
|
-
return {}.toString.call( value ).indexOf( 'Date' ) > -1 && this.isInteger( value.getDate() )
|
1022
|
-
},
|
1023
920
|
|
921
|
+
/**
|
922
|
+
* Lead numbers below 10 with a zero.
|
923
|
+
*/
|
924
|
+
lead: function (number) {
|
925
|
+
return (number < 10 ? '0' : '') + number;
|
926
|
+
},
|
1024
927
|
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
928
|
+
/**
|
929
|
+
* Trigger a function otherwise return the value.
|
930
|
+
*/
|
931
|
+
trigger: function (callback, scope, args) {
|
932
|
+
return typeof callback == 'function' ? callback.apply(scope, args || []) : callback;
|
933
|
+
},
|
1031
934
|
|
935
|
+
/**
|
936
|
+
* If the second character is a digit, length is 2 otherwise 1.
|
937
|
+
*/
|
938
|
+
digits: function (string) {
|
939
|
+
return (/\d/.test(string[1]) ? 2 : 1
|
940
|
+
);
|
941
|
+
},
|
1032
942
|
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
}
|
943
|
+
/**
|
944
|
+
* Tell if something is a date object.
|
945
|
+
*/
|
946
|
+
isDate: function (value) {
|
947
|
+
return {}.toString.call(value).indexOf('Date') > -1 && this.isInteger(value.getDate());
|
948
|
+
},
|
1038
949
|
|
950
|
+
/**
|
951
|
+
* Tell if something is an integer.
|
952
|
+
*/
|
953
|
+
isInteger: function (value) {
|
954
|
+
return {}.toString.call(value).indexOf('Number') > -1 && value % 1 === 0;
|
955
|
+
},
|
1039
956
|
|
957
|
+
/**
|
958
|
+
* Create ARIA attribute strings.
|
959
|
+
*/
|
960
|
+
ariaAttr: ariaAttr //PickerConstructor._
|
1040
961
|
|
1041
|
-
/**
|
1042
|
-
* Extend the picker with a component and defaults.
|
1043
|
-
*/
|
1044
|
-
PickerConstructor.extend = function( name, Component ) {
|
1045
962
|
|
1046
|
-
|
1047
|
-
|
963
|
+
/**
|
964
|
+
* Extend the picker with a component and defaults.
|
965
|
+
*/
|
966
|
+
};PickerConstructor.extend = function (name, Component) {
|
1048
967
|
|
1049
|
-
//
|
1050
|
-
|
968
|
+
// Extend jQuery.
|
969
|
+
$.fn[name] = function (options, action) {
|
1051
970
|
|
1052
|
-
|
1053
|
-
|
1054
|
-
return componentData
|
1055
|
-
}
|
971
|
+
// Grab the component data.
|
972
|
+
var componentData = this.data(name);
|
1056
973
|
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
974
|
+
// If the picker is requested, return the data object.
|
975
|
+
if (options == 'picker') {
|
976
|
+
return componentData;
|
977
|
+
}
|
1061
978
|
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
return this.each( function() {
|
1066
|
-
var $this = $( this )
|
1067
|
-
if ( !$this.data( name ) ) {
|
1068
|
-
new PickerConstructor( this, name, Component, options )
|
979
|
+
// If the component data exists and `options` is a string, carry out the action.
|
980
|
+
if (componentData && typeof options == 'string') {
|
981
|
+
return PickerConstructor._.trigger(componentData[options], componentData, [action]);
|
1069
982
|
}
|
1070
|
-
})
|
1071
|
-
}
|
1072
983
|
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
984
|
+
// Otherwise go through each matched element and if the component
|
985
|
+
// doesn’t exist, create a new picker using `this` element
|
986
|
+
// and merging the defaults and options with a deep copy.
|
987
|
+
return this.each(function () {
|
988
|
+
var $this = $(this);
|
989
|
+
if (!$this.data(name)) {
|
990
|
+
new PickerConstructor(this, name, Component, options);
|
991
|
+
}
|
992
|
+
});
|
993
|
+
};
|
1076
994
|
|
995
|
+
// Set the defaults.
|
996
|
+
$.fn[name].defaults = Component.defaults;
|
997
|
+
}; //PickerConstructor.extend
|
1077
998
|
|
1078
999
|
|
1079
|
-
function aria(element, attribute, value) {
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1000
|
+
function aria(element, attribute, value) {
|
1001
|
+
if ($.isPlainObject(attribute)) {
|
1002
|
+
for (var key in attribute) {
|
1003
|
+
ariaSet(element, key, attribute[key]);
|
1004
|
+
}
|
1005
|
+
} else {
|
1006
|
+
ariaSet(element, attribute, value);
|
1083
1007
|
}
|
1084
1008
|
}
|
1085
|
-
|
1086
|
-
|
1009
|
+
function ariaSet(element, attribute, value) {
|
1010
|
+
element.setAttribute((attribute == 'role' ? '' : 'aria-') + attribute, value);
|
1087
1011
|
}
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
data = ''
|
1100
|
-
for ( var key in attribute ) {
|
1101
|
-
var attr = (key == 'role' ? '' : 'aria-') + key,
|
1102
|
-
attrVal = attribute[key]
|
1103
|
-
data += attrVal == null ? '' : attr + '="' + attribute[key] + '"'
|
1012
|
+
function ariaAttr(attribute, data) {
|
1013
|
+
if (!$.isPlainObject(attribute)) {
|
1014
|
+
attribute = { attribute: data };
|
1015
|
+
}
|
1016
|
+
data = '';
|
1017
|
+
for (var key in attribute) {
|
1018
|
+
var attr = (key == 'role' ? '' : 'aria-') + key,
|
1019
|
+
attrVal = attribute[key];
|
1020
|
+
data += attrVal == null ? '' : attr + '="' + attribute[key] + '"';
|
1021
|
+
}
|
1022
|
+
return data;
|
1104
1023
|
}
|
1105
|
-
return data
|
1106
|
-
}
|
1107
|
-
|
1108
|
-
// IE8 bug throws an error for activeElements within iframes.
|
1109
|
-
function getActiveElement() {
|
1110
|
-
try {
|
1111
|
-
return document.activeElement
|
1112
|
-
} catch ( err ) { }
|
1113
|
-
}
|
1114
|
-
|
1115
1024
|
|
1025
|
+
// IE8 bug throws an error for activeElements within iframes.
|
1026
|
+
function getActiveElement() {
|
1027
|
+
try {
|
1028
|
+
return document.activeElement;
|
1029
|
+
} catch (err) {}
|
1030
|
+
}
|
1116
1031
|
|
1117
|
-
// Expose the picker constructor.
|
1118
|
-
return PickerConstructor
|
1119
|
-
|
1120
|
-
|
1121
|
-
}));
|
1122
|
-
|
1032
|
+
// Expose the picker constructor.
|
1033
|
+
return PickerConstructor;
|
1034
|
+
});
|