jekyll-theme-mdui 0.2.1 → 0.2.2

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.
@@ -1,2558 +1,9 @@
1
- (function (factory) {
2
-
3
- // AMD.
4
- if (typeof define == 'function' && define.amd)
5
- define('picker', ['jquery'], factory)
6
-
7
- // Node.js/browserify.
8
- else if (typeof exports == 'object')
9
- module.exports = factory(require('jquery'))
10
-
11
- // Browser globals.
12
- else this.Picker = factory(jQuery)
13
-
14
- }(function ($) {
15
-
16
- var $window = $(window)
17
- var $document = $(document)
18
- var $html = $(document.documentElement)
19
-
20
-
21
- /**
22
- * The picker constructor that creates a blank picker.
23
- */
24
- function PickerConstructor(ELEMENT, NAME, COMPONENT, OPTIONS) {
25
-
26
- // If there’s no element, return the picker constructor.
27
- if (!ELEMENT) return PickerConstructor
28
-
29
-
30
- var
31
- IS_DEFAULT_THEME = false,
32
-
33
-
34
- // The state of the picker.
35
- STATE = {
36
- id: ELEMENT.id || 'P' + Math.abs(~~(Math.random() * new Date()))
37
- },
38
-
39
-
40
- // Merge the defaults and options passed.
41
- SETTINGS = COMPONENT ? $.extend(true, {}, COMPONENT.defaults, OPTIONS) : OPTIONS || {},
42
-
43
-
44
- // Merge the default classes with the settings classes.
45
- CLASSES = $.extend({}, PickerConstructor.klasses(), SETTINGS.klass),
46
-
47
-
48
- // The element node wrapper into a jQuery object.
49
- $ELEMENT = $(ELEMENT),
50
-
51
-
52
- // Pseudo picker constructor.
53
- PickerInstance = function () {
54
- return this.start()
55
- },
56
-
57
-
58
- // The picker prototype.
59
- P = PickerInstance.prototype = {
60
-
61
- constructor: PickerInstance,
62
-
63
- $node: $ELEMENT,
64
-
65
-
66
- /**
67
- * Initialize everything
68
- */
69
- start: function () {
70
-
71
- // If it’s already started, do nothing.
72
- if (STATE && STATE.start) return P
73
-
74
-
75
- // Update the picker states.
76
- STATE.methods = {}
77
- STATE.start = true
78
- STATE.open = false
79
- STATE.type = ELEMENT.type
80
-
81
-
82
- // Confirm focus state, convert into text input to remove UA stylings,
83
- // and set as readonly to prevent keyboard popup.
84
- ELEMENT.autofocus = ELEMENT == getActiveElement()
85
- ELEMENT.readOnly = !SETTINGS.editable
86
- ELEMENT.id = ELEMENT.id || STATE.id
87
- if (ELEMENT.type != 'text') {
88
- ELEMENT.type = 'text'
89
- }
90
-
91
-
92
- // Create a new picker component with the settings.
93
- P.component = new COMPONENT(P, SETTINGS)
94
-
95
-
96
- // Create the picker root with a holder and then prepare it.
97
- P.$root = $(PickerConstructor._.node('div', createWrappedComponent(), CLASSES.picker, 'id="' + ELEMENT.id + '_root" tabindex="0"'))
98
- prepareElementRoot()
99
-
100
-
101
- // If there’s a format for the hidden input element, create the element.
102
- if (SETTINGS.formatSubmit) {
103
- prepareElementHidden()
104
- }
105
-
106
-
107
- // Prepare the input element.
108
- prepareElement()
109
-
110
-
111
- // Insert the root as specified in the settings.
112
- if (SETTINGS.container) $(SETTINGS.container).append(P.$root)
113
- else $ELEMENT.after(P.$root)
114
-
115
-
116
- // Bind the default component and settings events.
117
- P.on({
118
- start: P.component.onStart,
119
- render: P.component.onRender,
120
- stop: P.component.onStop,
121
- open: P.component.onOpen,
122
- close: P.component.onClose,
123
- set: P.component.onSet
124
- }).on({
125
- start: SETTINGS.onStart,
126
- render: SETTINGS.onRender,
127
- stop: SETTINGS.onStop,
128
- open: SETTINGS.onOpen,
129
- close: SETTINGS.onClose,
130
- set: SETTINGS.onSet
131
- })
132
-
133
-
134
- // Once we’re all set, check the theme in use.
135
- IS_DEFAULT_THEME = isUsingDefaultTheme(P.$root.children()[0])
136
-
137
-
138
- // If the element has autofocus, open the picker.
139
- if (ELEMENT.autofocus) {
140
- P.open()
141
- }
142
-
143
-
144
- // Trigger queued the “start” and “render” events.
145
- return P.trigger('start').trigger('render')
146
- }, //start
147
-
148
-
149
- /**
150
- * Render a new picker
151
- */
152
- render: function (entireComponent) {
153
-
154
- // Insert a new component holder in the root or box.
155
- if (entireComponent) P.$root.html(createWrappedComponent())
156
- else P.$root.find('.' + CLASSES.box).html(P.component.nodes(STATE.open))
157
-
158
- // Trigger the queued “render” events.
159
- return P.trigger('render')
160
- }, //render
161
-
162
-
163
- /**
164
- * Destroy everything
165
- */
166
- stop: function () {
167
-
168
- // If it’s already stopped, do nothing.
169
- if (!STATE.start) return P
170
-
171
- // Then close the picker.
172
- P.close()
173
-
174
- // Remove the hidden field.
175
- if (P._hidden) {
176
- P._hidden.parentNode.removeChild(P._hidden)
177
- }
178
-
179
- // Remove the root.
180
- P.$root.remove()
181
-
182
- // Remove the input class, remove the stored data, and unbind
183
- // the events (after a tick for IE - see `P.close`).
184
- $ELEMENT.removeClass(CLASSES.input).removeData(NAME)
185
- setTimeout(function () {
186
- $ELEMENT.off('.' + STATE.id)
187
- }, 0)
188
-
189
- // Restore the element state
190
- ELEMENT.type = STATE.type
191
- ELEMENT.readOnly = false
192
-
193
- // Trigger the queued “stop” events.
194
- P.trigger('stop')
195
-
196
- // Reset the picker states.
197
- STATE.methods = {}
198
- STATE.start = false
199
-
200
- return P
201
- }, //stop
202
-
203
-
204
- /**
205
- * Open up the picker
206
- */
207
- open: function (dontGiveFocus) {
208
-
209
- // If it’s already open, do nothing.
210
- if (STATE.open) return P
211
-
212
- // Add the “active” class.
213
- $ELEMENT.addClass(CLASSES.active)
214
- aria(ELEMENT, 'expanded', true)
215
-
216
- // * A Firefox bug, when `html` has `overflow:hidden`, results in
217
- // killing transitions :(. So add the “opened” state on the next tick.
218
- // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
219
- setTimeout(function () {
220
-
221
- // Add the “opened” class to the picker root.
222
- P.$root.addClass(CLASSES.opened)
223
- aria(P.$root[0], 'hidden', false)
224
-
225
- }, 0)
226
-
227
- // If we have to give focus, bind the element and doc events.
228
- if (dontGiveFocus !== false) {
229
-
230
- // Set it as open.
231
- STATE.open = true
232
-
233
- // Prevent the page from scrolling.
234
- if (IS_DEFAULT_THEME) {
235
- $html.
236
- css('overflow', 'hidden').
237
- css('padding-right', '+=' + getScrollbarWidth())
238
- }
239
-
240
- // Pass focus to the root element’s jQuery object.
241
- // * Workaround for iOS8 to bring the picker’s root into view.
242
- P.$root.eq(0).focus()
243
-
244
- // Bind the document events.
245
- $document.on('click.' + STATE.id + ' focusin.' + STATE.id, function (event) {
246
-
247
- var target = event.target
248
-
249
- // If the target of the event is not the element, close the picker picker.
250
- // * Don’t worry about clicks or focusins on the root because those don’t bubble up.
251
- // Also, for Firefox, a click on an `option` element bubbles up directly
252
- // to the doc. So make sure the target wasn't the doc.
253
- // * In Firefox stopPropagation() doesn’t prevent right-click events from bubbling,
254
- // which causes the picker to unexpectedly close when right-clicking it. So make
255
- // sure the event wasn’t a right-click.
256
- if (target != ELEMENT && target != document && event.which != 3) {
257
-
258
- // If the target was the holder that covers the screen,
259
- // keep the element focused to maintain tabindex.
260
- P.close(target === P.$root.children()[0])
261
- }
262
-
263
- }).on('keydown.' + STATE.id, function (event) {
264
-
265
- var
266
- // Get the keycode.
267
- keycode = event.keyCode,
268
-
269
- // Translate that to a selection change.
270
- keycodeToMove = P.component.key[keycode],
271
-
272
- // Grab the target.
273
- target = event.target
274
-
275
-
276
- // On escape, close the picker and give focus.
277
- if (keycode == 27) {
278
- P.close(true)
279
- }
280
-
281
-
282
- // Check if there is a key movement or “enter” keypress on the element.
283
- else if (target == P.$root[0] && (keycodeToMove || keycode == 13)) {
284
-
285
- // Prevent the default action to stop page movement.
286
- event.preventDefault()
287
-
288
- // Trigger the key movement action.
289
- if (keycodeToMove) {
290
- PickerConstructor._.trigger(P.component.key.go, P, [PickerConstructor._.trigger(keycodeToMove)])
291
- }
292
-
293
- // On “enter”, if the highlighted item isn’t disabled, set the value and close.
294
- else if (!P.$root.find('.' + CLASSES.highlighted).hasClass(CLASSES.disabled)) {
295
- P.set('select', P.component.item.highlight).close()
296
- }
297
- }
298
-
299
-
300
- // If the target is within the root and “enter” is pressed,
301
- // prevent the default action and trigger a click on the target instead.
302
- else if ($.contains(P.$root[0], target) && keycode == 13) {
303
- event.preventDefault()
304
- target.click()
305
- }
306
- })
307
- }
308
-
309
- // Trigger the queued “open” events.
310
- return P.trigger('open')
311
- }, //open
312
-
313
-
314
- /**
315
- * Close the picker
316
- */
317
- close: function (giveFocus) {
318
-
319
- // If we need to give focus, do it before changing states.
320
- if (giveFocus) {
321
- // ....ah yes! It would’ve been incomplete without a crazy workaround for IE :|
322
- // The focus is triggered *after* the close has completed - causing it
323
- // to open again. So unbind and rebind the event at the next tick.
324
- P.$root.off('focus.toOpen').eq(0).focus()
325
- setTimeout(function () {
326
- P.$root.on('focus.toOpen', handleFocusToOpenEvent)
327
- }, 0)
328
- }
329
-
330
- // Remove the “active” class.
331
- $ELEMENT.removeClass(CLASSES.active)
332
- aria(ELEMENT, 'expanded', false)
333
-
334
- // * A Firefox bug, when `html` has `overflow:hidden`, results in
335
- // killing transitions :(. So remove the “opened” state on the next tick.
336
- // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=625289
337
- setTimeout(function () {
338
-
339
- // Remove the “opened” and “focused” class from the picker root.
340
- P.$root.removeClass(CLASSES.opened + ' ' + CLASSES.focused)
341
- aria(P.$root[0], 'hidden', true)
342
-
343
- }, 0)
344
-
345
- // If it’s already closed, do nothing more.
346
- if (!STATE.open) return P
347
-
348
- // Set it as closed.
349
- STATE.open = false
350
-
351
- // Allow the page to scroll.
352
- if (IS_DEFAULT_THEME) {
353
- $html.
354
- css('overflow', '').
355
- css('padding-right', '-=' + getScrollbarWidth())
356
- }
357
-
358
- // Unbind the document events.
359
- $document.off('.' + STATE.id)
360
-
361
- // Trigger the queued “close” events.
362
- return P.trigger('close')
363
- }, //close
364
-
365
-
366
- /**
367
- * Clear the values
368
- */
369
- clear: function (options) {
370
- return P.set('clear', null, options)
371
- }, //clear
372
-
373
-
374
- /**
375
- * Set something
376
- */
377
- set: function (thing, value, options) {
378
-
379
- var thingItem, thingValue,
380
- thingIsObject = $.isPlainObject(thing),
381
- thingObject = thingIsObject ? thing : {}
382
-
383
- // Make sure we have usable options.
384
- options = thingIsObject && $.isPlainObject(value) ? value : options || {}
385
-
386
- if (thing) {
387
-
388
- // If the thing isn’t an object, make it one.
389
- if (!thingIsObject) {
390
- thingObject[thing] = value
391
- }
392
-
393
- // Go through the things of items to set.
394
- for (thingItem in thingObject) {
395
-
396
- // Grab the value of the thing.
397
- thingValue = thingObject[thingItem]
398
-
399
- // First, if the item exists and there’s a value, set it.
400
- if (thingItem in P.component.item) {
401
- if (thingValue === undefined) thingValue = null
402
- P.component.set(thingItem, thingValue, options)
403
- }
404
-
405
- // Then, check to update the element value and broadcast a change.
406
- if (thingItem == 'select' || thingItem == 'clear') {
407
- $ELEMENT.
408
- val(thingItem == 'clear' ? '' : P.get(thingItem, SETTINGS.format)).
409
- trigger('change')
410
- }
411
- }
412
-
413
- // Render a new picker.
414
- P.render()
415
- }
416
-
417
- // When the method isn’t muted, trigger queued “set” events and pass the `thingObject`.
418
- return options.muted ? P : P.trigger('set', thingObject)
419
- }, //set
420
-
421
-
422
- /**
423
- * Get something
424
- */
425
- get: function (thing, format) {
426
-
427
- // Make sure there’s something to get.
428
- thing = thing || 'value'
429
-
430
- // If a picker state exists, return that.
431
- if (STATE[thing] != null) {
432
- return STATE[thing]
433
- }
434
-
435
- // Return the submission value, if that.
436
- if (thing == 'valueSubmit') {
437
- if (P._hidden) {
438
- return P._hidden.value
439
- }
440
- thing = 'value'
441
- }
442
-
443
- // Return the value, if that.
444
- if (thing == 'value') {
445
- return ELEMENT.value
446
- }
447
-
448
- // Check if a component item exists, return that.
449
- if (thing in P.component.item) {
450
- if (typeof format == 'string') {
451
- var thingValue = P.component.get(thing)
452
- return thingValue ?
453
- PickerConstructor._.trigger(
454
- P.component.formats.toString,
455
- P.component, [format, thingValue]
456
- ) : ''
457
- }
458
- return P.component.get(thing)
459
- }
460
- }, //get
461
-
462
-
463
-
464
- /**
465
- * Bind events on the things.
466
- */
467
- on: function (thing, method, internal) {
468
-
469
- var thingName, thingMethod,
470
- thingIsObject = $.isPlainObject(thing),
471
- thingObject = thingIsObject ? thing : {}
472
-
473
- if (thing) {
474
-
475
- // If the thing isn’t an object, make it one.
476
- if (!thingIsObject) {
477
- thingObject[thing] = method
478
- }
479
-
480
- // Go through the things to bind to.
481
- for (thingName in thingObject) {
482
-
483
- // Grab the method of the thing.
484
- thingMethod = thingObject[thingName]
485
-
486
- // If it was an internal binding, prefix it.
487
- if (internal) {
488
- thingName = '_' + thingName
489
- }
490
-
491
- // Make sure the thing methods collection exists.
492
- STATE.methods[thingName] = STATE.methods[thingName] || []
493
-
494
- // Add the method to the relative method collection.
495
- STATE.methods[thingName].push(thingMethod)
496
- }
497
- }
498
-
499
- return P
500
- }, //on
501
-
502
-
503
-
504
- /**
505
- * Unbind events on the things.
506
- */
507
- off: function () {
508
- var i, thingName,
509
- names = arguments;
510
- for (i = 0, namesCount = names.length; i < namesCount; i += 1) {
511
- thingName = names[i]
512
- if (thingName in STATE.methods) {
513
- delete STATE.methods[thingName]
514
- }
515
- }
516
- return P
517
- },
518
-
519
-
520
- /**
521
- * Fire off method events.
522
- */
523
- trigger: function (name, data) {
524
- var _trigger = function (name) {
525
- var methodList = STATE.methods[name]
526
- if (methodList) {
527
- methodList.map(function (method) {
528
- PickerConstructor._.trigger(method, P, [data])
529
- })
530
- }
531
- }
532
- _trigger('_' + name)
533
- _trigger(name)
534
- return P
535
- } //trigger
536
- } //PickerInstance.prototype
537
-
538
-
539
- /**
540
- * Wrap the picker holder components together.
541
- */
542
- function createWrappedComponent() {
543
-
544
- // Create a picker wrapper holder
545
- return PickerConstructor._.node('div',
546
-
547
- // Create a picker wrapper node
548
- PickerConstructor._.node('div',
549
-
550
- // Create a picker frame
551
- PickerConstructor._.node('div',
552
-
553
- // Create a picker box node
554
- PickerConstructor._.node('div',
555
-
556
- // Create the components nodes.
557
- P.component.nodes(STATE.open),
558
-
559
- // The picker box class
560
- CLASSES.box
561
- ),
562
-
563
- // Picker wrap class
564
- CLASSES.wrap
565
- ),
566
-
567
- // Picker frame class
568
- CLASSES.frame
569
- ),
570
-
571
- // Picker holder class
572
- CLASSES.holder
573
- ) //endreturn
574
- } //createWrappedComponent
575
-
576
-
577
-
578
- /**
579
- * Prepare the input element with all bindings.
580
- */
581
- function prepareElement() {
582
-
583
- $ELEMENT.
584
-
585
- // Store the picker data by component name.
586
- data(NAME, P).
587
-
588
- // Add the “input” class name.
589
- addClass(CLASSES.input).
590
-
591
- // Remove the tabindex.
592
- attr('tabindex', -1).
593
-
594
- // If there’s a `data-value`, update the value of the element.
595
- val($ELEMENT.data('value') ?
596
- P.get('select', SETTINGS.format) :
597
- ELEMENT.value
598
- )
599
-
600
-
601
- // Only bind keydown events if the element isn’t editable.
602
- if (!SETTINGS.editable) {
603
-
604
- $ELEMENT.
605
-
606
- // On focus/click, focus onto the root to open it up.
607
- on('focus.' + STATE.id + ' click.' + STATE.id, function (event) {
608
- event.preventDefault()
609
- P.$root.eq(0).focus()
610
- }).
611
-
612
- // Handle keyboard event based on the picker being opened or not.
613
- on('keydown.' + STATE.id, handleKeydownEvent)
614
- }
615
-
616
-
617
- // Update the aria attributes.
618
- aria(ELEMENT, {
619
- haspopup: true,
620
- expanded: false,
621
- readonly: false,
622
- owns: ELEMENT.id + '_root'
623
- })
624
- }
625
-
626
-
627
- /**
628
- * Prepare the root picker element with all bindings.
629
- */
630
- function prepareElementRoot() {
631
-
632
- P.$root.
633
-
634
- on({
635
-
636
- // For iOS8.
637
- keydown: handleKeydownEvent,
638
-
639
- // When something within the root is focused, stop from bubbling
640
- // to the doc and remove the “focused” state from the root.
641
- focusin: function (event) {
642
- P.$root.removeClass(CLASSES.focused)
643
- event.stopPropagation()
644
- },
645
-
646
- // When something within the root holder is clicked, stop it
647
- // from bubbling to the doc.
648
- 'mousedown click': function (event) {
649
-
650
- var target = event.target
651
-
652
- // Make sure the target isn’t the root holder so it can bubble up.
653
- if (target != P.$root.children()[0]) {
654
-
655
- event.stopPropagation()
656
-
657
- // * For mousedown events, cancel the default action in order to
658
- // prevent cases where focus is shifted onto external elements
659
- // when using things like jQuery mobile or MagnificPopup (ref: #249 & #120).
660
- // Also, for Firefox, don’t prevent action on the `option` element.
661
- if (event.type == 'mousedown' && !$(target).is('input, select, textarea, button, option')) {
662
-
663
- event.preventDefault()
664
-
665
- // Re-focus onto the root so that users can click away
666
- // from elements focused within the picker.
667
- P.$root.eq(0).focus()
668
- }
669
- }
670
- }
671
- }).
672
-
673
- // Add/remove the “target” class on focus and blur.
674
- on({
675
- focus: function () {
676
- $ELEMENT.addClass(CLASSES.target)
677
- },
678
- blur: function () {
679
- $ELEMENT.removeClass(CLASSES.target)
680
- }
681
- }).
682
-
683
- // Open the picker and adjust the root “focused” state
684
- on('focus.toOpen', handleFocusToOpenEvent).
685
-
686
- // If there’s a click on an actionable element, carry out the actions.
687
- on('click', '[data-pick], [data-nav], [data-clear], [data-close]', function () {
688
-
689
- var $target = $(this),
690
- targetData = $target.data(),
691
- targetDisabled = $target.hasClass(CLASSES.navDisabled) || $target.hasClass(CLASSES.disabled),
692
-
693
- // * For IE, non-focusable elements can be active elements as well
694
- // (http://stackoverflow.com/a/2684561).
695
- activeElement = getActiveElement()
696
- activeElement = activeElement && (activeElement.type || activeElement.href)
697
-
698
- // If it’s disabled or nothing inside is actively focused, re-focus the element.
699
- if (targetDisabled || activeElement && !$.contains(P.$root[0], activeElement)) {
700
- P.$root.eq(0).focus()
701
- }
702
-
703
- // If something is superficially changed, update the `highlight` based on the `nav`.
704
- if (!targetDisabled && targetData.nav) {
705
- P.set('highlight', P.component.item.highlight, {
706
- nav: targetData.nav
707
- })
708
- }
709
-
710
- // If something is picked, set `select` then close with focus.
711
- else if (!targetDisabled && 'pick' in targetData) {
712
- P.set('select', targetData.pick)
713
- }
714
-
715
- // If a “clear” button is pressed, empty the values and close with focus.
716
- else if (targetData.clear) {
717
- P.clear().close(true)
718
- } else if (targetData.close) {
719
- P.close(true)
720
- }
721
-
722
- }) //P.$root
723
-
724
- aria(P.$root[0], 'hidden', true)
725
- }
726
-
727
-
728
- /**
729
- * Prepare the hidden input element along with all bindings.
730
- */
731
- function prepareElementHidden() {
732
-
733
- var name
734
-
735
- if (SETTINGS.hiddenName === true) {
736
- name = ELEMENT.name
737
- ELEMENT.name = ''
738
- } else {
739
- name = [
740
- typeof SETTINGS.hiddenPrefix == 'string' ? SETTINGS.hiddenPrefix : '',
741
- typeof SETTINGS.hiddenSuffix == 'string' ? SETTINGS.hiddenSuffix : '_submit'
742
- ]
743
- name = name[0] + ELEMENT.name + name[1]
744
- }
745
-
746
- P._hidden = $(
747
- '<input ' +
748
- 'type=hidden ' +
749
-
750
- // Create the name using the original input’s with a prefix and suffix.
751
- 'name="' + name + '"' +
752
-
753
- // If the element has a value, set the hidden value as well.
754
- (
755
- $ELEMENT.data('value') || ELEMENT.value ?
756
- ' value="' + P.get('select', SETTINGS.formatSubmit) + '"' :
757
- ''
758
- ) +
759
- '>'
760
- )[0]
761
-
762
- $ELEMENT.
763
-
764
- // If the value changes, update the hidden input with the correct format.
765
- on('change.' + STATE.id, function () {
766
- P._hidden.value = ELEMENT.value ?
767
- P.get('select', SETTINGS.formatSubmit) :
768
- ''
769
- })
770
-
771
-
772
- // Insert the hidden input as specified in the settings.
773
- if (SETTINGS.container) $(SETTINGS.container).append(P._hidden)
774
- else $ELEMENT.after(P._hidden)
775
- }
776
-
777
-
778
- // For iOS8.
779
- function handleKeydownEvent(event) {
780
-
781
- var keycode = event.keyCode,
782
-
783
- // Check if one of the delete keys was pressed.
784
- isKeycodeDelete = /^(8|46)$/.test(keycode)
785
-
786
- // For some reason IE clears the input value on “escape”.
787
- if (keycode == 27) {
788
- P.close()
789
- return false
790
- }
791
-
792
- // Check if `space` or `delete` was pressed or the picker is closed with a key movement.
793
- if (keycode == 32 || isKeycodeDelete || !STATE.open && P.component.key[keycode]) {
794
-
795
- // Prevent it from moving the page and bubbling to doc.
796
- event.preventDefault()
797
- event.stopPropagation()
798
-
799
- // If `delete` was pressed, clear the values and close the picker.
800
- // Otherwise open the picker.
801
- if (isKeycodeDelete) {
802
- P.clear().close()
803
- } else {
804
- P.open()
805
- }
806
- }
807
- }
808
-
809
-
810
- // Separated for IE
811
- function handleFocusToOpenEvent(event) {
812
-
813
- // Stop the event from propagating to the doc.
814
- event.stopPropagation()
815
-
816
- // If it’s a focus event, add the “focused” class to the root.
817
- if (event.type == 'focus') {
818
- P.$root.addClass(CLASSES.focused)
819
- }
820
-
821
- // And then finally open the picker.
822
- P.open()
823
- }
824
-
825
-
826
- // Return a new picker instance.
827
- return new PickerInstance()
828
- } //PickerConstructor
829
-
830
-
831
-
832
- /**
833
- * The default classes and prefix to use for the HTML classes.
834
- */
835
- PickerConstructor.klasses = function (prefix) {
836
- prefix = prefix || 'picker'
837
- return {
838
-
839
- picker: prefix,
840
- opened: prefix + '--opened',
841
- focused: prefix + '--focused',
842
-
843
- input: prefix + '__input',
844
- active: prefix + '__input--active',
845
- target: prefix + '__input--target',
846
-
847
- holder: prefix + '__holder',
848
-
849
- frame: prefix + '__frame',
850
- wrap: prefix + '__wrap',
851
-
852
- box: prefix + '__box'
853
- }
854
- } //PickerConstructor.klasses
855
-
856
-
857
-
858
- /**
859
- * Check if the default theme is being used.
860
- */
861
- function isUsingDefaultTheme(element) {
862
-
863
- var theme,
864
- prop = 'position'
865
-
866
- // For IE.
867
- if (element.currentStyle) {
868
- theme = element.currentStyle[prop]
869
- }
870
-
871
- // For normal browsers.
872
- else if (window.getComputedStyle) {
873
- theme = getComputedStyle(element)[prop]
874
- }
875
-
876
- return theme == 'fixed'
877
- }
878
-
879
-
880
-
881
- /**
882
- * Get the width of the browser’s scrollbar.
883
- * Taken from: https://github.com/VodkaBears/Remodal/blob/master/src/jquery.remodal.js
884
- */
885
- function getScrollbarWidth() {
886
-
887
- if ($html.height() <= $window.height()) {
888
- return 0
889
- }
890
-
891
- var $outer = $('<div style="visibility:hidden;width:100px" />').
892
- appendTo('body')
893
-
894
- // Get the width without scrollbars.
895
- var widthWithoutScroll = $outer[0].offsetWidth
896
-
897
- // Force adding scrollbars.
898
- $outer.css('overflow', 'scroll')
899
-
900
- // Add the inner div.
901
- var $inner = $('<div style="width:100%" />').appendTo($outer)
902
-
903
- // Get the width with scrollbars.
904
- var widthWithScroll = $inner[0].offsetWidth
905
-
906
- // Remove the divs.
907
- $outer.remove()
908
-
909
- // Return the difference between the widths.
910
- return widthWithoutScroll - widthWithScroll
911
- }
912
-
913
-
914
-
915
- /**
916
- * PickerConstructor helper methods.
917
- */
918
- PickerConstructor._ = {
919
-
920
- /**
921
- * Create a group of nodes. Expects:
922
- * `
923
- {
924
- min: {Integer},
925
- max: {Integer},
926
- i: {Integer},
927
- node: {String},
928
- item: {Function}
929
- }
930
- * `
931
- */
932
- group: function (groupObject) {
933
-
934
- var
935
- // Scope for the looped object
936
- loopObjectScope,
937
-
938
- // Create the nodes list
939
- nodesList = '',
940
-
941
- // The counter starts from the `min`
942
- counter = PickerConstructor._.trigger(groupObject.min, groupObject)
943
-
944
-
945
- // Loop from the `min` to `max`, incrementing by `i`
946
- for (; counter <= PickerConstructor._.trigger(groupObject.max, groupObject, [counter]); counter += groupObject.i) {
947
-
948
- // Trigger the `item` function within scope of the object
949
- loopObjectScope = PickerConstructor._.trigger(groupObject.item, groupObject, [counter])
950
-
951
- // Splice the subgroup and create nodes out of the sub nodes
952
- nodesList += PickerConstructor._.node(
953
- groupObject.node,
954
- loopObjectScope[0], // the node
955
- loopObjectScope[1], // the classes
956
- loopObjectScope[2] // the attributes
957
- )
958
- }
959
-
960
- // Return the list of nodes
961
- return nodesList
962
- }, //group
963
-
964
-
965
- /**
966
- * Create a dom node string
967
- */
968
- node: function (wrapper, item, klass, attribute) {
969
-
970
- // If the item is false-y, just return an empty string
971
- if (!item) return ''
972
-
973
- // If the item is an array, do a join
974
- item = $.isArray(item) ? item.join('') : item
975
-
976
- // Check for the class
977
- klass = klass ? ' class="' + klass + '"' : ''
978
-
979
- // Check for any attributes
980
- attribute = attribute ? ' ' + attribute : ''
981
-
982
- // Return the wrapped item
983
- return '<' + wrapper + klass + attribute + '>' + item + '</' + wrapper + '>'
984
- }, //node
985
-
986
-
987
- /**
988
- * Lead numbers below 10 with a zero.
989
- */
990
- lead: function (number) {
991
- return (number < 10 ? '0' : '') + number
992
- },
993
-
994
-
995
- /**
996
- * Trigger a function otherwise return the value.
997
- */
998
- trigger: function (callback, scope, args) {
999
- return typeof callback == 'function' ? callback.apply(scope, args || []) : callback
1000
- },
1001
-
1002
-
1003
- /**
1004
- * If the second character is a digit, length is 2 otherwise 1.
1005
- */
1006
- digits: function (string) {
1007
- return (/\d/).test(string[1]) ? 2 : 1
1008
- },
1009
-
1010
-
1011
- /**
1012
- * Tell if something is a date object.
1013
- */
1014
- isDate: function (value) {
1015
- return {}.toString.call(value).indexOf('Date') > -1 && this.isInteger(value.getDate())
1016
- },
1017
-
1018
-
1019
- /**
1020
- * Tell if something is an integer.
1021
- */
1022
- isInteger: function (value) {
1023
- return {}.toString.call(value).indexOf('Number') > -1 && value % 1 === 0
1024
- },
1025
-
1026
-
1027
- /**
1028
- * Create ARIA attribute strings.
1029
- */
1030
- ariaAttr: ariaAttr
1031
- } //PickerConstructor._
1032
-
1033
-
1034
-
1035
- /**
1036
- * Extend the picker with a component and defaults.
1037
- */
1038
- PickerConstructor.extend = function (name, Component) {
1039
-
1040
- // Extend jQuery.
1041
- $.fn[name] = function (options, action) {
1042
-
1043
- // Grab the component data.
1044
- var componentData = this.data(name)
1045
-
1046
- // If the picker is requested, return the data object.
1047
- if (options == 'picker') {
1048
- return componentData
1049
- }
1050
-
1051
- // If the component data exists and `options` is a string, carry out the action.
1052
- if (componentData && typeof options == 'string') {
1053
- return PickerConstructor._.trigger(componentData[options], componentData, [action])
1054
- }
1055
-
1056
- // Otherwise go through each matched element and if the component
1057
- // doesn’t exist, create a new picker using `this` element
1058
- // and merging the defaults and options with a deep copy.
1059
- return this.each(function () {
1060
- var $this = $(this)
1061
- if (!$this.data(name)) {
1062
- new PickerConstructor(this, name, Component, options)
1063
- }
1064
- })
1065
- }
1066
-
1067
- // Set the defaults.
1068
- $.fn[name].defaults = Component.defaults
1069
- } //PickerConstructor.extend
1070
-
1071
-
1072
-
1073
- function aria(element, attribute, value) {
1074
- if ($.isPlainObject(attribute)) {
1075
- for (var key in attribute) {
1076
- ariaSet(element, key, attribute[key])
1077
- }
1078
- } else {
1079
- ariaSet(element, attribute, value)
1080
- }
1081
- }
1082
-
1083
- function ariaSet(element, attribute, value) {
1084
- element.setAttribute(
1085
- (attribute == 'role' ? '' : 'aria-') + attribute,
1086
- value
1087
- )
1088
- }
1089
-
1090
- function ariaAttr(attribute, data) {
1091
- if (!$.isPlainObject(attribute)) {
1092
- attribute = {
1093
- attribute: data
1094
- }
1095
- }
1096
- data = ''
1097
- for (var key in attribute) {
1098
- var attr = (key == 'role' ? '' : 'aria-') + key,
1099
- attrVal = attribute[key]
1100
- data += attrVal == null ? '' : attr + '="' + attribute[key] + '"'
1101
- }
1102
- return data
1103
- }
1104
-
1105
- // IE8 bug throws an error for activeElements within iframes.
1106
- function getActiveElement() {
1107
- try {
1108
- return document.activeElement
1109
- } catch (err) {}
1110
- }
1111
-
1112
-
1113
-
1114
- // Expose the picker constructor.
1115
- return PickerConstructor
1116
-
1117
-
1118
- }));
1119
-
1120
-
1121
- ;
1122
- /*!
1123
- * Date picker for pickadate.js v3.5.0
1124
- * http://amsul.github.io/pickadate.js/date.htm
1125
- */
1126
-
1127
- (function (factory) {
1128
-
1129
- // AMD.
1130
- if (typeof define == 'function' && define.amd)
1131
- define(['picker', 'jquery'], factory)
1132
-
1133
- // Node.js/browserify.
1134
- else if (typeof exports == 'object')
1135
- module.exports = factory(require('./picker.js'), require('jquery'))
1136
-
1137
- // Browser globals.
1138
- else factory(Picker, jQuery)
1139
-
1140
- }(function (Picker, $) {
1141
-
1142
-
1143
- /**
1144
- * Globals and constants
1145
- */
1146
- var DAYS_IN_WEEK = 7,
1147
- WEEKS_IN_CALENDAR = 6,
1148
- _ = Picker._
1149
-
1150
-
1151
-
1152
- /**
1153
- * The date picker constructor
1154
- */
1155
- function DatePicker(picker, settings) {
1156
-
1157
- var calendar = this,
1158
- element = picker.$node[0],
1159
- elementValue = element.value,
1160
- elementDataValue = picker.$node.data('value'),
1161
- valueString = elementDataValue || elementValue,
1162
- formatString = elementDataValue ? settings.formatSubmit : settings.format,
1163
- isRTL = function () {
1164
-
1165
- return element.currentStyle ?
1166
-
1167
- // For IE.
1168
- element.currentStyle.direction == 'rtl' :
1169
-
1170
- // For normal browsers.
1171
- getComputedStyle(picker.$root[0]).direction == 'rtl'
1172
- }
1173
-
1174
- calendar.settings = settings
1175
- calendar.$node = picker.$node
1176
-
1177
- // The queue of methods that will be used to build item objects.
1178
- calendar.queue = {
1179
- min: 'measure create',
1180
- max: 'measure create',
1181
- now: 'now create',
1182
- select: 'parse create validate',
1183
- highlight: 'parse navigate create validate',
1184
- view: 'parse create validate viewset',
1185
- disable: 'deactivate',
1186
- enable: 'activate'
1187
- }
1188
-
1189
- // The component's item object.
1190
- calendar.item = {}
1191
-
1192
- calendar.item.clear = null
1193
- calendar.item.disable = (settings.disable || []).slice(0)
1194
- calendar.item.enable = -(function (collectionDisabled) {
1195
- return collectionDisabled[0] === true ? collectionDisabled.shift() : -1
1196
- })(calendar.item.disable)
1197
-
1198
- calendar.
1199
- set('min', settings.min).
1200
- set('max', settings.max).
1201
- set('now')
1202
-
1203
- // When there’s a value, set the `select`, which in turn
1204
- // also sets the `highlight` and `view`.
1205
- if (valueString) {
1206
- calendar.set('select', valueString, {
1207
- format: formatString
1208
- })
1209
- }
1210
-
1211
- // If there’s no value, default to highlighting “today”.
1212
- else {
1213
- calendar.
1214
- set('select', null).
1215
- set('highlight', calendar.item.now)
1216
- }
1217
-
1218
-
1219
- // The keycode to movement mapping.
1220
- calendar.key = {
1221
- 40: 7, // Down
1222
- 38: -7, // Up
1223
- 39: function () {
1224
- return isRTL() ? -1 : 1
1225
- }, // Right
1226
- 37: function () {
1227
- return isRTL() ? 1 : -1
1228
- }, // Left
1229
- go: function (timeChange) {
1230
- var highlightedObject = calendar.item.highlight,
1231
- targetDate = new Date(highlightedObject.year, highlightedObject.month, highlightedObject.date + timeChange)
1232
- calendar.set(
1233
- 'highlight',
1234
- targetDate, {
1235
- interval: timeChange
1236
- }
1237
- )
1238
- this.render()
1239
- }
1240
- }
1241
-
1242
-
1243
- // Bind some picker events.
1244
- picker.
1245
- on('render', function () {
1246
- picker.$root.find('.' + settings.klass.selectMonth).on('change', function () {
1247
- var value = this.value
1248
- if (value) {
1249
- picker.set('highlight', [picker.get('view').year, value, picker.get('highlight').date])
1250
- picker.$root.find('.' + settings.klass.selectMonth).trigger('focus')
1251
- }
1252
- })
1253
- picker.$root.find('.' + settings.klass.selectYear).on('change', function () {
1254
- var value = this.value
1255
- if (value) {
1256
- picker.set('highlight', [value, picker.get('view').month, picker.get('highlight').date])
1257
- picker.$root.find('.' + settings.klass.selectYear).trigger('focus')
1258
- }
1259
- })
1260
- }, 1).
1261
- on('open', function () {
1262
- var includeToday = ''
1263
- if (calendar.disabled(calendar.get('now'))) {
1264
- includeToday = ':not(.' + settings.klass.buttonToday + ')'
1265
- }
1266
- picker.$root.find('button' + includeToday + ', select').attr('disabled', false)
1267
- }, 1).
1268
- on('close', function () {
1269
- picker.$root.find('button, select').attr('disabled', true)
1270
- }, 1)
1271
-
1272
- } //DatePicker
1273
-
1274
-
1275
- /**
1276
- * Set a datepicker item object.
1277
- */
1278
- DatePicker.prototype.set = function (type, value, options) {
1279
-
1280
- var calendar = this,
1281
- calendarItem = calendar.item
1282
-
1283
- // If the value is `null` just set it immediately.
1284
- if (value === null) {
1285
- if (type == 'clear') type = 'select'
1286
- calendarItem[type] = value
1287
- return calendar
1288
- }
1289
-
1290
- // Otherwise go through the queue of methods, and invoke the functions.
1291
- // Update this as the time unit, and set the final value as this item.
1292
- // * In the case of `enable`, keep the queue but set `disable` instead.
1293
- // And in the case of `flip`, keep the queue but set `enable` instead.
1294
- calendarItem[(type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type)] = calendar.queue[type].split(' ').map(function (method) {
1295
- value = calendar[method](type, value, options)
1296
- return value
1297
- }).pop()
1298
-
1299
- // Check if we need to cascade through more updates.
1300
- if (type == 'select') {
1301
- calendar.set('highlight', calendarItem.select, options)
1302
- } else if (type == 'highlight') {
1303
- calendar.set('view', calendarItem.highlight, options)
1304
- } else if (type.match(/^(flip|min|max|disable|enable)$/)) {
1305
- if (calendarItem.select && calendar.disabled(calendarItem.select)) {
1306
- calendar.set('select', calendarItem.select, options)
1307
- }
1308
- if (calendarItem.highlight && calendar.disabled(calendarItem.highlight)) {
1309
- calendar.set('highlight', calendarItem.highlight, options)
1310
- }
1311
- }
1312
-
1313
- return calendar
1314
- } //DatePicker.prototype.set
1315
-
1316
-
1317
- /**
1318
- * Get a datepicker item object.
1319
- */
1320
- DatePicker.prototype.get = function (type) {
1321
- return this.item[type]
1322
- } //DatePicker.prototype.get
1323
-
1324
-
1325
- /**
1326
- * Create a picker date object.
1327
- */
1328
- DatePicker.prototype.create = function (type, value, options) {
1329
-
1330
- var isInfiniteValue,
1331
- calendar = this
1332
-
1333
- // If there’s no value, use the type as the value.
1334
- value = value === undefined ? type : value
1335
-
1336
-
1337
- // If it’s infinity, update the value.
1338
- if (value == -Infinity || value == Infinity) {
1339
- isInfiniteValue = value
1340
- }
1341
-
1342
- // If it’s an object, use the native date object.
1343
- else if ($.isPlainObject(value) && _.isInteger(value.pick)) {
1344
- value = value.obj
1345
- }
1346
-
1347
- // If it’s an array, convert it into a date and make sure
1348
- // that it’s a valid date – otherwise default to today.
1349
- else if ($.isArray(value)) {
1350
- value = new Date(value[0], value[1], value[2])
1351
- value = _.isDate(value) ? value : calendar.create().obj
1352
- }
1353
-
1354
- // If it’s a number or date object, make a normalized date.
1355
- else if (_.isInteger(value) || _.isDate(value)) {
1356
- value = calendar.normalize(new Date(value), options)
1357
- }
1358
-
1359
- // If it’s a literal true or any other case, set it to now.
1360
- else /*if ( value === true )*/ {
1361
- value = calendar.now(type, value, options)
1362
- }
1363
-
1364
- // Return the compiled object.
1365
- return {
1366
- year: isInfiniteValue || value.getFullYear(),
1367
- month: isInfiniteValue || value.getMonth(),
1368
- date: isInfiniteValue || value.getDate(),
1369
- day: isInfiniteValue || value.getDay(),
1370
- obj: isInfiniteValue || value,
1371
- pick: isInfiniteValue || value.getTime()
1372
- }
1373
- } //DatePicker.prototype.create
1374
-
1375
-
1376
- /**
1377
- * Create a range limit object using an array, date object,
1378
- * literal “true”, or integer relative to another time.
1379
- */
1380
- DatePicker.prototype.createRange = function (from, to) {
1381
-
1382
- var calendar = this,
1383
- createDate = function (date) {
1384
- if (date === true || $.isArray(date) || _.isDate(date)) {
1385
- return calendar.create(date)
1386
- }
1387
- return date
1388
- }
1389
-
1390
- // Create objects if possible.
1391
- if (!_.isInteger(from)) {
1392
- from = createDate(from)
1393
- }
1394
- if (!_.isInteger(to)) {
1395
- to = createDate(to)
1396
- }
1397
-
1398
- // Create relative dates.
1399
- if (_.isInteger(from) && $.isPlainObject(to)) {
1400
- from = [to.year, to.month, to.date + from];
1401
- } else if (_.isInteger(to) && $.isPlainObject(from)) {
1402
- to = [from.year, from.month, from.date + to];
1403
- }
1404
-
1405
- return {
1406
- from: createDate(from),
1407
- to: createDate(to)
1408
- }
1409
- } //DatePicker.prototype.createRange
1410
-
1411
-
1412
- /**
1413
- * Check if a date unit falls within a date range object.
1414
- */
1415
- DatePicker.prototype.withinRange = function (range, dateUnit) {
1416
- range = this.createRange(range.from, range.to)
1417
- return dateUnit.pick >= range.from.pick && dateUnit.pick <= range.to.pick
1418
- }
1419
-
1420
-
1421
- /**
1422
- * Check if two date range objects overlap.
1423
- */
1424
- DatePicker.prototype.overlapRanges = function (one, two) {
1425
-
1426
- var calendar = this
1427
-
1428
- // Convert the ranges into comparable dates.
1429
- one = calendar.createRange(one.from, one.to)
1430
- two = calendar.createRange(two.from, two.to)
1431
-
1432
- return calendar.withinRange(one, two.from) || calendar.withinRange(one, two.to) ||
1433
- calendar.withinRange(two, one.from) || calendar.withinRange(two, one.to)
1434
- }
1435
-
1436
-
1437
- /**
1438
- * Get the date today.
1439
- */
1440
- DatePicker.prototype.now = function (type, value, options) {
1441
- value = new Date()
1442
- if (options && options.rel) {
1443
- value.setDate(value.getDate() + options.rel)
1444
- }
1445
- return this.normalize(value, options)
1446
- }
1447
-
1448
-
1449
- /**
1450
- * Navigate to next/prev month.
1451
- */
1452
- DatePicker.prototype.navigate = function (type, value, options) {
1453
-
1454
- var targetDateObject,
1455
- targetYear,
1456
- targetMonth,
1457
- targetDate,
1458
- isTargetArray = $.isArray(value),
1459
- isTargetObject = $.isPlainObject(value),
1460
- viewsetObject = this.item.view
1461
- /*,
1462
- safety = 100*/
1463
-
1464
-
1465
- if (isTargetArray || isTargetObject) {
1466
-
1467
- if (isTargetObject) {
1468
- targetYear = value.year
1469
- targetMonth = value.month
1470
- targetDate = value.date
1471
- } else {
1472
- targetYear = +value[0]
1473
- targetMonth = +value[1]
1474
- targetDate = +value[2]
1475
- }
1476
-
1477
- // If we’re navigating months but the view is in a different
1478
- // month, navigate to the view’s year and month.
1479
- if (options && options.nav && viewsetObject && viewsetObject.month !== targetMonth) {
1480
- targetYear = viewsetObject.year
1481
- targetMonth = viewsetObject.month
1482
- }
1483
-
1484
- // Figure out the expected target year and month.
1485
- targetDateObject = new Date(targetYear, targetMonth + (options && options.nav ? options.nav : 0), 1)
1486
- targetYear = targetDateObject.getFullYear()
1487
- targetMonth = targetDateObject.getMonth()
1488
-
1489
- // If the month we’re going to doesn’t have enough days,
1490
- // keep decreasing the date until we reach the month’s last date.
1491
- while ( /*safety &&*/ new Date(targetYear, targetMonth, targetDate).getMonth() !== targetMonth) {
1492
- targetDate -= 1
1493
- /*safety -= 1
1494
- if ( !safety ) {
1495
- throw 'Fell into an infinite loop while navigating to ' + new Date( targetYear, targetMonth, targetDate ) + '.'
1496
- }*/
1497
- }
1498
-
1499
- value = [targetYear, targetMonth, targetDate]
1500
- }
1501
-
1502
- return value
1503
- } //DatePicker.prototype.navigate
1504
-
1505
-
1506
- /**
1507
- * Normalize a date by setting the hours to midnight.
1508
- */
1509
- DatePicker.prototype.normalize = function (value /*, options*/ ) {
1510
- value.setHours(0, 0, 0, 0)
1511
- return value
1512
- }
1513
-
1514
-
1515
- /**
1516
- * Measure the range of dates.
1517
- */
1518
- DatePicker.prototype.measure = function (type, value /*, options*/ ) {
1519
-
1520
- var calendar = this
1521
-
1522
- // If it’s anything false-y, remove the limits.
1523
- if (!value) {
1524
- value = type == 'min' ? -Infinity : Infinity
1525
- }
1526
-
1527
- // If it’s a string, parse it.
1528
- else if (typeof value == 'string') {
1529
- value = calendar.parse(type, value)
1530
- }
1531
-
1532
- // If it's an integer, get a date relative to today.
1533
- else if (_.isInteger(value)) {
1534
- value = calendar.now(type, value, {
1535
- rel: value
1536
- })
1537
- }
1538
-
1539
- return value
1540
- } ///DatePicker.prototype.measure
1541
-
1542
-
1543
- /**
1544
- * Create a viewset object based on navigation.
1545
- */
1546
- DatePicker.prototype.viewset = function (type, dateObject /*, options*/ ) {
1547
- return this.create([dateObject.year, dateObject.month, 1])
1548
- }
1549
-
1550
-
1551
- /**
1552
- * Validate a date as enabled and shift if needed.
1553
- */
1554
- DatePicker.prototype.validate = function (type, dateObject, options) {
1555
-
1556
- var calendar = this,
1557
-
1558
- // Keep a reference to the original date.
1559
- originalDateObject = dateObject,
1560
-
1561
- // Make sure we have an interval.
1562
- interval = options && options.interval ? options.interval : 1,
1563
-
1564
- // Check if the calendar enabled dates are inverted.
1565
- isFlippedBase = calendar.item.enable === -1,
1566
-
1567
- // Check if we have any enabled dates after/before now.
1568
- hasEnabledBeforeTarget, hasEnabledAfterTarget,
1569
-
1570
- // The min & max limits.
1571
- minLimitObject = calendar.item.min,
1572
- maxLimitObject = calendar.item.max,
1573
-
1574
- // Check if we’ve reached the limit during shifting.
1575
- reachedMin, reachedMax,
1576
-
1577
- // Check if the calendar is inverted and at least one weekday is enabled.
1578
- hasEnabledWeekdays = isFlippedBase && calendar.item.disable.filter(function (value) {
1579
-
1580
- // If there’s a date, check where it is relative to the target.
1581
- if ($.isArray(value)) {
1582
- var dateTime = calendar.create(value).pick
1583
- if (dateTime < dateObject.pick) hasEnabledBeforeTarget = true
1584
- else if (dateTime > dateObject.pick) hasEnabledAfterTarget = true
1585
- }
1586
-
1587
- // Return only integers for enabled weekdays.
1588
- return _.isInteger(value)
1589
- }).length
1590
- /*,
1591
-
1592
- safety = 100*/
1593
-
1594
-
1595
-
1596
- // Cases to validate for:
1597
- // [1] Not inverted and date disabled.
1598
- // [2] Inverted and some dates enabled.
1599
- // [3] Not inverted and out of range.
1600
- //
1601
- // Cases to **not** validate for:
1602
- // • Navigating months.
1603
- // • Not inverted and date enabled.
1604
- // • Inverted and all dates disabled.
1605
- // • ..and anything else.
1606
- if (!options || !options.nav)
1607
- if (
1608
- /* 1 */
1609
- (!isFlippedBase && calendar.disabled(dateObject)) ||
1610
- /* 2 */
1611
- (isFlippedBase && calendar.disabled(dateObject) && (hasEnabledWeekdays || hasEnabledBeforeTarget || hasEnabledAfterTarget)) ||
1612
- /* 3 */
1613
- (!isFlippedBase && (dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick))
1614
- ) {
1615
-
1616
-
1617
- // When inverted, flip the direction if there aren’t any enabled weekdays
1618
- // and there are no enabled dates in the direction of the interval.
1619
- if (isFlippedBase && !hasEnabledWeekdays && ((!hasEnabledAfterTarget && interval > 0) || (!hasEnabledBeforeTarget && interval < 0))) {
1620
- interval *= -1
1621
- }
1622
-
1623
-
1624
- // Keep looping until we reach an enabled date.
1625
- while ( /*safety &&*/ calendar.disabled(dateObject)) {
1626
-
1627
- /*safety -= 1
1628
- if ( !safety ) {
1629
- throw 'Fell into an infinite loop while validating ' + dateObject.obj + '.'
1630
- }*/
1631
-
1632
-
1633
- // If we’ve looped into the next/prev month with a large interval, return to the original date and flatten the interval.
1634
- if (Math.abs(interval) > 1 && (dateObject.month < originalDateObject.month || dateObject.month > originalDateObject.month)) {
1635
- dateObject = originalDateObject
1636
- interval = interval > 0 ? 1 : -1
1637
- }
1638
-
1639
-
1640
- // If we’ve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit.
1641
- if (dateObject.pick <= minLimitObject.pick) {
1642
- reachedMin = true
1643
- interval = 1
1644
- dateObject = calendar.create([
1645
- minLimitObject.year,
1646
- minLimitObject.month,
1647
- minLimitObject.date + (dateObject.pick === minLimitObject.pick ? 0 : -1)
1648
- ])
1649
- } else if (dateObject.pick >= maxLimitObject.pick) {
1650
- reachedMax = true
1651
- interval = -1
1652
- dateObject = calendar.create([
1653
- maxLimitObject.year,
1654
- maxLimitObject.month,
1655
- maxLimitObject.date + (dateObject.pick === maxLimitObject.pick ? 0 : 1)
1656
- ])
1657
- }
1658
-
1659
-
1660
- // If we’ve reached both limits, just break out of the loop.
1661
- if (reachedMin && reachedMax) {
1662
- break
1663
- }
1664
-
1665
-
1666
- // Finally, create the shifted date using the interval and keep looping.
1667
- dateObject = calendar.create([dateObject.year, dateObject.month, dateObject.date + interval])
1668
- }
1669
-
1670
- } //endif
1671
-
1672
-
1673
- // Return the date object settled on.
1674
- return dateObject
1675
- } //DatePicker.prototype.validate
1676
-
1677
-
1678
- /**
1679
- * Check if a date is disabled.
1680
- */
1681
- DatePicker.prototype.disabled = function (dateToVerify) {
1682
-
1683
- var
1684
- calendar = this,
1685
-
1686
- // Filter through the disabled dates to check if this is one.
1687
- isDisabledMatch = calendar.item.disable.filter(function (dateToDisable) {
1688
-
1689
- // If the date is a number, match the weekday with 0index and `firstDay` check.
1690
- if (_.isInteger(dateToDisable)) {
1691
- return dateToVerify.day === (calendar.settings.firstDay ? dateToDisable : dateToDisable - 1) % 7
1692
- }
1693
-
1694
- // If it’s an array or a native JS date, create and match the exact date.
1695
- if ($.isArray(dateToDisable) || _.isDate(dateToDisable)) {
1696
- return dateToVerify.pick === calendar.create(dateToDisable).pick
1697
- }
1698
-
1699
- // If it’s an object, match a date within the “from” and “to” range.
1700
- if ($.isPlainObject(dateToDisable)) {
1701
- return calendar.withinRange(dateToDisable, dateToVerify)
1702
- }
1703
- })
1704
-
1705
- // If this date matches a disabled date, confirm it’s not inverted.
1706
- isDisabledMatch = isDisabledMatch.length && !isDisabledMatch.filter(function (dateToDisable) {
1707
- return $.isArray(dateToDisable) && dateToDisable[3] == 'inverted' ||
1708
- $.isPlainObject(dateToDisable) && dateToDisable.inverted
1709
- }).length
1710
-
1711
- // Check the calendar “enabled” flag and respectively flip the
1712
- // disabled state. Then also check if it’s beyond the min/max limits.
1713
- return calendar.item.enable === -1 ? !isDisabledMatch : isDisabledMatch ||
1714
- dateToVerify.pick < calendar.item.min.pick ||
1715
- dateToVerify.pick > calendar.item.max.pick
1716
-
1717
- } //DatePicker.prototype.disabled
1718
-
1719
-
1720
- /**
1721
- * Parse a string into a usable type.
1722
- */
1723
- DatePicker.prototype.parse = function (type, value, options) {
1724
-
1725
- var calendar = this,
1726
- parsingObject = {}
1727
-
1728
- // If it’s already parsed, we’re good.
1729
- if (!value || typeof value != 'string') {
1730
- return value
1731
- }
1732
-
1733
- // We need a `.format` to parse the value with.
1734
- if (!(options && options.format)) {
1735
- options = options || {}
1736
- options.format = calendar.settings.format
1737
- }
1738
-
1739
- // Convert the format into an array and then map through it.
1740
- calendar.formats.toArray(options.format).map(function (label) {
1741
-
1742
- var
1743
- // Grab the formatting label.
1744
- formattingLabel = calendar.formats[label],
1745
-
1746
- // The format length is from the formatting label function or the
1747
- // label length without the escaping exclamation (!) mark.
1748
- formatLength = formattingLabel ? _.trigger(formattingLabel, calendar, [value, parsingObject]) : label.replace(/^!/, '').length
1749
-
1750
- // If there's a format label, split the value up to the format length.
1751
- // Then add it to the parsing object with appropriate label.
1752
- if (formattingLabel) {
1753
- parsingObject[label] = value.substr(0, formatLength)
1754
- }
1755
-
1756
- // Update the value as the substring from format length to end.
1757
- value = value.substr(formatLength)
1758
- })
1759
-
1760
- // Compensate for month 0index.
1761
- return [
1762
- parsingObject.yyyy || parsingObject.yy, +(parsingObject.mm || parsingObject.m) - 1,
1763
- parsingObject.dd || parsingObject.d
1764
- ]
1765
- } //DatePicker.prototype.parse
1766
-
1767
-
1768
- /**
1769
- * Various formats to display the object in.
1770
- */
1771
- DatePicker.prototype.formats = (function () {
1772
-
1773
- // Return the length of the first word in a collection.
1774
- function getWordLengthFromCollection(string, collection, dateObject) {
1775
-
1776
- // Grab the first word from the string.
1777
- var word = string.match(/\w+/)[0]
1778
-
1779
- // If there's no month index, add it to the date object
1780
- if (!dateObject.mm && !dateObject.m) {
1781
- dateObject.m = collection.indexOf(word) + 1
1782
- }
1783
-
1784
- // Return the length of the word.
1785
- return word.length
1786
- }
1787
-
1788
- // Get the length of the first word in a string.
1789
- function getFirstWordLength(string) {
1790
- return string.match(/\w+/)[0].length
1791
- }
1792
-
1793
- return {
1794
-
1795
- d: function (string, dateObject) {
1796
-
1797
- // If there's string, then get the digits length.
1798
- // Otherwise return the selected date.
1799
- return string ? _.digits(string) : dateObject.date
1800
- },
1801
- dd: function (string, dateObject) {
1802
-
1803
- // If there's a string, then the length is always 2.
1804
- // Otherwise return the selected date with a leading zero.
1805
- return string ? 2 : _.lead(dateObject.date)
1806
- },
1807
- ddd: function (string, dateObject) {
1808
-
1809
- // If there's a string, then get the length of the first word.
1810
- // Otherwise return the short selected weekday.
1811
- return string ? getFirstWordLength(string) : this.settings.weekdaysShort[dateObject.day]
1812
- },
1813
- dddd: function (string, dateObject) {
1814
-
1815
- // If there's a string, then get the length of the first word.
1816
- // Otherwise return the full selected weekday.
1817
- return string ? getFirstWordLength(string) : this.settings.weekdaysFull[dateObject.day]
1818
- },
1819
- m: function (string, dateObject) {
1820
-
1821
- // If there's a string, then get the length of the digits
1822
- // Otherwise return the selected month with 0index compensation.
1823
- return string ? _.digits(string) : dateObject.month + 1
1824
- },
1825
- mm: function (string, dateObject) {
1826
-
1827
- // If there's a string, then the length is always 2.
1828
- // Otherwise return the selected month with 0index and leading zero.
1829
- return string ? 2 : _.lead(dateObject.month + 1)
1830
- },
1831
- mmm: function (string, dateObject) {
1832
-
1833
- var collection = this.settings.monthsShort
1834
-
1835
- // If there's a string, get length of the relevant month from the short
1836
- // months collection. Otherwise return the selected month from that collection.
1837
- return string ? getWordLengthFromCollection(string, collection, dateObject) : collection[dateObject.month]
1838
- },
1839
- mmmm: function (string, dateObject) {
1840
-
1841
- var collection = this.settings.monthsFull
1842
-
1843
- // If there's a string, get length of the relevant month from the full
1844
- // months collection. Otherwise return the selected month from that collection.
1845
- return string ? getWordLengthFromCollection(string, collection, dateObject) : collection[dateObject.month]
1846
- },
1847
- yy: function (string, dateObject) {
1848
-
1849
- // If there's a string, then the length is always 2.
1850
- // Otherwise return the selected year by slicing out the first 2 digits.
1851
- return string ? 2 : ('' + dateObject.year).slice(2)
1852
- },
1853
- yyyy: function (string, dateObject) {
1854
-
1855
- // If there's a string, then the length is always 4.
1856
- // Otherwise return the selected year.
1857
- return string ? 4 : dateObject.year
1858
- },
1859
-
1860
- // Create an array by splitting the formatting string passed.
1861
- toArray: function (formatString) {
1862
- return formatString.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)
1863
- },
1864
-
1865
- // Format an object into a string using the formatting options.
1866
- toString: function (formatString, itemObject) {
1867
- var calendar = this
1868
- return calendar.formats.toArray(formatString).map(function (label) {
1869
- return _.trigger(calendar.formats[label], calendar, [0, itemObject]) || label.replace(/^!/, '')
1870
- }).join('')
1871
- }
1872
- }
1873
- })() //DatePicker.prototype.formats
1874
-
1875
-
1876
-
1877
-
1878
- /**
1879
- * Check if two date units are the exact.
1880
- */
1881
- DatePicker.prototype.isDateExact = function (one, two) {
1882
-
1883
- var calendar = this
1884
-
1885
- // When we’re working with weekdays, do a direct comparison.
1886
- if (
1887
- (_.isInteger(one) && _.isInteger(two)) ||
1888
- (typeof one == 'boolean' && typeof two == 'boolean')
1889
- ) {
1890
- return one === two
1891
- }
1892
-
1893
- // When we’re working with date representations, compare the “pick” value.
1894
- if (
1895
- (_.isDate(one) || $.isArray(one)) &&
1896
- (_.isDate(two) || $.isArray(two))
1897
- ) {
1898
- return calendar.create(one).pick === calendar.create(two).pick
1899
- }
1900
-
1901
- // When we’re working with range objects, compare the “from” and “to”.
1902
- if ($.isPlainObject(one) && $.isPlainObject(two)) {
1903
- return calendar.isDateExact(one.from, two.from) && calendar.isDateExact(one.to, two.to)
1904
- }
1905
-
1906
- return false
1907
- }
1908
-
1909
-
1910
- /**
1911
- * Check if two date units overlap.
1912
- */
1913
- DatePicker.prototype.isDateOverlap = function (one, two) {
1914
-
1915
- var calendar = this,
1916
- firstDay = calendar.settings.firstDay ? 1 : 0
1917
-
1918
- // When we’re working with a weekday index, compare the days.
1919
- if (_.isInteger(one) && (_.isDate(two) || $.isArray(two))) {
1920
- one = one % 7 + firstDay
1921
- return one === calendar.create(two).day + 1
1922
- }
1923
- if (_.isInteger(two) && (_.isDate(one) || $.isArray(one))) {
1924
- two = two % 7 + firstDay
1925
- return two === calendar.create(one).day + 1
1926
- }
1927
-
1928
- // When we’re working with range objects, check if the ranges overlap.
1929
- if ($.isPlainObject(one) && $.isPlainObject(two)) {
1930
- return calendar.overlapRanges(one, two)
1931
- }
1932
-
1933
- return false
1934
- }
1935
-
1936
-
1937
- /**
1938
- * Flip the “enabled” state.
1939
- */
1940
- DatePicker.prototype.flipEnable = function (val) {
1941
- var itemObject = this.item
1942
- itemObject.enable = val || (itemObject.enable == -1 ? 1 : -1)
1943
- }
1944
-
1945
-
1946
- /**
1947
- * Mark a collection of dates as “disabled”.
1948
- */
1949
- DatePicker.prototype.deactivate = function (type, datesToDisable) {
1950
-
1951
- var calendar = this,
1952
- disabledItems = calendar.item.disable.slice(0)
1953
-
1954
-
1955
- // If we’re flipping, that’s all we need to do.
1956
- if (datesToDisable == 'flip') {
1957
- calendar.flipEnable()
1958
- } else if (datesToDisable === false) {
1959
- calendar.flipEnable(1)
1960
- disabledItems = []
1961
- } else if (datesToDisable === true) {
1962
- calendar.flipEnable(-1)
1963
- disabledItems = []
1964
- }
1965
-
1966
- // Otherwise go through the dates to disable.
1967
- else {
1968
-
1969
- datesToDisable.map(function (unitToDisable) {
1970
-
1971
- var matchFound
1972
-
1973
- // When we have disabled items, check for matches.
1974
- // If something is matched, immediately break out.
1975
- for (var index = 0; index < disabledItems.length; index += 1) {
1976
- if (calendar.isDateExact(unitToDisable, disabledItems[index])) {
1977
- matchFound = true
1978
- break
1979
- }
1980
- }
1981
-
1982
- // If nothing was found, add the validated unit to the collection.
1983
- if (!matchFound) {
1984
- if (
1985
- _.isInteger(unitToDisable) ||
1986
- _.isDate(unitToDisable) ||
1987
- $.isArray(unitToDisable) ||
1988
- ($.isPlainObject(unitToDisable) && unitToDisable.from && unitToDisable.to)
1989
- ) {
1990
- disabledItems.push(unitToDisable)
1991
- }
1992
- }
1993
- })
1994
- }
1995
-
1996
- // Return the updated collection.
1997
- return disabledItems
1998
- } //DatePicker.prototype.deactivate
1999
-
2000
-
2001
- /**
2002
- * Mark a collection of dates as “enabled”.
2003
- */
2004
- DatePicker.prototype.activate = function (type, datesToEnable) {
2005
-
2006
- var calendar = this,
2007
- disabledItems = calendar.item.disable,
2008
- disabledItemsCount = disabledItems.length
2009
-
2010
- // If we’re flipping, that’s all we need to do.
2011
- if (datesToEnable == 'flip') {
2012
- calendar.flipEnable()
2013
- } else if (datesToEnable === true) {
2014
- calendar.flipEnable(1)
2015
- disabledItems = []
2016
- } else if (datesToEnable === false) {
2017
- calendar.flipEnable(-1)
2018
- disabledItems = []
2019
- }
2020
-
2021
- // Otherwise go through the disabled dates.
2022
- else {
2023
-
2024
- datesToEnable.map(function (unitToEnable) {
2025
-
2026
- var matchFound,
2027
- disabledUnit,
2028
- index,
2029
- isExactRange
2030
-
2031
- // Go through the disabled items and try to find a match.
2032
- for (index = 0; index < disabledItemsCount; index += 1) {
2033
-
2034
- disabledUnit = disabledItems[index]
2035
-
2036
- // When an exact match is found, remove it from the collection.
2037
- if (calendar.isDateExact(disabledUnit, unitToEnable)) {
2038
- matchFound = disabledItems[index] = null
2039
- isExactRange = true
2040
- break
2041
- }
2042
-
2043
- // When an overlapped match is found, add the “inverted” state to it.
2044
- else if (calendar.isDateOverlap(disabledUnit, unitToEnable)) {
2045
- if ($.isPlainObject(unitToEnable)) {
2046
- unitToEnable.inverted = true
2047
- matchFound = unitToEnable
2048
- } else if ($.isArray(unitToEnable)) {
2049
- matchFound = unitToEnable
2050
- if (!matchFound[3]) matchFound.push('inverted')
2051
- } else if (_.isDate(unitToEnable)) {
2052
- matchFound = [unitToEnable.getFullYear(), unitToEnable.getMonth(), unitToEnable.getDate(), 'inverted']
2053
- }
2054
- break
2055
- }
2056
- }
2057
-
2058
- // If a match was found, remove a previous duplicate entry.
2059
- if (matchFound)
2060
- for (index = 0; index < disabledItemsCount; index += 1) {
2061
- if (calendar.isDateExact(disabledItems[index], unitToEnable)) {
2062
- disabledItems[index] = null
2063
- break
2064
- }
2065
- }
2066
-
2067
- // In the event that we’re dealing with an exact range of dates,
2068
- // make sure there are no “inverted” dates because of it.
2069
- if (isExactRange)
2070
- for (index = 0; index < disabledItemsCount; index += 1) {
2071
- if (calendar.isDateOverlap(disabledItems[index], unitToEnable)) {
2072
- disabledItems[index] = null
2073
- break
2074
- }
2075
- }
2076
-
2077
- // If something is still matched, add it into the collection.
2078
- if (matchFound) {
2079
- disabledItems.push(matchFound)
2080
- }
2081
- })
2082
- }
2083
-
2084
- // Return the updated collection.
2085
- return disabledItems.filter(function (val) {
2086
- return val != null
2087
- })
2088
- } //DatePicker.prototype.activate
2089
-
2090
-
2091
- /**
2092
- * Create a string for the nodes in the picker.
2093
- */
2094
- DatePicker.prototype.nodes = function (isOpen) {
2095
-
2096
- var
2097
- calendar = this,
2098
- settings = calendar.settings,
2099
- calendarItem = calendar.item,
2100
- nowObject = calendarItem.now,
2101
- selectedObject = calendarItem.select,
2102
- highlightedObject = calendarItem.highlight,
2103
- viewsetObject = calendarItem.view,
2104
- disabledCollection = calendarItem.disable,
2105
- minLimitObject = calendarItem.min,
2106
- maxLimitObject = calendarItem.max,
2107
-
2108
-
2109
- // Create the calendar table head using a copy of weekday labels collection.
2110
- // * We do a copy so we don't mutate the original array.
2111
- tableHead = (function (collection, fullCollection) {
2112
-
2113
- // If the first day should be Monday, move Sunday to the end.
2114
- if (settings.firstDay) {
2115
- collection.push(collection.shift())
2116
- fullCollection.push(fullCollection.shift())
2117
- }
2118
-
2119
- // Create and return the table head group.
2120
- return _.node(
2121
- 'thead',
2122
- _.node(
2123
- 'tr',
2124
- _.group({
2125
- min: 0,
2126
- max: DAYS_IN_WEEK - 1,
2127
- i: 1,
2128
- node: 'th',
2129
- item: function (counter) {
2130
- return [
2131
- collection[counter],
2132
- settings.klass.weekdays,
2133
- 'scope=col title="' + fullCollection[counter] + '"'
2134
- ]
2135
- }
2136
- })
2137
- )
2138
- ) //endreturn
2139
-
2140
- // Materialize modified
2141
- })((settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysLetter).slice(0), settings.weekdaysFull.slice(0)), //tableHead
2142
-
2143
-
2144
- // Create the nav for next/prev month.
2145
- createMonthNav = function (next) {
2146
-
2147
- // Otherwise, return the created month tag.
2148
- return _.node(
2149
- 'div',
2150
- ' ',
2151
- settings.klass['nav' + (next ? 'Next' : 'Prev')] + (
2152
-
2153
- // If the focused month is outside the range, disabled the button.
2154
- (next && viewsetObject.year >= maxLimitObject.year && viewsetObject.month >= maxLimitObject.month) ||
2155
- (!next && viewsetObject.year <= minLimitObject.year && viewsetObject.month <= minLimitObject.month) ?
2156
- ' ' + settings.klass.navDisabled : ''
2157
- ),
2158
- 'data-nav=' + (next || -1) + ' ' +
2159
- _.ariaAttr({
2160
- role: 'button',
2161
- controls: calendar.$node[0].id + '_table'
2162
- }) + ' ' +
2163
- 'title="' + (next ? settings.labelMonthNext : settings.labelMonthPrev) + '"'
2164
- ) //endreturn
2165
- }, //createMonthNav
2166
-
2167
-
2168
- // Create the month label.
2169
- //Materialize modified
2170
- createMonthLabel = function (override) {
2171
-
2172
- var monthsCollection = settings.showMonthsShort ? settings.monthsShort : settings.monthsFull
2173
-
2174
- // Materialize modified
2175
- if (override == "short_months") {
2176
- monthsCollection = settings.monthsShort;
2177
- }
2178
-
2179
- // If there are months to select, add a dropdown menu.
2180
- if (settings.selectMonths && override == undefined) {
2181
-
2182
- return _.node('select',
2183
- _.group({
2184
- min: 0,
2185
- max: 11,
2186
- i: 1,
2187
- node: 'option',
2188
- item: function (loopedMonth) {
2189
-
2190
- return [
2191
-
2192
- // The looped month and no classes.
2193
- monthsCollection[loopedMonth], 0,
2194
-
2195
- // Set the value and selected index.
2196
- 'value=' + loopedMonth +
2197
- (viewsetObject.month == loopedMonth ? ' selected' : '') +
2198
- (
2199
- (
2200
- (viewsetObject.year == minLimitObject.year && loopedMonth < minLimitObject.month) ||
2201
- (viewsetObject.year == maxLimitObject.year && loopedMonth > maxLimitObject.month)
2202
- ) ?
2203
- ' disabled' : ''
2204
- )
2205
- ]
2206
- }
2207
- }),
2208
- settings.klass.selectMonth + ' browser-default',
2209
- (isOpen ? '' : 'disabled') + ' ' +
2210
- _.ariaAttr({
2211
- controls: calendar.$node[0].id + '_table'
2212
- }) + ' ' +
2213
- 'title="' + settings.labelMonthSelect + '"'
2214
- )
2215
- }
2216
-
2217
- // Materialize modified
2218
- if (override == "short_months")
2219
- if (selectedObject != null)
2220
- return _.node('div', monthsCollection[selectedObject.month]);
2221
- else return _.node('div', monthsCollection[viewsetObject.month]);
2222
-
2223
- // If there's a need for a month selector
2224
- return _.node('div', monthsCollection[viewsetObject.month], settings.klass.month)
2225
- }, //createMonthLabel
2226
-
2227
-
2228
- // Create the year label.
2229
- // Materialize modified
2230
- createYearLabel = function (override) {
2231
-
2232
- var focusedYear = viewsetObject.year,
2233
-
2234
- // If years selector is set to a literal "true", set it to 5. Otherwise
2235
- // divide in half to get half before and half after focused year.
2236
- numberYears = settings.selectYears === true ? 5 : ~~(settings.selectYears / 2)
2237
-
2238
- // If there are years to select, add a dropdown menu.
2239
- if (numberYears) {
2240
-
2241
- var
2242
- minYear = minLimitObject.year,
2243
- maxYear = maxLimitObject.year,
2244
- lowestYear = focusedYear - numberYears,
2245
- highestYear = focusedYear + numberYears
2246
-
2247
- // If the min year is greater than the lowest year, increase the highest year
2248
- // by the difference and set the lowest year to the min year.
2249
- if (minYear > lowestYear) {
2250
- highestYear += minYear - lowestYear
2251
- lowestYear = minYear
2252
- }
2253
-
2254
- // If the max year is less than the highest year, decrease the lowest year
2255
- // by the lower of the two: available and needed years. Then set the
2256
- // highest year to the max year.
2257
- if (maxYear < highestYear) {
2258
-
2259
- var availableYears = lowestYear - minYear,
2260
- neededYears = highestYear - maxYear
2261
-
2262
- lowestYear -= availableYears > neededYears ? neededYears : availableYears
2263
- highestYear = maxYear
2264
- }
2265
-
2266
- if (settings.selectYears && override == undefined) {
2267
- return _.node('select',
2268
- _.group({
2269
- min: lowestYear,
2270
- max: highestYear,
2271
- i: 1,
2272
- node: 'option',
2273
- item: function (loopedYear) {
2274
- return [
2275
-
2276
- // The looped year and no classes.
2277
- loopedYear, 0,
2278
-
2279
- // Set the value and selected index.
2280
- 'value=' + loopedYear + (focusedYear == loopedYear ? ' selected' : '')
2281
- ]
2282
- }
2283
- }),
2284
- settings.klass.selectYear + ' browser-default',
2285
- (isOpen ? '' : 'disabled') + ' ' + _.ariaAttr({
2286
- controls: calendar.$node[0].id + '_table'
2287
- }) + ' ' +
2288
- 'title="' + settings.labelYearSelect + '"'
2289
- )
2290
- }
2291
- }
2292
-
2293
- // Materialize modified
2294
- if (override == "raw")
2295
- return _.node('div', focusedYear)
2296
-
2297
- // Otherwise just return the year focused
2298
- return _.node('div', focusedYear, settings.klass.year)
2299
- } //createYearLabel
2300
-
2301
-
2302
- // Materialize modified
2303
- createDayLabel = function () {
2304
- if (selectedObject != null)
2305
- return _.node('div', selectedObject.date)
2306
- else return _.node('div', nowObject.date)
2307
- }
2308
- createWeekdayLabel = function () {
2309
- var display_day;
2310
-
2311
- if (selectedObject != null)
2312
- display_day = selectedObject.day;
2313
- else
2314
- display_day = nowObject.day;
2315
- var weekday = settings.weekdaysFull[display_day]
2316
- return weekday
2317
- }
2318
-
2319
-
2320
- // Create and return the entire calendar.
2321
- return _.node(
2322
- // Date presentation View
2323
- 'div',
2324
- _.node(
2325
- 'div',
2326
- createWeekdayLabel(),
2327
- "picker__weekday-display"
2328
- ) +
2329
- _.node(
2330
- // Div for short Month
2331
- 'div',
2332
- createMonthLabel("short_months"),
2333
- settings.klass.month_display
2334
- ) +
2335
- _.node(
2336
- // Div for Day
2337
- 'div',
2338
- createDayLabel(),
2339
- settings.klass.day_display
2340
- ) +
2341
- _.node(
2342
- // Div for Year
2343
- 'div',
2344
- createYearLabel("raw"),
2345
- settings.klass.year_display
2346
- ),
2347
- settings.klass.date_display
2348
- ) +
2349
- // Calendar container
2350
- _.node('div',
2351
- _.node('div',
2352
- (settings.selectYears ? createMonthLabel() + createYearLabel() : createMonthLabel() + createYearLabel()) +
2353
- createMonthNav() + createMonthNav(1),
2354
- settings.klass.header
2355
- ) + _.node(
2356
- 'table',
2357
- tableHead +
2358
- _.node(
2359
- 'tbody',
2360
- _.group({
2361
- min: 0,
2362
- max: WEEKS_IN_CALENDAR - 1,
2363
- i: 1,
2364
- node: 'tr',
2365
- item: function (rowCounter) {
2366
-
2367
- // If Monday is the first day and the month starts on Sunday, shift the date back a week.
2368
- var shiftDateBy = settings.firstDay && calendar.create([viewsetObject.year, viewsetObject.month, 1]).day === 0 ? -7 : 0
2369
-
2370
- return [
2371
- _.group({
2372
- min: DAYS_IN_WEEK * rowCounter - viewsetObject.day + shiftDateBy + 1, // Add 1 for weekday 0index
2373
- max: function () {
2374
- return this.min + DAYS_IN_WEEK - 1
2375
- },
2376
- i: 1,
2377
- node: 'td',
2378
- item: function (targetDate) {
2379
-
2380
- // Convert the time date from a relative date to a target date.
2381
- targetDate = calendar.create([viewsetObject.year, viewsetObject.month, targetDate + (settings.firstDay ? 1 : 0)])
2382
-
2383
- var isSelected = selectedObject && selectedObject.pick == targetDate.pick,
2384
- isHighlighted = highlightedObject && highlightedObject.pick == targetDate.pick,
2385
- isDisabled = disabledCollection && calendar.disabled(targetDate) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick,
2386
- formattedDate = _.trigger(calendar.formats.toString, calendar, [settings.format, targetDate])
2387
-
2388
- return [
2389
- _.node(
2390
- 'div',
2391
- targetDate.date,
2392
- (function (klasses) {
2393
-
2394
- // Add the `infocus` or `outfocus` classes based on month in view.
2395
- klasses.push(viewsetObject.month == targetDate.month ? settings.klass.infocus : settings.klass.outfocus)
2396
-
2397
- // Add the `today` class if needed.
2398
- if (nowObject.pick == targetDate.pick) {
2399
- klasses.push(settings.klass.now)
2400
- }
2401
-
2402
- // Add the `selected` class if something's selected and the time matches.
2403
- if (isSelected) {
2404
- klasses.push(settings.klass.selected)
2405
- }
2406
-
2407
- // Add the `highlighted` class if something's highlighted and the time matches.
2408
- if (isHighlighted) {
2409
- klasses.push(settings.klass.highlighted)
2410
- }
2411
-
2412
- // Add the `disabled` class if something's disabled and the object matches.
2413
- if (isDisabled) {
2414
- klasses.push(settings.klass.disabled)
2415
- }
2416
-
2417
- return klasses.join(' ')
2418
- })([settings.klass.day]),
2419
- 'data-pick=' + targetDate.pick + ' ' + _.ariaAttr({
2420
- role: 'gridcell',
2421
- label: formattedDate,
2422
- selected: isSelected && calendar.$node.val() === formattedDate ? true : null,
2423
- activedescendant: isHighlighted ? true : null,
2424
- disabled: isDisabled ? true : null
2425
- })
2426
- ),
2427
- '',
2428
- _.ariaAttr({
2429
- role: 'presentation'
2430
- })
2431
- ] //endreturn
2432
- }
2433
- })
2434
- ] //endreturn
2435
- }
2436
- })
2437
- ),
2438
- settings.klass.table,
2439
- 'id="' + calendar.$node[0].id + '_table' + '" ' + _.ariaAttr({
2440
- role: 'grid',
2441
- controls: calendar.$node[0].id,
2442
- readonly: true
2443
- })
2444
- ), settings.klass.calendar_container) // end calendar
2445
-
2446
- +
2447
-
2448
- // * For Firefox forms to submit, make sure to set the buttons’ `type` attributes as “button”.
2449
- _.node(
2450
- 'div',
2451
- _.node('button', settings.today, "mdui-btn picker__today",
2452
- 'type=button data-pick=' + nowObject.pick +
2453
- (isOpen && !calendar.disabled(nowObject) ? '' : ' disabled') + ' ' +
2454
- _.ariaAttr({
2455
- controls: calendar.$node[0].id
2456
- })) +
2457
- _.node('button', settings.clear, "mdui-btn picker__clear",
2458
- 'type=button data-clear=1' +
2459
- (isOpen ? '' : ' disabled') + ' ' +
2460
- _.ariaAttr({
2461
- controls: calendar.$node[0].id
2462
- })) +
2463
- _.node('button', settings.close, "mdui-btn picker__close",
2464
- 'type=button data-close=true ' +
2465
- (isOpen ? '' : ' disabled') + ' ' +
2466
- _.ariaAttr({
2467
- controls: calendar.$node[0].id
2468
- })),
2469
- settings.klass.footer
2470
- ) //endreturn
2471
- } //DatePicker.prototype.nodes
2472
-
2473
-
2474
-
2475
-
2476
- /**
2477
- * The date picker defaults.
2478
- */
2479
- DatePicker.defaults = (function (prefix) {
2480
-
2481
- return {
2482
-
2483
- // The title label to use for the month nav buttons
2484
- labelMonthNext: 'Next month',
2485
- labelMonthPrev: 'Previous month',
2486
-
2487
- // The title label to use for the dropdown selectors
2488
- labelMonthSelect: 'Select a month',
2489
- labelYearSelect: 'Select a year',
2490
-
2491
- // Months and weekdays
2492
- monthsFull: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
2493
- monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
2494
- weekdaysFull: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
2495
- weekdaysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
2496
-
2497
- // Materialize modified
2498
- weekdaysLetter: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
2499
-
2500
- // Today and clear
2501
- today: 'Today',
2502
- clear: 'Clear',
2503
- close: 'Close',
2504
-
2505
- // The format to show on the `input` element
2506
- format: 'd mmmm, yyyy',
2507
-
2508
- // Classes
2509
- klass: {
2510
-
2511
- table: prefix + 'table',
2512
-
2513
- header: prefix + 'header',
2514
-
2515
-
2516
- // Materialize Added klasses
2517
- date_display: prefix + 'date-display',
2518
- day_display: prefix + 'day-display',
2519
- month_display: prefix + 'month-display',
2520
- year_display: prefix + 'year-display',
2521
- calendar_container: prefix + 'calendar-container',
2522
- // end
2523
-
2524
-
2525
-
2526
- navPrev: prefix + 'nav--prev',
2527
- navNext: prefix + 'nav--next',
2528
- navDisabled: prefix + 'nav--disabled',
2529
-
2530
- month: prefix + 'month',
2531
- year: prefix + 'year',
2532
-
2533
- selectMonth: prefix + 'select--month',
2534
- selectYear: prefix + 'select--year',
2535
-
2536
- weekdays: prefix + 'weekday',
2537
-
2538
- day: prefix + 'day',
2539
- disabled: prefix + 'day--disabled',
2540
- selected: prefix + 'day--selected',
2541
- highlighted: prefix + 'day--highlighted',
2542
- now: prefix + 'day--today',
2543
- infocus: prefix + 'day--infocus',
2544
- outfocus: prefix + 'day--outfocus',
2545
-
2546
- footer: prefix + 'footer',
2547
-
2548
- buttonClear: prefix + 'button--clear',
2549
- buttonToday: prefix + 'button--today',
2550
- buttonClose: prefix + 'button--close'
2551
- }
2552
- }
2553
- })(Picker.klasses().picker + '__')
2554
- /**
2555
- * Extend the picker to add the date picker.
2556
- */
2557
- Picker.extend('pickadate', DatePicker)
2558
- }));
1
+ (function(factory){if(typeof define=="function"&&define.amd){define("picker",["jquery"],factory)}else{if(typeof exports=="object"){module.exports=factory(require("jquery"))}else{this.Picker=factory(jQuery)}}}(function($){var $window=$(window);var $document=$(document);var $html=$(document.documentElement);function PickerConstructor(ELEMENT,NAME,COMPONENT,OPTIONS){if(!ELEMENT){return PickerConstructor}var IS_DEFAULT_THEME=false,STATE={id:ELEMENT.id||"P"+Math.abs(~~(Math.random()*new Date()))},SETTINGS=COMPONENT?$.extend(true,{},COMPONENT.defaults,OPTIONS):OPTIONS||{},CLASSES=$.extend({},PickerConstructor.klasses(),SETTINGS.klass),$ELEMENT=$(ELEMENT),PickerInstance=function(){return this.start()},P=PickerInstance.prototype={constructor:PickerInstance,$node:$ELEMENT,start:function(){if(STATE&&STATE.start){return P}STATE.methods={};STATE.start=true;STATE.open=false;STATE.type=ELEMENT.type;ELEMENT.autofocus=ELEMENT==getActiveElement();ELEMENT.readOnly=!SETTINGS.editable;ELEMENT.id=ELEMENT.id||STATE.id;if(ELEMENT.type!="text"){ELEMENT.type="text"}P.component=new COMPONENT(P,SETTINGS);P.$root=$(PickerConstructor._.node("div",createWrappedComponent(),CLASSES.picker,'id="'+ELEMENT.id+'_root" tabindex="0"'));prepareElementRoot();if(SETTINGS.formatSubmit){prepareElementHidden()}prepareElement();if(SETTINGS.container){$(SETTINGS.container).append(P.$root)}else{$ELEMENT.after(P.$root)}P.on({start:P.component.onStart,render:P.component.onRender,stop:P.component.onStop,open:P.component.onOpen,close:P.component.onClose,set:P.component.onSet}).on({start:SETTINGS.onStart,render:SETTINGS.onRender,stop:SETTINGS.onStop,open:SETTINGS.onOpen,close:SETTINGS.onClose,set:SETTINGS.onSet});IS_DEFAULT_THEME=isUsingDefaultTheme(P.$root.children()[0]);if(ELEMENT.autofocus){P.open()}return P.trigger("start").trigger("render")},render:function(entireComponent){if(entireComponent){P.$root.html(createWrappedComponent())}else{P.$root.find("."+CLASSES.box).html(P.component.nodes(STATE.open))}return P.trigger("render")},stop:function(){if(!STATE.start){return P}P.close();if(P._hidden){P._hidden.parentNode.removeChild(P._hidden)}P.$root.remove();$ELEMENT.removeClass(CLASSES.input).removeData(NAME);setTimeout(function(){$ELEMENT.off("."+STATE.id)},0);ELEMENT.type=STATE.type;ELEMENT.readOnly=false;P.trigger("stop");STATE.methods={};STATE.start=false;return P},open:function(dontGiveFocus){if(STATE.open){return P}$ELEMENT.addClass(CLASSES.active);aria(ELEMENT,"expanded",true);setTimeout(function(){P.$root.addClass(CLASSES.opened);aria(P.$root[0],"hidden",false)},0);if(dontGiveFocus!==false){STATE.open=true;if(IS_DEFAULT_THEME){$html.css("overflow","hidden").css("padding-right","+="+getScrollbarWidth())}P.$root.eq(0).focus();$document.on("click."+STATE.id+" focusin."+STATE.id,function(event){var target=event.target;if(target!=ELEMENT&&target!=document&&event.which!=3){P.close(target===P.$root.children()[0])}}).on("keydown."+STATE.id,function(event){var keycode=event.keyCode,keycodeToMove=P.component.key[keycode],target=event.target;if(keycode==27){P.close(true)}else{if(target==P.$root[0]&&(keycodeToMove||keycode==13)){event.preventDefault();if(keycodeToMove){PickerConstructor._.trigger(P.component.key.go,P,[PickerConstructor._.trigger(keycodeToMove)])}else{if(!P.$root.find("."+CLASSES.highlighted).hasClass(CLASSES.disabled)){P.set("select",P.component.item.highlight).close()}}}else{if($.contains(P.$root[0],target)&&keycode==13){event.preventDefault();target.click()}}}})}return P.trigger("open")},close:function(giveFocus){if(giveFocus){P.$root.off("focus.toOpen").eq(0).focus();setTimeout(function(){P.$root.on("focus.toOpen",handleFocusToOpenEvent)},0)}$ELEMENT.removeClass(CLASSES.active);aria(ELEMENT,"expanded",false);setTimeout(function(){P.$root.removeClass(CLASSES.opened+" "+CLASSES.focused);aria(P.$root[0],"hidden",true)},0);if(!STATE.open){return P}STATE.open=false;if(IS_DEFAULT_THEME){$html.css("overflow","").css("padding-right","-="+getScrollbarWidth())}$document.off("."+STATE.id);return P.trigger("close")},clear:function(options){return P.set("clear",null,options)},set:function(thing,value,options){var thingItem,thingValue,thingIsObject=$.isPlainObject(thing),thingObject=thingIsObject?thing:{};options=thingIsObject&&$.isPlainObject(value)?value:options||{};if(thing){if(!thingIsObject){thingObject[thing]=value}for(thingItem in thingObject){thingValue=thingObject[thingItem];if(thingItem in P.component.item){if(thingValue===undefined){thingValue=null}P.component.set(thingItem,thingValue,options)}if(thingItem=="select"||thingItem=="clear"){$ELEMENT.val(thingItem=="clear"?"":P.get(thingItem,SETTINGS.format)).trigger("change")}}P.render()}return options.muted?P:P.trigger("set",thingObject)},get:function(thing,format){thing=thing||"value";if(STATE[thing]!=null){return STATE[thing]}if(thing=="valueSubmit"){if(P._hidden){return P._hidden.value}thing="value"}if(thing=="value"){return ELEMENT.value}if(thing in P.component.item){if(typeof format=="string"){var thingValue=P.component.get(thing);
2
+ return thingValue?PickerConstructor._.trigger(P.component.formats.toString,P.component,[format,thingValue]):""}return P.component.get(thing)}},on:function(thing,method,internal){var thingName,thingMethod,thingIsObject=$.isPlainObject(thing),thingObject=thingIsObject?thing:{};if(thing){if(!thingIsObject){thingObject[thing]=method}for(thingName in thingObject){thingMethod=thingObject[thingName];if(internal){thingName="_"+thingName}STATE.methods[thingName]=STATE.methods[thingName]||[];STATE.methods[thingName].push(thingMethod)}}return P},off:function(){var i,thingName,names=arguments;for(i=0,namesCount=names.length;i<namesCount;i+=1){thingName=names[i];if(thingName in STATE.methods){delete STATE.methods[thingName]}}return P},trigger:function(name,data){var _trigger=function(name){var methodList=STATE.methods[name];if(methodList){methodList.map(function(method){PickerConstructor._.trigger(method,P,[data])})}};_trigger("_"+name);_trigger(name);return P}};function createWrappedComponent(){return PickerConstructor._.node("div",PickerConstructor._.node("div",PickerConstructor._.node("div",PickerConstructor._.node("div",P.component.nodes(STATE.open),CLASSES.box),CLASSES.wrap),CLASSES.frame),CLASSES.holder)}function prepareElement(){$ELEMENT.data(NAME,P).addClass(CLASSES.input).attr("tabindex",-1).val($ELEMENT.data("value")?P.get("select",SETTINGS.format):ELEMENT.value);if(!SETTINGS.editable){$ELEMENT.on("focus."+STATE.id+" click."+STATE.id,function(event){event.preventDefault();P.$root.eq(0).focus()}).on("keydown."+STATE.id,handleKeydownEvent)}aria(ELEMENT,{haspopup:true,expanded:false,readonly:false,owns:ELEMENT.id+"_root"})}function prepareElementRoot(){P.$root.on({keydown:handleKeydownEvent,focusin:function(event){P.$root.removeClass(CLASSES.focused);event.stopPropagation()},"mousedown click":function(event){var target=event.target;if(target!=P.$root.children()[0]){event.stopPropagation();if(event.type=="mousedown"&&!$(target).is("input, select, textarea, button, option")){event.preventDefault();P.$root.eq(0).focus()}}}}).on({focus:function(){$ELEMENT.addClass(CLASSES.target)},blur:function(){$ELEMENT.removeClass(CLASSES.target)}}).on("focus.toOpen",handleFocusToOpenEvent).on("click","[data-pick], [data-nav], [data-clear], [data-close]",function(){var $target=$(this),targetData=$target.data(),targetDisabled=$target.hasClass(CLASSES.navDisabled)||$target.hasClass(CLASSES.disabled),activeElement=getActiveElement();activeElement=activeElement&&(activeElement.type||activeElement.href);if(targetDisabled||activeElement&&!$.contains(P.$root[0],activeElement)){P.$root.eq(0).focus()}if(!targetDisabled&&targetData.nav){P.set("highlight",P.component.item.highlight,{nav:targetData.nav})}else{if(!targetDisabled&&"pick" in targetData){P.set("select",targetData.pick)}else{if(targetData.clear){P.clear().close(true)}else{if(targetData.close){P.close(true)}}}}});aria(P.$root[0],"hidden",true)}function prepareElementHidden(){var name;if(SETTINGS.hiddenName===true){name=ELEMENT.name;ELEMENT.name=""}else{name=[typeof SETTINGS.hiddenPrefix=="string"?SETTINGS.hiddenPrefix:"",typeof SETTINGS.hiddenSuffix=="string"?SETTINGS.hiddenSuffix:"_submit"];name=name[0]+ELEMENT.name+name[1]}P._hidden=$("<input "+"type=hidden "+'name="'+name+'"'+($ELEMENT.data("value")||ELEMENT.value?' value="'+P.get("select",SETTINGS.formatSubmit)+'"':"")+">")[0];$ELEMENT.on("change."+STATE.id,function(){P._hidden.value=ELEMENT.value?P.get("select",SETTINGS.formatSubmit):""});if(SETTINGS.container){$(SETTINGS.container).append(P._hidden)}else{$ELEMENT.after(P._hidden)}}function handleKeydownEvent(event){var keycode=event.keyCode,isKeycodeDelete=/^(8|46)$/.test(keycode);if(keycode==27){P.close();return false}if(keycode==32||isKeycodeDelete||!STATE.open&&P.component.key[keycode]){event.preventDefault();event.stopPropagation();if(isKeycodeDelete){P.clear().close()}else{P.open()}}}function handleFocusToOpenEvent(event){event.stopPropagation();if(event.type=="focus"){P.$root.addClass(CLASSES.focused)}P.open()}return new PickerInstance()}PickerConstructor.klasses=function(prefix){prefix=prefix||"picker";return{picker:prefix,opened:prefix+"--opened",focused:prefix+"--focused",input:prefix+"__input",active:prefix+"__input--active",target:prefix+"__input--target",holder:prefix+"__holder",frame:prefix+"__frame",wrap:prefix+"__wrap",box:prefix+"__box"}};function isUsingDefaultTheme(element){var theme,prop="position";if(element.currentStyle){theme=element.currentStyle[prop]}else{if(window.getComputedStyle){theme=getComputedStyle(element)[prop]}}return theme=="fixed"}function getScrollbarWidth(){if($html.height()<=$window.height()){return 0}var $outer=$('<div style="visibility:hidden;width:100px" />').appendTo("body");var widthWithoutScroll=$outer[0].offsetWidth;$outer.css("overflow","scroll");var $inner=$('<div style="width:100%" />').appendTo($outer);var widthWithScroll=$inner[0].offsetWidth;$outer.remove();return widthWithoutScroll-widthWithScroll}PickerConstructor._={group:function(groupObject){var loopObjectScope,nodesList="",counter=PickerConstructor._.trigger(groupObject.min,groupObject);
3
+ for(;counter<=PickerConstructor._.trigger(groupObject.max,groupObject,[counter]);counter+=groupObject.i){loopObjectScope=PickerConstructor._.trigger(groupObject.item,groupObject,[counter]);nodesList+=PickerConstructor._.node(groupObject.node,loopObjectScope[0],loopObjectScope[1],loopObjectScope[2])}return nodesList},node:function(wrapper,item,klass,attribute){if(!item){return""}item=$.isArray(item)?item.join(""):item;klass=klass?' class="'+klass+'"':"";attribute=attribute?" "+attribute:"";return"<"+wrapper+klass+attribute+">"+item+"</"+wrapper+">"},lead:function(number){return(number<10?"0":"")+number},trigger:function(callback,scope,args){return typeof callback=="function"?callback.apply(scope,args||[]):callback},digits:function(string){return(/\d/).test(string[1])?2:1},isDate:function(value){return{}.toString.call(value).indexOf("Date")>-1&&this.isInteger(value.getDate())},isInteger:function(value){return{}.toString.call(value).indexOf("Number")>-1&&value%1===0},ariaAttr:ariaAttr};PickerConstructor.extend=function(name,Component){$.fn[name]=function(options,action){var componentData=this.data(name);if(options=="picker"){return componentData}if(componentData&&typeof options=="string"){return PickerConstructor._.trigger(componentData[options],componentData,[action])}return this.each(function(){var $this=$(this);if(!$this.data(name)){new PickerConstructor(this,name,Component,options)}})};$.fn[name].defaults=Component.defaults};function aria(element,attribute,value){if($.isPlainObject(attribute)){for(var key in attribute){ariaSet(element,key,attribute[key])}}else{ariaSet(element,attribute,value)}}function ariaSet(element,attribute,value){element.setAttribute((attribute=="role"?"":"aria-")+attribute,value)}function ariaAttr(attribute,data){if(!$.isPlainObject(attribute)){attribute={attribute:data}}data="";for(var key in attribute){var attr=(key=="role"?"":"aria-")+key,attrVal=attribute[key];data+=attrVal==null?"":attr+'="'+attribute[key]+'"'}return data}function getActiveElement(){try{return document.activeElement}catch(err){}}return PickerConstructor}));
4
+
5
+ (function(factory){if(typeof define=="function"&&define.amd){define(["picker","jquery"],factory)}else{if(typeof exports=="object"){module.exports=factory(require("./picker.js"),require("jquery"))}else{factory(Picker,jQuery)}}}(function(Picker,$){var DAYS_IN_WEEK=7,WEEKS_IN_CALENDAR=6,_=Picker._;function DatePicker(picker,settings){var calendar=this,element=picker.$node[0],elementValue=element.value,elementDataValue=picker.$node.data("value"),valueString=elementDataValue||elementValue,formatString=elementDataValue?settings.formatSubmit:settings.format,isRTL=function(){return element.currentStyle?element.currentStyle.direction=="rtl":getComputedStyle(picker.$root[0]).direction=="rtl"};calendar.settings=settings;calendar.$node=picker.$node;calendar.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"};calendar.item={};calendar.item.clear=null;calendar.item.disable=(settings.disable||[]).slice(0);calendar.item.enable=-(function(collectionDisabled){return collectionDisabled[0]===true?collectionDisabled.shift():-1})(calendar.item.disable);calendar.set("min",settings.min).set("max",settings.max).set("now");if(valueString){calendar.set("select",valueString,{format:formatString})}else{calendar.set("select",null).set("highlight",calendar.item.now)}calendar.key={40:7,38:-7,39:function(){return isRTL()?-1:1},37:function(){return isRTL()?1:-1},go:function(timeChange){var highlightedObject=calendar.item.highlight,targetDate=new Date(highlightedObject.year,highlightedObject.month,highlightedObject.date+timeChange);calendar.set("highlight",targetDate,{interval:timeChange});this.render()}};picker.on("render",function(){picker.$root.find("."+settings.klass.selectMonth).on("change",function(){var value=this.value;if(value){picker.set("highlight",[picker.get("view").year,value,picker.get("highlight").date]);picker.$root.find("."+settings.klass.selectMonth).trigger("focus")}});picker.$root.find("."+settings.klass.selectYear).on("change",function(){var value=this.value;if(value){picker.set("highlight",[value,picker.get("view").month,picker.get("highlight").date]);picker.$root.find("."+settings.klass.selectYear).trigger("focus")}})},1).on("open",function(){var includeToday="";if(calendar.disabled(calendar.get("now"))){includeToday=":not(."+settings.klass.buttonToday+")"}picker.$root.find("button"+includeToday+", select").attr("disabled",false)},1).on("close",function(){picker.$root.find("button, select").attr("disabled",true)},1)}DatePicker.prototype.set=function(type,value,options){var calendar=this,calendarItem=calendar.item;if(value===null){if(type=="clear"){type="select"}calendarItem[type]=value;return calendar}calendarItem[(type=="enable"?"disable":type=="flip"?"enable":type)]=calendar.queue[type].split(" ").map(function(method){value=calendar[method](type,value,options);
6
+ return value}).pop();if(type=="select"){calendar.set("highlight",calendarItem.select,options)}else{if(type=="highlight"){calendar.set("view",calendarItem.highlight,options)}else{if(type.match(/^(flip|min|max|disable|enable)$/)){if(calendarItem.select&&calendar.disabled(calendarItem.select)){calendar.set("select",calendarItem.select,options)}if(calendarItem.highlight&&calendar.disabled(calendarItem.highlight)){calendar.set("highlight",calendarItem.highlight,options)}}}}return calendar};DatePicker.prototype.get=function(type){return this.item[type]};DatePicker.prototype.create=function(type,value,options){var isInfiniteValue,calendar=this;value=value===undefined?type:value;if(value==-Infinity||value==Infinity){isInfiniteValue=value}else{if($.isPlainObject(value)&&_.isInteger(value.pick)){value=value.obj}else{if($.isArray(value)){value=new Date(value[0],value[1],value[2]);value=_.isDate(value)?value:calendar.create().obj}else{if(_.isInteger(value)||_.isDate(value)){value=calendar.normalize(new Date(value),options)}else{value=calendar.now(type,value,options)}}}}return{year:isInfiniteValue||value.getFullYear(),month:isInfiniteValue||value.getMonth(),date:isInfiniteValue||value.getDate(),day:isInfiniteValue||value.getDay(),obj:isInfiniteValue||value,pick:isInfiniteValue||value.getTime()}};DatePicker.prototype.createRange=function(from,to){var calendar=this,createDate=function(date){if(date===true||$.isArray(date)||_.isDate(date)){return calendar.create(date)}return date};if(!_.isInteger(from)){from=createDate(from)}if(!_.isInteger(to)){to=createDate(to)}if(_.isInteger(from)&&$.isPlainObject(to)){from=[to.year,to.month,to.date+from]}else{if(_.isInteger(to)&&$.isPlainObject(from)){to=[from.year,from.month,from.date+to]}}return{from:createDate(from),to:createDate(to)}};DatePicker.prototype.withinRange=function(range,dateUnit){range=this.createRange(range.from,range.to);return dateUnit.pick>=range.from.pick&&dateUnit.pick<=range.to.pick};DatePicker.prototype.overlapRanges=function(one,two){var calendar=this;one=calendar.createRange(one.from,one.to);two=calendar.createRange(two.from,two.to);return calendar.withinRange(one,two.from)||calendar.withinRange(one,two.to)||calendar.withinRange(two,one.from)||calendar.withinRange(two,one.to)};DatePicker.prototype.now=function(type,value,options){value=new Date();if(options&&options.rel){value.setDate(value.getDate()+options.rel)}return this.normalize(value,options)};DatePicker.prototype.navigate=function(type,value,options){var targetDateObject,targetYear,targetMonth,targetDate,isTargetArray=$.isArray(value),isTargetObject=$.isPlainObject(value),viewsetObject=this.item.view;if(isTargetArray||isTargetObject){if(isTargetObject){targetYear=value.year;targetMonth=value.month;targetDate=value.date}else{targetYear=+value[0];targetMonth=+value[1];targetDate=+value[2]}if(options&&options.nav&&viewsetObject&&viewsetObject.month!==targetMonth){targetYear=viewsetObject.year;targetMonth=viewsetObject.month}targetDateObject=new Date(targetYear,targetMonth+(options&&options.nav?options.nav:0),1);targetYear=targetDateObject.getFullYear();targetMonth=targetDateObject.getMonth();while(new Date(targetYear,targetMonth,targetDate).getMonth()!==targetMonth){targetDate-=1}value=[targetYear,targetMonth,targetDate]}return value};DatePicker.prototype.normalize=function(value){value.setHours(0,0,0,0);return value};DatePicker.prototype.measure=function(type,value){var calendar=this;if(!value){value=type=="min"?-Infinity:Infinity}else{if(typeof value=="string"){value=calendar.parse(type,value)}else{if(_.isInteger(value)){value=calendar.now(type,value,{rel:value})}}}return value};DatePicker.prototype.viewset=function(type,dateObject){return this.create([dateObject.year,dateObject.month,1])};DatePicker.prototype.validate=function(type,dateObject,options){var calendar=this,originalDateObject=dateObject,interval=options&&options.interval?options.interval:1,isFlippedBase=calendar.item.enable===-1,hasEnabledBeforeTarget,hasEnabledAfterTarget,minLimitObject=calendar.item.min,maxLimitObject=calendar.item.max,reachedMin,reachedMax,hasEnabledWeekdays=isFlippedBase&&calendar.item.disable.filter(function(value){if($.isArray(value)){var dateTime=calendar.create(value).pick;if(dateTime<dateObject.pick){hasEnabledBeforeTarget=true}else{if(dateTime>dateObject.pick){hasEnabledAfterTarget=true}}}return _.isInteger(value)}).length;if(!options||!options.nav){if((!isFlippedBase&&calendar.disabled(dateObject))||(isFlippedBase&&calendar.disabled(dateObject)&&(hasEnabledWeekdays||hasEnabledBeforeTarget||hasEnabledAfterTarget))||(!isFlippedBase&&(dateObject.pick<=minLimitObject.pick||dateObject.pick>=maxLimitObject.pick))){if(isFlippedBase&&!hasEnabledWeekdays&&((!hasEnabledAfterTarget&&interval>0)||(!hasEnabledBeforeTarget&&interval<0))){interval*=-1}while(calendar.disabled(dateObject)){if(Math.abs(interval)>1&&(dateObject.month<originalDateObject.month||dateObject.month>originalDateObject.month)){dateObject=originalDateObject;
7
+ interval=interval>0?1:-1}if(dateObject.pick<=minLimitObject.pick){reachedMin=true;interval=1;dateObject=calendar.create([minLimitObject.year,minLimitObject.month,minLimitObject.date+(dateObject.pick===minLimitObject.pick?0:-1)])}else{if(dateObject.pick>=maxLimitObject.pick){reachedMax=true;interval=-1;dateObject=calendar.create([maxLimitObject.year,maxLimitObject.month,maxLimitObject.date+(dateObject.pick===maxLimitObject.pick?0:1)])}}if(reachedMin&&reachedMax){break}dateObject=calendar.create([dateObject.year,dateObject.month,dateObject.date+interval])}}}return dateObject};DatePicker.prototype.disabled=function(dateToVerify){var calendar=this,isDisabledMatch=calendar.item.disable.filter(function(dateToDisable){if(_.isInteger(dateToDisable)){return dateToVerify.day===(calendar.settings.firstDay?dateToDisable:dateToDisable-1)%7}if($.isArray(dateToDisable)||_.isDate(dateToDisable)){return dateToVerify.pick===calendar.create(dateToDisable).pick}if($.isPlainObject(dateToDisable)){return calendar.withinRange(dateToDisable,dateToVerify)}});isDisabledMatch=isDisabledMatch.length&&!isDisabledMatch.filter(function(dateToDisable){return $.isArray(dateToDisable)&&dateToDisable[3]=="inverted"||$.isPlainObject(dateToDisable)&&dateToDisable.inverted}).length;return calendar.item.enable===-1?!isDisabledMatch:isDisabledMatch||dateToVerify.pick<calendar.item.min.pick||dateToVerify.pick>calendar.item.max.pick};DatePicker.prototype.parse=function(type,value,options){var calendar=this,parsingObject={};if(!value||typeof value!="string"){return value}if(!(options&&options.format)){options=options||{};options.format=calendar.settings.format}calendar.formats.toArray(options.format).map(function(label){var formattingLabel=calendar.formats[label],formatLength=formattingLabel?_.trigger(formattingLabel,calendar,[value,parsingObject]):label.replace(/^!/,"").length;if(formattingLabel){parsingObject[label]=value.substr(0,formatLength)}value=value.substr(formatLength)});return[parsingObject.yyyy||parsingObject.yy,+(parsingObject.mm||parsingObject.m)-1,parsingObject.dd||parsingObject.d]};DatePicker.prototype.formats=(function(){function getWordLengthFromCollection(string,collection,dateObject){var word=string.match(/\w+/)[0];if(!dateObject.mm&&!dateObject.m){dateObject.m=collection.indexOf(word)+1}return word.length}function getFirstWordLength(string){return string.match(/\w+/)[0].length}return{d:function(string,dateObject){return string?_.digits(string):dateObject.date},dd:function(string,dateObject){return string?2:_.lead(dateObject.date)},ddd:function(string,dateObject){return string?getFirstWordLength(string):this.settings.weekdaysShort[dateObject.day]},dddd:function(string,dateObject){return string?getFirstWordLength(string):this.settings.weekdaysFull[dateObject.day]},m:function(string,dateObject){return string?_.digits(string):dateObject.month+1},mm:function(string,dateObject){return string?2:_.lead(dateObject.month+1)},mmm:function(string,dateObject){var collection=this.settings.monthsShort;return string?getWordLengthFromCollection(string,collection,dateObject):collection[dateObject.month]},mmmm:function(string,dateObject){var collection=this.settings.monthsFull;return string?getWordLengthFromCollection(string,collection,dateObject):collection[dateObject.month]},yy:function(string,dateObject){return string?2:(""+dateObject.year).slice(2)},yyyy:function(string,dateObject){return string?4:dateObject.year},toArray:function(formatString){return formatString.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(formatString,itemObject){var calendar=this;return calendar.formats.toArray(formatString).map(function(label){return _.trigger(calendar.formats[label],calendar,[0,itemObject])||label.replace(/^!/,"")}).join("")}}})();DatePicker.prototype.isDateExact=function(one,two){var calendar=this;if((_.isInteger(one)&&_.isInteger(two))||(typeof one=="boolean"&&typeof two=="boolean")){return one===two}if((_.isDate(one)||$.isArray(one))&&(_.isDate(two)||$.isArray(two))){return calendar.create(one).pick===calendar.create(two).pick}if($.isPlainObject(one)&&$.isPlainObject(two)){return calendar.isDateExact(one.from,two.from)&&calendar.isDateExact(one.to,two.to)}return false};DatePicker.prototype.isDateOverlap=function(one,two){var calendar=this,firstDay=calendar.settings.firstDay?1:0;if(_.isInteger(one)&&(_.isDate(two)||$.isArray(two))){one=one%7+firstDay;return one===calendar.create(two).day+1}if(_.isInteger(two)&&(_.isDate(one)||$.isArray(one))){two=two%7+firstDay;return two===calendar.create(one).day+1}if($.isPlainObject(one)&&$.isPlainObject(two)){return calendar.overlapRanges(one,two)}return false};DatePicker.prototype.flipEnable=function(val){var itemObject=this.item;itemObject.enable=val||(itemObject.enable==-1?1:-1)};DatePicker.prototype.deactivate=function(type,datesToDisable){var calendar=this,disabledItems=calendar.item.disable.slice(0);if(datesToDisable=="flip"){calendar.flipEnable()}else{if(datesToDisable===false){calendar.flipEnable(1);
8
+ disabledItems=[]}else{if(datesToDisable===true){calendar.flipEnable(-1);disabledItems=[]}else{datesToDisable.map(function(unitToDisable){var matchFound;for(var index=0;index<disabledItems.length;index+=1){if(calendar.isDateExact(unitToDisable,disabledItems[index])){matchFound=true;break}}if(!matchFound){if(_.isInteger(unitToDisable)||_.isDate(unitToDisable)||$.isArray(unitToDisable)||($.isPlainObject(unitToDisable)&&unitToDisable.from&&unitToDisable.to)){disabledItems.push(unitToDisable)}}})}}}return disabledItems};DatePicker.prototype.activate=function(type,datesToEnable){var calendar=this,disabledItems=calendar.item.disable,disabledItemsCount=disabledItems.length;if(datesToEnable=="flip"){calendar.flipEnable()}else{if(datesToEnable===true){calendar.flipEnable(1);disabledItems=[]}else{if(datesToEnable===false){calendar.flipEnable(-1);disabledItems=[]}else{datesToEnable.map(function(unitToEnable){var matchFound,disabledUnit,index,isExactRange;for(index=0;index<disabledItemsCount;index+=1){disabledUnit=disabledItems[index];if(calendar.isDateExact(disabledUnit,unitToEnable)){matchFound=disabledItems[index]=null;isExactRange=true;break}else{if(calendar.isDateOverlap(disabledUnit,unitToEnable)){if($.isPlainObject(unitToEnable)){unitToEnable.inverted=true;matchFound=unitToEnable}else{if($.isArray(unitToEnable)){matchFound=unitToEnable;if(!matchFound[3]){matchFound.push("inverted")}}else{if(_.isDate(unitToEnable)){matchFound=[unitToEnable.getFullYear(),unitToEnable.getMonth(),unitToEnable.getDate(),"inverted"]}}}break}}}if(matchFound){for(index=0;index<disabledItemsCount;index+=1){if(calendar.isDateExact(disabledItems[index],unitToEnable)){disabledItems[index]=null;break}}}if(isExactRange){for(index=0;index<disabledItemsCount;index+=1){if(calendar.isDateOverlap(disabledItems[index],unitToEnable)){disabledItems[index]=null;break}}}if(matchFound){disabledItems.push(matchFound)}})}}}return disabledItems.filter(function(val){return val!=null})};DatePicker.prototype.nodes=function(isOpen){var calendar=this,settings=calendar.settings,calendarItem=calendar.item,nowObject=calendarItem.now,selectedObject=calendarItem.select,highlightedObject=calendarItem.highlight,viewsetObject=calendarItem.view,disabledCollection=calendarItem.disable,minLimitObject=calendarItem.min,maxLimitObject=calendarItem.max,tableHead=(function(collection,fullCollection){if(settings.firstDay){collection.push(collection.shift());fullCollection.push(fullCollection.shift())}return _.node("thead",_.node("tr",_.group({min:0,max:DAYS_IN_WEEK-1,i:1,node:"th",item:function(counter){return[collection[counter],settings.klass.weekdays,'scope=col title="'+fullCollection[counter]+'"']}})))})((settings.showWeekdaysFull?settings.weekdaysFull:settings.weekdaysLetter).slice(0),settings.weekdaysFull.slice(0)),createMonthNav=function(next){return _.node("div"," ",settings.klass["nav"+(next?"Next":"Prev")]+((next&&viewsetObject.year>=maxLimitObject.year&&viewsetObject.month>=maxLimitObject.month)||(!next&&viewsetObject.year<=minLimitObject.year&&viewsetObject.month<=minLimitObject.month)?" "+settings.klass.navDisabled:""),"data-nav="+(next||-1)+" "+_.ariaAttr({role:"button",controls:calendar.$node[0].id+"_table"})+" "+'title="'+(next?settings.labelMonthNext:settings.labelMonthPrev)+'"')},createMonthLabel=function(override){var monthsCollection=settings.showMonthsShort?settings.monthsShort:settings.monthsFull;if(override=="short_months"){monthsCollection=settings.monthsShort}if(settings.selectMonths&&override==undefined){return _.node("select",_.group({min:0,max:11,i:1,node:"option",item:function(loopedMonth){return[monthsCollection[loopedMonth],0,"value="+loopedMonth+(viewsetObject.month==loopedMonth?" selected":"")+(((viewsetObject.year==minLimitObject.year&&loopedMonth<minLimitObject.month)||(viewsetObject.year==maxLimitObject.year&&loopedMonth>maxLimitObject.month))?" disabled":"")]}}),settings.klass.selectMonth+" browser-default",(isOpen?"":"disabled")+" "+_.ariaAttr({controls:calendar.$node[0].id+"_table"})+" "+'title="'+settings.labelMonthSelect+'"')}if(override=="short_months"){if(selectedObject!=null){return _.node("div",monthsCollection[selectedObject.month])}else{return _.node("div",monthsCollection[viewsetObject.month])}}return _.node("div",monthsCollection[viewsetObject.month],settings.klass.month)},createYearLabel=function(override){var focusedYear=viewsetObject.year,numberYears=settings.selectYears===true?5:~~(settings.selectYears/2);if(numberYears){var minYear=minLimitObject.year,maxYear=maxLimitObject.year,lowestYear=focusedYear-numberYears,highestYear=focusedYear+numberYears;if(minYear>lowestYear){highestYear+=minYear-lowestYear;lowestYear=minYear}if(maxYear<highestYear){var availableYears=lowestYear-minYear,neededYears=highestYear-maxYear;lowestYear-=availableYears>neededYears?neededYears:availableYears;highestYear=maxYear}if(settings.selectYears&&override==undefined){return _.node("select",_.group({min:lowestYear,max:highestYear,i:1,node:"option",item:function(loopedYear){return[loopedYear,0,"value="+loopedYear+(focusedYear==loopedYear?" selected":"")]
9
+ }}),settings.klass.selectYear+" browser-default",(isOpen?"":"disabled")+" "+_.ariaAttr({controls:calendar.$node[0].id+"_table"})+" "+'title="'+settings.labelYearSelect+'"')}}if(override=="raw"){return _.node("div",focusedYear)}return _.node("div",focusedYear,settings.klass.year)};createDayLabel=function(){if(selectedObject!=null){return _.node("div",selectedObject.date)}else{return _.node("div",nowObject.date)}};createWeekdayLabel=function(){var display_day;if(selectedObject!=null){display_day=selectedObject.day}else{display_day=nowObject.day}var weekday=settings.weekdaysFull[display_day];return weekday};return _.node("div",_.node("div",createWeekdayLabel(),"picker__weekday-display")+_.node("div",createMonthLabel("short_months"),settings.klass.month_display)+_.node("div",createDayLabel(),settings.klass.day_display)+_.node("div",createYearLabel("raw"),settings.klass.year_display),settings.klass.date_display)+_.node("div",_.node("div",(settings.selectYears?createMonthLabel()+createYearLabel():createMonthLabel()+createYearLabel())+createMonthNav()+createMonthNav(1),settings.klass.header)+_.node("table",tableHead+_.node("tbody",_.group({min:0,max:WEEKS_IN_CALENDAR-1,i:1,node:"tr",item:function(rowCounter){var shiftDateBy=settings.firstDay&&calendar.create([viewsetObject.year,viewsetObject.month,1]).day===0?-7:0;return[_.group({min:DAYS_IN_WEEK*rowCounter-viewsetObject.day+shiftDateBy+1,max:function(){return this.min+DAYS_IN_WEEK-1},i:1,node:"td",item:function(targetDate){targetDate=calendar.create([viewsetObject.year,viewsetObject.month,targetDate+(settings.firstDay?1:0)]);var isSelected=selectedObject&&selectedObject.pick==targetDate.pick,isHighlighted=highlightedObject&&highlightedObject.pick==targetDate.pick,isDisabled=disabledCollection&&calendar.disabled(targetDate)||targetDate.pick<minLimitObject.pick||targetDate.pick>maxLimitObject.pick,formattedDate=_.trigger(calendar.formats.toString,calendar,[settings.format,targetDate]);return[_.node("div",targetDate.date,(function(klasses){klasses.push(viewsetObject.month==targetDate.month?settings.klass.infocus:settings.klass.outfocus);if(nowObject.pick==targetDate.pick){klasses.push(settings.klass.now)}if(isSelected){klasses.push(settings.klass.selected)}if(isHighlighted){klasses.push(settings.klass.highlighted)}if(isDisabled){klasses.push(settings.klass.disabled)}return klasses.join(" ")})([settings.klass.day]),"data-pick="+targetDate.pick+" "+_.ariaAttr({role:"gridcell",label:formattedDate,selected:isSelected&&calendar.$node.val()===formattedDate?true:null,activedescendant:isHighlighted?true:null,disabled:isDisabled?true:null})),"",_.ariaAttr({role:"presentation"})]}})]}})),settings.klass.table,'id="'+calendar.$node[0].id+"_table"+'" '+_.ariaAttr({role:"grid",controls:calendar.$node[0].id,readonly:true})),settings.klass.calendar_container)+_.node("div",_.node("button",settings.today,"mdui-btn picker__today","type=button data-pick="+nowObject.pick+(isOpen&&!calendar.disabled(nowObject)?"":" disabled")+" "+_.ariaAttr({controls:calendar.$node[0].id}))+_.node("button",settings.clear,"mdui-btn picker__clear","type=button data-clear=1"+(isOpen?"":" disabled")+" "+_.ariaAttr({controls:calendar.$node[0].id}))+_.node("button",settings.close,"mdui-btn picker__close","type=button data-close=true "+(isOpen?"":" disabled")+" "+_.ariaAttr({controls:calendar.$node[0].id})),settings.klass.footer)};DatePicker.defaults=(function(prefix){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],weekdaysLetter:["S","M","T","W","T","F","S"],today:"Today",clear:"Clear",close:"Close",format:"d mmmm, yyyy",klass:{table:prefix+"table",header:prefix+"header",date_display:prefix+"date-display",day_display:prefix+"day-display",month_display:prefix+"month-display",year_display:prefix+"year-display",calendar_container:prefix+"calendar-container",navPrev:prefix+"nav--prev",navNext:prefix+"nav--next",navDisabled:prefix+"nav--disabled",month:prefix+"month",year:prefix+"year",selectMonth:prefix+"select--month",selectYear:prefix+"select--year",weekdays:prefix+"weekday",day:prefix+"day",disabled:prefix+"day--disabled",selected:prefix+"day--selected",highlighted:prefix+"day--highlighted",now:prefix+"day--today",infocus:prefix+"day--infocus",outfocus:prefix+"day--outfocus",footer:prefix+"footer",buttonClear:prefix+"button--clear",buttonToday:prefix+"button--today",buttonClose:prefix+"button--close"}}})(Picker.klasses().picker+"__");Picker.extend("pickadate",DatePicker)}));