pickadate-rails 1.3.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ecab16b12a07768c82fb511574de65471ee0f84
4
- data.tar.gz: b58d663694fe7f0dbe57f0029e63d2f5502d1024
3
+ metadata.gz: b8bbf39c9f159feed3de69900df634b556e902ac
4
+ data.tar.gz: 44c4abfe39c4d8a63c0181b812cb0ff68a9e85a1
5
5
  SHA512:
6
- metadata.gz: 1cf838b0a21a732e6e812b91f9dd24cbb2027564ff33166e80f75f4b52628e7bbeaab7c7ae6e3b34fd5a999a5d63944711aca9b46f2bc0f75a52aa47bdb7571a
7
- data.tar.gz: 837f6c6e499d31bf216dc337b03b7f41ccb36c503e048a0d476939639fc18d48104226ad1668521f56bda52a6bf4a749fb414fcb1d87e86bd610a5d9767f28f7
6
+ metadata.gz: 7621c5f039ba977bfb838997b0e74902d7d7bbacaa6c0abddc7204cf25ed6d3bdd297969e5c0c53d9c6004c4ef8ca3e181b1139842aeb35a54f3f93ab5f8b3c9
7
+ data.tar.gz: 2661ae990c6fdaf3148aaabbd4916f0c69c9cfecf64c3ebe853e29ce022e953060fe1de27b3edae9c4b088a72d432f683c714545303fb5abf6bb141331eb68a1
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Pickadate-Rails [![Gem Version](https://badge.fury.io/rb/pickadate-rails.png)](http://badge.fury.io/rb/pickadate-rails)
2
2
 
3
- ## Pickadate Version: 3.3.2
3
+ ## Pickadate Version: 3.4.0
4
4
 
5
5
  Easily add [pickadate.js](https://github.com/amsul/pickadate.js) to your Rails 3.1+ application using the asset pipeline.
6
6
 
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ namespace :pickadate do
5
5
  task :download do
6
6
  require 'fileutils'
7
7
 
8
- system "curl https://github.com/amsul/pickadate.js/archive/gh-pages.zip -f -L -o tmp/pickadate.zip"
8
+ system "curl https://github.com/amsul/pickadate.js/archive/gh-pages.zip -f -L --create-dirs -o tmp/pickadate.zip"
9
9
  system "unzip tmp/pickadate.zip -d tmp/"
10
10
  system "rm tmp/pickadate.zip"
11
11
 
@@ -23,4 +23,4 @@ namespace :pickadate do
23
23
 
24
24
  system "rm -rf tmp/pickadate*"
25
25
  end
26
- end
26
+ end
@@ -1,3 +1,3 @@
1
1
  module PickadateRails
2
- VERSION = "1.3.2"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -1,22 +1,13 @@
1
1
 
2
2
  /*!
3
- * Date picker for pickadate.js v3.3.2
3
+ * Date picker for pickadate.js v3.4.0
4
4
  * http://amsul.github.io/pickadate.js/date.htm
5
5
  */
6
6
 
7
- /*jshint
8
- debug: true,
9
- devel: true,
10
- browser: true,
11
- asi: true,
12
- unused: true,
13
- boss: true
14
- */
15
-
16
7
  (function ( factory ) {
17
8
 
18
9
  // Register as an anonymous module.
19
- if ( typeof define === 'function' && define.amd )
10
+ if ( typeof define == 'function' && define.amd )
20
11
  define( ['picker','jquery'], factory )
21
12
 
22
13
  // Or using browser globals.
@@ -29,7 +20,8 @@
29
20
  * Globals and constants
30
21
  */
31
22
  var DAYS_IN_WEEK = 7,
32
- WEEKS_IN_CALENDAR = 6
23
+ WEEKS_IN_CALENDAR = 6,
24
+ _ = Picker._
33
25
 
34
26
 
35
27
 
@@ -48,6 +40,7 @@ function DatePicker( picker, settings ) {
48
40
  }
49
41
 
50
42
  calendar.settings = settings
43
+ calendar.$node = picker.$node
51
44
 
52
45
  // The queue of methods that will be used to build item objects.
53
46
  calendar.queue = {
@@ -55,10 +48,10 @@ function DatePicker( picker, settings ) {
55
48
  max: 'measure create',
56
49
  now: 'now create',
57
50
  select: 'parse create validate',
58
- highlight: 'navigate create validate',
59
- view: 'create validate viewset',
60
- disable: 'flipItem',
61
- enable: 'flipItem'
51
+ highlight: 'parse navigate create validate',
52
+ view: 'parse create validate viewset',
53
+ disable: 'deactivate',
54
+ enable: 'activate'
62
55
  }
63
56
 
64
57
  // The component's item object.
@@ -72,24 +65,23 @@ function DatePicker( picker, settings ) {
72
65
  calendar.
73
66
  set( 'min', settings.min ).
74
67
  set( 'max', settings.max ).
75
- set( 'now' ).
76
-
77
- // Setting the `select` also sets the `highlight` and `view`.
78
- set( 'select',
79
-
80
- // Use the value provided or default to selecting “today”.
81
- valueString || calendar.item.now,
82
- {
83
- // Use the appropriate format.
84
- format: formatString,
85
-
86
- // Set user-provided month data as true when there is a
87
- // “mm” or “m” used in the relative format string.
88
- data: (function( formatArray ) {
89
- return valueString && ( formatArray.indexOf( 'mm' ) > -1 || formatArray.indexOf( 'm' ) > -1 )
90
- })( calendar.formats.toArray( formatString ) )
91
- }
92
- )
68
+ set( 'now' )
69
+
70
+ // When there’s a value, set the `select`, which in turn
71
+ // also sets the `highlight` and `view`.
72
+ if ( valueString ) {
73
+ calendar.set( 'select', valueString, {
74
+ format: formatString,
75
+ fromValue: !!elementValue
76
+ })
77
+ }
78
+
79
+ // If there’s no value, default to highlighting “today”.
80
+ else {
81
+ calendar.
82
+ set( 'select', null ).
83
+ set( 'highlight', calendar.item.now )
84
+ }
93
85
 
94
86
 
95
87
  // The keycode to movement mapping.
@@ -99,7 +91,13 @@ function DatePicker( picker, settings ) {
99
91
  39: function() { return isRTL() ? -1 : 1 }, // Right
100
92
  37: function() { return isRTL() ? 1 : -1 }, // Left
101
93
  go: function( timeChange ) {
102
- calendar.set( 'highlight', [ calendar.item.highlight.year, calendar.item.highlight.month, calendar.item.highlight.date + timeChange ], { interval: timeChange } )
94
+ var highlightedObject = calendar.item.highlight,
95
+ targetDate = new Date( highlightedObject.year, highlightedObject.month, highlightedObject.date + timeChange )
96
+ calendar.set(
97
+ 'highlight',
98
+ [ targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate() ],
99
+ { interval: timeChange }
100
+ )
103
101
  this.render()
104
102
  }
105
103
  }
@@ -109,12 +107,18 @@ function DatePicker( picker, settings ) {
109
107
  picker.
110
108
  on( 'render', function() {
111
109
  picker.$root.find( '.' + settings.klass.selectMonth ).on( 'change', function() {
112
- picker.set( 'highlight', [ picker.get( 'view' ).year, this.value, picker.get( 'highlight' ).date ] )
113
- picker.$root.find( '.' + settings.klass.selectMonth ).trigger( 'focus' )
110
+ var value = this.value
111
+ if ( value ) {
112
+ picker.set( 'highlight', [ picker.get( 'view' ).year, value, picker.get( 'highlight' ).date ] )
113
+ picker.$root.find( '.' + settings.klass.selectMonth ).trigger( 'focus' )
114
+ }
114
115
  })
115
116
  picker.$root.find( '.' + settings.klass.selectYear ).on( 'change', function() {
116
- picker.set( 'highlight', [ this.value, picker.get( 'view' ).month, picker.get( 'highlight' ).date ] )
117
- picker.$root.find( '.' + settings.klass.selectYear ).trigger( 'focus' )
117
+ var value = this.value
118
+ if ( value ) {
119
+ picker.set( 'highlight', [ value, picker.get( 'view' ).month, picker.get( 'highlight' ).date ] )
120
+ picker.$root.find( '.' + settings.klass.selectYear ).trigger( 'focus' )
121
+ }
118
122
  })
119
123
  }).
120
124
  on( 'open', function() {
@@ -132,27 +136,38 @@ function DatePicker( picker, settings ) {
132
136
  */
133
137
  DatePicker.prototype.set = function( type, value, options ) {
134
138
 
135
- var calendar = this
139
+ var calendar = this,
140
+ calendarItem = calendar.item
141
+
142
+ // If the value is `null` just set it immediately.
143
+ if ( value === null ) {
144
+ calendarItem[ type ] = value
145
+ return calendar
146
+ }
136
147
 
137
- // Go through the queue of methods, and invoke the function. Update this
138
- // as the time unit, and set the final resultant as this item type.
148
+ // Otherwise go through the queue of methods, and invoke the functions.
149
+ // Update this as the time unit, and set the final value as this item.
139
150
  // * In the case of `enable`, keep the queue but set `disable` instead.
140
151
  // And in the case of `flip`, keep the queue but set `enable` instead.
141
- calendar.item[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = calendar.queue[ type ].split( ' ' ).map( function( method ) {
142
- return value = calendar[ method ]( type, value, options )
152
+ calendarItem[ ( type == 'enable' ? 'disable' : type == 'flip' ? 'enable' : type ) ] = calendar.queue[ type ].split( ' ' ).map( function( method ) {
153
+ value = calendar[ method ]( type, value, options )
154
+ return value
143
155
  }).pop()
144
156
 
145
157
  // Check if we need to cascade through more updates.
146
158
  if ( type == 'select' ) {
147
- calendar.set( 'highlight', calendar.item.select, options )
159
+ calendar.set( 'highlight', calendarItem.select, options )
148
160
  }
149
161
  else if ( type == 'highlight' ) {
150
- calendar.set( 'view', calendar.item.highlight, options )
162
+ calendar.set( 'view', calendarItem.highlight, options )
151
163
  }
152
- else if ( ( type == 'flip' || type == 'min' || type == 'max' || type == 'disable' || type == 'enable' ) && calendar.item.select && calendar.item.highlight ) {
153
- calendar.
154
- set( 'select', calendar.item.select, options ).
155
- set( 'highlight', calendar.item.highlight, options )
164
+ else if ( type.match( /^(flip|min|max|disable|enable)$/ ) ) {
165
+ if ( calendarItem.select && calendar.disabled( calendarItem.select ) ) {
166
+ calendar.set( 'select', calendarItem.select, options )
167
+ }
168
+ if ( calendarItem.highlight && calendar.disabled( calendarItem.highlight ) ) {
169
+ calendar.set( 'highlight', calendarItem.highlight, options )
170
+ }
156
171
  }
157
172
 
158
173
  return calendar
@@ -185,7 +200,7 @@ DatePicker.prototype.create = function( type, value, options ) {
185
200
  }
186
201
 
187
202
  // If it’s an object, use the native date object.
188
- else if ( $.isPlainObject( value ) && Picker._.isInteger( value.pick ) ) {
203
+ else if ( $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
189
204
  value = value.obj
190
205
  }
191
206
 
@@ -193,11 +208,11 @@ DatePicker.prototype.create = function( type, value, options ) {
193
208
  // that it’s a valid date – otherwise default to today.
194
209
  else if ( $.isArray( value ) ) {
195
210
  value = new Date( value[ 0 ], value[ 1 ], value[ 2 ] )
196
- value = Picker._.isDate( value ) ? value : calendar.create().obj
211
+ value = _.isDate( value ) ? value : calendar.create().obj
197
212
  }
198
213
 
199
214
  // If it’s a number or date object, make a normalized date.
200
- else if ( Picker._.isInteger( value ) || Picker._.isDate( value ) ) {
215
+ else if ( _.isInteger( value ) || _.isDate( value ) ) {
201
216
  value = calendar.normalize( new Date( value ), options )
202
217
  }
203
218
 
@@ -218,6 +233,68 @@ DatePicker.prototype.create = function( type, value, options ) {
218
233
  } //DatePicker.prototype.create
219
234
 
220
235
 
236
+ /**
237
+ * Create a range limit object using an array, date object,
238
+ * literal “true”, or integer relative to another time.
239
+ */
240
+ DatePicker.prototype.createRange = function( from, to ) {
241
+
242
+ var calendar = this,
243
+ createDate = function( date ) {
244
+ if ( date === true || $.isArray( date ) || _.isDate( date ) ) {
245
+ return calendar.create( date )
246
+ }
247
+ return date
248
+ }
249
+
250
+ // Create objects if possible.
251
+ if ( !_.isInteger( from ) ) {
252
+ from = createDate( from )
253
+ }
254
+ if ( !_.isInteger( to ) ) {
255
+ to = createDate( to )
256
+ }
257
+
258
+ // Create relative dates.
259
+ if ( _.isInteger( from ) && $.isPlainObject( to ) ) {
260
+ from = [ to.year, to.month, to.date + from ];
261
+ }
262
+ else if ( _.isInteger( to ) && $.isPlainObject( from ) ) {
263
+ to = [ from.year, from.month, from.date + to ];
264
+ }
265
+
266
+ return {
267
+ from: createDate( from ),
268
+ to: createDate( to )
269
+ }
270
+ } //DatePicker.prototype.createRange
271
+
272
+
273
+ /**
274
+ * Check if a date unit falls within a date range object.
275
+ */
276
+ DatePicker.prototype.withinRange = function( range, dateUnit ) {
277
+ range = this.createRange(range.from, range.to)
278
+ return dateUnit.pick >= range.from.pick && dateUnit.pick <= range.to.pick
279
+ }
280
+
281
+
282
+ /**
283
+ * Check if two date range objects overlap.
284
+ */
285
+ DatePicker.prototype.overlapRanges = function( one, two ) {
286
+
287
+ var calendar = this
288
+
289
+ // Convert the ranges into comparable dates.
290
+ one = calendar.createRange( one.from, one.to )
291
+ two = calendar.createRange( two.from, two.to )
292
+
293
+ return calendar.withinRange( one, two.from ) || calendar.withinRange( one, two.to ) ||
294
+ calendar.withinRange( two, one.from ) || calendar.withinRange( two, one.to )
295
+ }
296
+
297
+
221
298
  /**
222
299
  * Get the date today.
223
300
  */
@@ -227,7 +304,7 @@ DatePicker.prototype.now = function( type, value, options ) {
227
304
  value.setDate( value.getDate() + options.rel )
228
305
  }
229
306
  return this.normalize( value, options )
230
- } //DatePicker.prototype.now
307
+ }
231
308
 
232
309
 
233
310
  /**
@@ -235,20 +312,52 @@ DatePicker.prototype.now = function( type, value, options ) {
235
312
  */
236
313
  DatePicker.prototype.navigate = function( type, value, options ) {
237
314
 
238
- if ( $.isPlainObject( value ) ) {
315
+ var targetDateObject,
316
+ targetYear,
317
+ targetMonth,
318
+ targetDate,
319
+ isTargetArray = $.isArray( value ),
320
+ isTargetObject = $.isPlainObject( value ),
321
+ viewsetObject = this.item.view/*,
322
+ safety = 100*/
239
323
 
240
- var targetDateObject = new Date( value.year, value.month + ( options && options.nav ? options.nav : 0 ), 1 ),
241
- year = targetDateObject.getFullYear(),
242
- month = targetDateObject.getMonth(),
243
- date = value.date
244
324
 
245
- // Make sure the date is valid and if the month we’re going to doesn’t have enough
246
- // days, keep decreasing the date until we reach the month’s last date.
247
- while ( Picker._.isDate( targetDateObject ) && new Date( year, month, date ).getMonth() !== month ) {
248
- date -= 1
325
+ if ( isTargetArray || isTargetObject ) {
326
+
327
+ if ( isTargetObject ) {
328
+ targetYear = value.year
329
+ targetMonth = value.month
330
+ targetDate = value.date
331
+ }
332
+ else {
333
+ targetYear = +value[0]
334
+ targetMonth = +value[1]
335
+ targetDate = +value[2]
336
+ }
337
+
338
+ // If we’re navigating months but the view is in a different
339
+ // month, navigate to the view’s year and month.
340
+ if ( options && options.nav && viewsetObject && viewsetObject.month !== targetMonth ) {
341
+ targetYear = viewsetObject.year
342
+ targetMonth = viewsetObject.month
249
343
  }
250
344
 
251
- value = [ year, month, date ]
345
+ // Figure out the expected target year and month.
346
+ targetDateObject = new Date( targetYear, targetMonth + ( options && options.nav ? options.nav : 0 ), 1 )
347
+ targetYear = targetDateObject.getFullYear()
348
+ targetMonth = targetDateObject.getMonth()
349
+
350
+ // If the month we’re going to doesn’t have enough days,
351
+ // keep decreasing the date until we reach the month’s last date.
352
+ while ( /*safety &&*/ new Date( targetYear, targetMonth, targetDate ).getMonth() !== targetMonth ) {
353
+ targetDate -= 1
354
+ /*safety -= 1
355
+ if ( !safety ) {
356
+ throw 'Fell into an infinite loop while navigating to ' + new Date( targetYear, targetMonth, targetDate ) + '.'
357
+ }*/
358
+ }
359
+
360
+ value = [ targetYear, targetMonth, targetDate ]
252
361
  }
253
362
 
254
363
  return value
@@ -277,7 +386,7 @@ DatePicker.prototype.measure = function( type, value/*, options*/ ) {
277
386
  }
278
387
 
279
388
  // If it's an integer, get a date relative to today.
280
- else if ( Picker._.isInteger( value ) ) {
389
+ else if ( _.isInteger( value ) ) {
281
390
  value = calendar.now( type, value, { rel: value } )
282
391
  }
283
392
 
@@ -330,25 +439,27 @@ DatePicker.prototype.validate = function( type, dateObject, options ) {
330
439
  }
331
440
 
332
441
  // Return only integers for enabled weekdays.
333
- return Picker._.isInteger( value )
334
- }).length
442
+ return _.isInteger( value )
443
+ }).length/*,
444
+
445
+ safety = 100*/
335
446
 
336
447
 
337
448
 
338
449
  // Cases to validate for:
339
450
  // [1] Not inverted and date disabled.
340
451
  // [2] Inverted and some dates enabled.
341
- // [3] Out of range.
452
+ // [3] Not inverted and out of range.
342
453
  //
343
454
  // Cases to **not** validate for:
344
455
  // • Navigating months.
345
456
  // • Not inverted and date enabled.
346
457
  // • Inverted and all dates disabled.
347
458
  // • ..and anything else.
348
- if ( !options.nav ) if (
459
+ if ( !options || !options.nav ) if (
349
460
  /* 1 */ ( !isFlippedBase && calendar.disabled( dateObject ) ) ||
350
461
  /* 2 */ ( isFlippedBase && calendar.disabled( dateObject ) && ( hasEnabledWeekdays || hasEnabledBeforeTarget || hasEnabledAfterTarget ) ) ||
351
- /* 3 */ ( dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick )
462
+ /* 3 */ ( !isFlippedBase && (dateObject.pick <= minLimitObject.pick || dateObject.pick >= maxLimitObject.pick) )
352
463
  ) {
353
464
 
354
465
 
@@ -360,24 +471,31 @@ DatePicker.prototype.validate = function( type, dateObject, options ) {
360
471
 
361
472
 
362
473
  // Keep looping until we reach an enabled date.
363
- while ( calendar.disabled( dateObject ) ) {
474
+ while ( /*safety &&*/ calendar.disabled( dateObject ) ) {
364
475
 
476
+ /*safety -= 1
477
+ if ( !safety ) {
478
+ throw 'Fell into an infinite loop while validating ' + dateObject.obj + '.'
479
+ }*/
365
480
 
366
- // If we’ve looped into the next/prev month, return to the original date and flatten the interval.
481
+
482
+ // If we’ve looped into the next/prev month with a large interval, return to the original date and flatten the interval.
367
483
  if ( Math.abs( interval ) > 1 && ( dateObject.month < originalDateObject.month || dateObject.month > originalDateObject.month ) ) {
368
484
  dateObject = originalDateObject
369
- interval = Math.abs( interval ) / interval
485
+ interval = interval > 0 ? 1 : -1
370
486
  }
371
487
 
372
488
 
373
- // If we’ve reached the min/max limit, reverse the direction and flatten the interval.
489
+ // If we’ve reached the min/max limit, reverse the direction, flatten the interval and set it to the limit.
374
490
  if ( dateObject.pick <= minLimitObject.pick ) {
375
491
  reachedMin = true
376
492
  interval = 1
493
+ dateObject = calendar.create([ minLimitObject.year, minLimitObject.month, minLimitObject.date - 1 ])
377
494
  }
378
495
  else if ( dateObject.pick >= maxLimitObject.pick ) {
379
496
  reachedMax = true
380
497
  interval = -1
498
+ dateObject = calendar.create([ maxLimitObject.year, maxLimitObject.month, maxLimitObject.date + 1 ])
381
499
  }
382
500
 
383
501
 
@@ -402,34 +520,41 @@ DatePicker.prototype.validate = function( type, dateObject, options ) {
402
520
  /**
403
521
  * Check if a date is disabled.
404
522
  */
405
- DatePicker.prototype.disabled = function( dateObject ) {
523
+ DatePicker.prototype.disabled = function( dateToVerify ) {
406
524
 
407
- var calendar = this,
525
+ var
526
+ calendar = this,
408
527
 
409
528
  // Filter through the disabled dates to check if this is one.
410
529
  isDisabledMatch = calendar.item.disable.filter( function( dateToDisable ) {
411
530
 
412
531
  // If the date is a number, match the weekday with 0index and `firstDay` check.
413
- if ( Picker._.isInteger( dateToDisable ) ) {
414
- return dateObject.day === ( calendar.settings.firstDay ? dateToDisable : dateToDisable - 1 ) % 7
532
+ if ( _.isInteger( dateToDisable ) ) {
533
+ return dateToVerify.day === ( calendar.settings.firstDay ? dateToDisable : dateToDisable - 1 ) % 7
415
534
  }
416
535
 
417
536
  // If it’s an array or a native JS date, create and match the exact date.
418
- if ( $.isArray( dateToDisable ) || Picker._.isDate( dateToDisable ) ) {
419
- return dateObject.pick === calendar.create( dateToDisable ).pick
537
+ if ( $.isArray( dateToDisable ) || _.isDate( dateToDisable ) ) {
538
+ return dateToVerify.pick === calendar.create( dateToDisable ).pick
539
+ }
540
+
541
+ // If it’s an object, match a date within the “from” and “to” range.
542
+ if ( $.isPlainObject( dateToDisable ) ) {
543
+ return calendar.withinRange( dateToDisable, dateToVerify )
420
544
  }
421
545
  })
422
546
 
423
547
  // If this date matches a disabled date, confirm it’s not inverted.
424
548
  isDisabledMatch = isDisabledMatch.length && !isDisabledMatch.filter(function( dateToDisable ) {
425
- return $.isArray( dateToDisable ) && dateToDisable[3] == 'inverted'
549
+ return $.isArray( dateToDisable ) && dateToDisable[3] == 'inverted' ||
550
+ $.isPlainObject( dateToDisable ) && dateToDisable.inverted
426
551
  }).length
427
552
 
428
553
  // Check the calendar “enabled” flag and respectively flip the
429
554
  // disabled state. Then also check if it’s beyond the min/max limits.
430
555
  return calendar.item.enable === -1 ? !isDisabledMatch : isDisabledMatch ||
431
- dateObject.pick < calendar.item.min.pick ||
432
- dateObject.pick > calendar.item.max.pick
556
+ dateToVerify.pick < calendar.item.min.pick ||
557
+ dateToVerify.pick > calendar.item.max.pick
433
558
 
434
559
  } //DatePicker.prototype.disabled
435
560
 
@@ -440,18 +565,22 @@ DatePicker.prototype.disabled = function( dateObject ) {
440
565
  DatePicker.prototype.parse = function( type, value, options ) {
441
566
 
442
567
  var calendar = this,
443
- parsingObject = {}
568
+ parsingObject = {},
569
+ monthIndex
444
570
 
445
- if ( !value || Picker._.isInteger( value ) || $.isArray( value ) || Picker._.isDate( value ) || $.isPlainObject( value ) && Picker._.isInteger( value.pick ) ) {
571
+ if ( !value || _.isInteger( value ) || $.isArray( value ) || _.isDate( value ) || $.isPlainObject( value ) && _.isInteger( value.pick ) ) {
446
572
  return value
447
573
  }
448
574
 
449
- // We need a `.format` to parse the value.
575
+ // We need a `.format` to parse the value with.
450
576
  if ( !( options && options.format ) ) {
451
- // should probably default to the default format.
452
- throw "Need a formatting option to parse this.."
577
+ options = options || {}
578
+ options.format = calendar.settings.format
453
579
  }
454
580
 
581
+ // Calculate the month index to adjust with.
582
+ monthIndex = typeof value == 'string' && !options.fromValue ? 1 : 0
583
+
455
584
  // Convert the format into an array and then map through it.
456
585
  calendar.formats.toArray( options.format ).map( function( label ) {
457
586
 
@@ -461,7 +590,7 @@ DatePicker.prototype.parse = function( type, value, options ) {
461
590
 
462
591
  // The format length is from the formatting label function or the
463
592
  // label length without the escaping exclamation (!) mark.
464
- formatLength = formattingLabel ? Picker._.trigger( formattingLabel, calendar, [ value, parsingObject ] ) : label.replace( /^!/, '' ).length
593
+ formatLength = formattingLabel ? _.trigger( formattingLabel, calendar, [ value, parsingObject ] ) : label.replace( /^!/, '' ).length
465
594
 
466
595
  // If there's a format label, split the value up to the format length.
467
596
  // Then add it to the parsing object with appropriate label.
@@ -474,7 +603,11 @@ DatePicker.prototype.parse = function( type, value, options ) {
474
603
  })
475
604
 
476
605
  // If it’s parsing a user provided month value, compensate for month 0index.
477
- return [ parsingObject.yyyy || parsingObject.yy, +( parsingObject.mm || parsingObject.m ) - ( options.data ? 1 : 0 ), parsingObject.dd || parsingObject.d ]
606
+ return [
607
+ parsingObject.yyyy || parsingObject.yy,
608
+ +( parsingObject.mm || parsingObject.m ) - monthIndex,
609
+ parsingObject.dd || parsingObject.d
610
+ ]
478
611
  } //DatePicker.prototype.parse
479
612
 
480
613
 
@@ -509,13 +642,13 @@ DatePicker.prototype.formats = (function() {
509
642
 
510
643
  // If there's string, then get the digits length.
511
644
  // Otherwise return the selected date.
512
- return string ? Picker._.digits( string ) : dateObject.date
645
+ return string ? _.digits( string ) : dateObject.date
513
646
  },
514
647
  dd: function( string, dateObject ) {
515
648
 
516
649
  // If there's a string, then the length is always 2.
517
650
  // Otherwise return the selected date with a leading zero.
518
- return string ? 2 : Picker._.lead( dateObject.date )
651
+ return string ? 2 : _.lead( dateObject.date )
519
652
  },
520
653
  ddd: function( string, dateObject ) {
521
654
 
@@ -533,13 +666,13 @@ DatePicker.prototype.formats = (function() {
533
666
 
534
667
  // If there's a string, then get the length of the digits
535
668
  // Otherwise return the selected month with 0index compensation.
536
- return string ? Picker._.digits( string ) : dateObject.month + 1
669
+ return string ? _.digits( string ) : dateObject.month + 1
537
670
  },
538
671
  mm: function( string, dateObject ) {
539
672
 
540
673
  // If there's a string, then the length is always 2.
541
674
  // Otherwise return the selected month with 0index and leading zero.
542
- return string ? 2 : Picker._.lead( dateObject.month + 1 )
675
+ return string ? 2 : _.lead( dateObject.month + 1 )
543
676
  },
544
677
  mmm: function( string, dateObject ) {
545
678
 
@@ -577,164 +710,229 @@ DatePicker.prototype.formats = (function() {
577
710
  toString: function ( formatString, itemObject ) {
578
711
  var calendar = this
579
712
  return calendar.formats.toArray( formatString ).map( function( label ) {
580
- return Picker._.trigger( calendar.formats[ label ], calendar, [ 0, itemObject ] ) || label.replace( /^!/, '' )
713
+ return _.trigger( calendar.formats[ label ], calendar, [ 0, itemObject ] ) || label.replace( /^!/, '' )
581
714
  }).join( '' )
582
715
  }
583
716
  }
584
717
  })() //DatePicker.prototype.formats
585
718
 
586
719
 
720
+
721
+
587
722
  /**
588
- * Flip an item as enabled or disabled.
723
+ * Check if two date units are the exact.
589
724
  */
590
- DatePicker.prototype.flipItem = function( type, value/*, options*/ ) {
591
-
592
- var calendar = this,
593
- collection = calendar.item.disable,
594
- isFlippedBase = calendar.item.enable === -1
725
+ DatePicker.prototype.isDateExact = function( one, two ) {
595
726
 
596
- // Flip the enabled and disabled dates.
597
- if ( value == 'flip' ) {
598
- calendar.item.enable = isFlippedBase ? 1 : -1
599
- }
727
+ var calendar = this
600
728
 
601
- // Reset the collection and enable the base state.
602
- else if ( ( type == 'enable' && value === true ) || ( type == 'disable' && value === false ) ) {
603
- calendar.item.enable = 1
604
- collection = []
729
+ // When we’re working with weekdays, do a direct comparison.
730
+ if (
731
+ ( _.isInteger( one ) && _.isInteger( two ) ) ||
732
+ ( typeof one == 'boolean' && typeof two == 'boolean' )
733
+ ) {
734
+ return one === two
605
735
  }
606
736
 
607
- // Reset the collection and disable the base state.
608
- else if ( ( type == 'enable' && value === false ) || ( type == 'disable' && value === true ) ) {
609
- calendar.item.enable = -1
610
- collection = []
737
+ // When we’re working with date representations, compare the “pick” value.
738
+ if (
739
+ ( _.isDate( one ) || $.isArray( one ) ) &&
740
+ ( _.isDate( two ) || $.isArray( two ) )
741
+ ) {
742
+ return calendar.create( one ).pick === calendar.create( two ).pick
611
743
  }
612
744
 
613
- // Make sure a collection of things was passed to add/remove.
614
- else if ( $.isArray( value ) ) {
615
-
616
- // Check if we have to add/remove from collection.
617
- if ( isFlippedBase && type == 'enable' || !isFlippedBase && type == 'disable' ) {
618
- collection = calendar.addDisabled( collection, value )
619
- }
620
- else if ( !isFlippedBase && type == 'enable' ) {
621
- collection = calendar.addEnabled( collection, value )
622
- }
623
- else if ( isFlippedBase && type == 'disable' ) {
624
- collection = calendar.removeDisabled( collection, value )
625
- }
745
+ // When we’re working with range objects, compare the “from” and “to”.
746
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
747
+ return calendar.isDateExact( one.from, two.from ) && calendar.isDateExact( one.to, two.to )
626
748
  }
627
749
 
628
- return collection
629
- } //DatePicker.prototype.flipItem
750
+ return false
751
+ }
630
752
 
631
753
 
632
754
  /**
633
- * Add an enabled (inverted) item to the disabled collection.
755
+ * Check if two date units overlap.
634
756
  */
635
- DatePicker.prototype.addEnabled = function( collection, item ) {
757
+ DatePicker.prototype.isDateOverlap = function( one, two ) {
636
758
 
637
759
  var calendar = this
638
760
 
639
- // Go through each item to enable.
640
- item.map( function( timeUnit ) {
641
-
642
- // Check if the time unit is already within the collection.
643
- if ( calendar.filterDisabled( collection, timeUnit, 1 ).length ) {
644
-
645
- // Remove the unit directly from the collection.
646
- collection = calendar.removeDisabled( collection, [timeUnit] )
647
-
648
- // If the unit is an array and it falls within a
649
- // disabled weekday, invert it and then insert it.
650
- if (
651
- $.isArray( timeUnit ) &&
652
- collection.filter( function( disabledDate ) {
653
- return Picker._.isInteger( disabledDate ) && calendar.create( timeUnit ).day === disabledDate - 1
654
- }).length
655
- ) {
656
- timeUnit = timeUnit.slice(0)
657
- timeUnit.push( 'inverted' )
658
- collection.push( timeUnit )
659
- }
660
- }
661
- })
761
+ // When we’re working with a weekday index, compare the days.
762
+ if ( _.isInteger( one ) && ( _.isDate( two ) || $.isArray( two ) ) ) {
763
+ return one === calendar.create( two ).day + 1
764
+ }
765
+ if ( _.isInteger( two ) && ( _.isDate( one ) || $.isArray( one ) ) ) {
766
+ return two === calendar.create( one ).day + 1
767
+ }
662
768
 
663
- // Return the final collection.
664
- return collection
665
- } //DatePicker.prototype.addEnabled
769
+ // When we’re working with range objects, check if the ranges overlap.
770
+ if ( $.isPlainObject( one ) && $.isPlainObject( two ) ) {
771
+ return calendar.overlapRanges( one, two )
772
+ }
773
+
774
+ return false
775
+ }
666
776
 
667
777
 
668
778
  /**
669
- * Add an item to the disabled collection.
779
+ * Flip the “enabled” state.
670
780
  */
671
- DatePicker.prototype.addDisabled = function( collection, item ) {
781
+ DatePicker.prototype.flipEnable = function(val) {
782
+ var itemObject = this.item
783
+ itemObject.enable = val || (itemObject.enable == -1 ? 1 : -1)
784
+ }
672
785
 
673
- var calendar = this
674
786
 
675
- // Go through each item to disable.
676
- item.map( function( timeUnit ) {
787
+ /**
788
+ * Mark a collection of dates as “disabled”.
789
+ */
790
+ DatePicker.prototype.deactivate = function( type, datesToDisable ) {
791
+
792
+ var calendar = this,
793
+ disabledItems = calendar.item.disable.slice(0)
677
794
 
678
- // Add the time unit if it isn’t already within the collection.
679
- if ( !calendar.filterDisabled( collection, timeUnit ).length ) {
680
- collection.push( timeUnit )
681
- }
682
795
 
683
- // If the time unit is an array and falls within the range, just remove it.
684
- else if ( $.isArray( timeUnit ) && calendar.filterDisabled( collection, timeUnit, 1 ).length ) {
685
- collection = calendar.removeDisabled( collection, [timeUnit] )
686
- }
687
- })
796
+ // If we’re flipping, that’s all we need to do.
797
+ if ( datesToDisable == 'flip' ) {
798
+ calendar.flipEnable()
799
+ }
688
800
 
689
- // Return the final collection.
690
- return collection
691
- } //DatePicker.prototype.addDisabled
801
+ else if ( datesToDisable === false ) {
802
+ calendar.flipEnable(1)
803
+ disabledItems = []
804
+ }
692
805
 
806
+ else if ( datesToDisable === true ) {
807
+ calendar.flipEnable(-1)
808
+ disabledItems = []
809
+ }
693
810
 
694
- /**
695
- * Remove an item from the disabled collection.
696
- */
697
- DatePicker.prototype.removeDisabled = function( collection, item ) {
811
+ // Otherwise go through the dates to disable.
812
+ else {
698
813
 
699
- var calendar = this
814
+ datesToDisable.map(function( unitToDisable ) {
700
815
 
701
- // Go through each item to enable.
702
- item.map( function( timeUnit ) {
816
+ var matchFound
703
817
 
704
- // Filter each item out of the collection.
705
- collection = calendar.filterDisabled( collection, timeUnit, 1 )
706
- })
818
+ // When we have disabled items, check for matches.
819
+ // If something is matched, immediately break out.
820
+ for ( var index = 0; index < disabledItems.length; index += 1 ) {
821
+ if ( calendar.isDateExact( unitToDisable, disabledItems[index] ) ) {
822
+ matchFound = true
823
+ break
824
+ }
825
+ }
707
826
 
708
- // Return the final colleciton.
709
- return collection
710
- } //DatePicker.prototype.removeDisabled
827
+ // If nothing was found, add the validated unit to the collection.
828
+ if ( !matchFound ) {
829
+ if (
830
+ _.isInteger( unitToDisable ) ||
831
+ _.isDate( unitToDisable ) ||
832
+ $.isArray( unitToDisable ) ||
833
+ ( $.isPlainObject( unitToDisable ) && unitToDisable.from && unitToDisable.to )
834
+ ) {
835
+ disabledItems.push( unitToDisable )
836
+ }
837
+ }
838
+ })
839
+ }
840
+
841
+ // Return the updated collection.
842
+ return disabledItems
843
+ } //DatePicker.prototype.deactivate
711
844
 
712
845
 
713
846
  /**
714
- * Filter through the disabled collection to find a time unit.
847
+ * Mark a collection of dates as “enabled”.
715
848
  */
716
- DatePicker.prototype.filterDisabled = function( collection, timeUnit, isRemoving ) {
849
+ DatePicker.prototype.activate = function( type, datesToEnable ) {
717
850
 
718
851
  var calendar = this,
852
+ disabledItems = calendar.item.disable,
853
+ disabledItemsCount = disabledItems.length
719
854
 
720
- // Check if the time unit passed is an array or date object.
721
- timeIsObject = $.isArray( timeUnit ) || Picker._.isDate( timeUnit ),
855
+ // If we’re flipping, that’s all we need to do.
856
+ if ( datesToEnable == 'flip' ) {
857
+ calendar.flipEnable()
858
+ }
722
859
 
723
- // Grab the comparison value if it’s an object.
724
- timeObjectValue = timeIsObject && calendar.create( timeUnit ).pick
860
+ else if ( datesToEnable === true ) {
861
+ calendar.flipEnable(1)
862
+ disabledItems = []
863
+ }
725
864
 
726
- // Go through the disabled collection and try to match this time unit.
727
- return collection.filter( function( disabledTimeUnit ) {
865
+ else if ( datesToEnable === false ) {
866
+ calendar.flipEnable(-1)
867
+ disabledItems = []
868
+ }
728
869
 
729
- // Check if it’s an object and the collection item is an object,
730
- // use the comparison values. Otherwise to a direct comparison.
731
- var isMatch = timeIsObject && ( $.isArray( disabledTimeUnit ) || Picker._.isDate( disabledTimeUnit ) ) ?
732
- timeObjectValue === calendar.create( disabledTimeUnit ).pick : timeUnit === disabledTimeUnit
870
+ // Otherwise go through the disabled dates.
871
+ else {
733
872
 
734
- // Invert the match if we’re removing from the collection.
735
- return isRemoving ? !isMatch : isMatch
736
- })
737
- } //DatePicker.prototype.filterDisabled
873
+ datesToEnable.map(function( unitToEnable ) {
874
+
875
+ var matchFound,
876
+ disabledUnit,
877
+ index,
878
+ isExactRange
879
+
880
+ // Go through the disabled items and try to find a match.
881
+ for ( index = 0; index < disabledItemsCount; index += 1 ) {
882
+
883
+ disabledUnit = disabledItems[index]
884
+
885
+ // When an exact match is found, remove it from the collection.
886
+ if ( calendar.isDateExact( disabledUnit, unitToEnable ) ) {
887
+ matchFound = disabledItems[index] = null
888
+ isExactRange = true
889
+ break
890
+ }
891
+
892
+ // When an overlapped match is found, add the “inverted” state to it.
893
+ else if ( calendar.isDateOverlap( disabledUnit, unitToEnable ) ) {
894
+ if ( $.isPlainObject( unitToEnable ) ) {
895
+ unitToEnable.inverted = true
896
+ matchFound = unitToEnable
897
+ }
898
+ else if ( $.isArray( unitToEnable ) ) {
899
+ matchFound = unitToEnable
900
+ if ( !matchFound[3] ) matchFound.push( 'inverted' )
901
+ }
902
+ else if ( _.isDate( unitToEnable ) ) {
903
+ matchFound = [ unitToEnable.getFullYear(), unitToEnable.getMonth(), unitToEnable.getDate(), 'inverted' ]
904
+ }
905
+ break
906
+ }
907
+ }
908
+
909
+ // If a match was found, remove a previous duplicate entry.
910
+ if ( matchFound ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
911
+ if ( calendar.isDateExact( disabledItems[index], unitToEnable ) ) {
912
+ disabledItems[index] = null
913
+ break
914
+ }
915
+ }
916
+
917
+ // In the event that we’re dealing with an exact range of dates,
918
+ // make sure there are no “inverted” dates because of it.
919
+ if ( isExactRange ) for ( index = 0; index < disabledItemsCount; index += 1 ) {
920
+ if ( calendar.isDateOverlap( disabledItems[index], unitToEnable ) ) {
921
+ disabledItems[index] = null
922
+ break
923
+ }
924
+ }
925
+
926
+ // If something is still matched, add it into the collection.
927
+ if ( matchFound ) {
928
+ disabledItems.push( matchFound )
929
+ }
930
+ })
931
+ }
932
+
933
+ // Return the updated collection.
934
+ return disabledItems.filter(function( val ) { return val != null })
935
+ } //DatePicker.prototype.activate
738
936
 
739
937
 
740
938
  /**
@@ -745,13 +943,14 @@ DatePicker.prototype.nodes = function( isOpen ) {
745
943
  var
746
944
  calendar = this,
747
945
  settings = calendar.settings,
748
- nowObject = calendar.item.now,
749
- selectedObject = calendar.item.select,
750
- highlightedObject = calendar.item.highlight,
751
- viewsetObject = calendar.item.view,
752
- disabledCollection = calendar.item.disable,
753
- minLimitObject = calendar.item.min,
754
- maxLimitObject = calendar.item.max,
946
+ calendarItem = calendar.item,
947
+ nowObject = calendarItem.now,
948
+ selectedObject = calendarItem.select,
949
+ highlightedObject = calendarItem.highlight,
950
+ viewsetObject = calendarItem.view,
951
+ disabledCollection = calendarItem.disable,
952
+ minLimitObject = calendarItem.min,
953
+ maxLimitObject = calendarItem.max,
755
954
 
756
955
 
757
956
  // Create the calendar table head using a copy of weekday labels collection.
@@ -764,20 +963,23 @@ DatePicker.prototype.nodes = function( isOpen ) {
764
963
  }
765
964
 
766
965
  // Create and return the table head group.
767
- return Picker._.node(
966
+ return _.node(
768
967
  'thead',
769
- Picker._.group({
770
- min: 0,
771
- max: DAYS_IN_WEEK - 1,
772
- i: 1,
773
- node: 'th',
774
- item: function( counter ) {
775
- return [
776
- collection[ counter ],
777
- settings.klass.weekdays
778
- ]
779
- }
780
- })
968
+ _.node(
969
+ 'tr',
970
+ _.group({
971
+ min: 0,
972
+ max: DAYS_IN_WEEK - 1,
973
+ i: 1,
974
+ node: 'th',
975
+ item: function( counter ) {
976
+ return [
977
+ collection[ counter ],
978
+ settings.klass.weekdays
979
+ ]
980
+ }
981
+ })
982
+ )
781
983
  ) //endreturn
782
984
  })( ( settings.showWeekdaysFull ? settings.weekdaysFull : settings.weekdaysShort ).slice( 0 ) ), //tableHead
783
985
 
@@ -786,7 +988,7 @@ DatePicker.prototype.nodes = function( isOpen ) {
786
988
  createMonthNav = function( next ) {
787
989
 
788
990
  // Otherwise, return the created month tag.
789
- return Picker._.node(
991
+ return _.node(
790
992
  'div',
791
993
  ' ',
792
994
  settings.klass[ 'nav' + ( next ? 'Next' : 'Prev' ) ] + (
@@ -807,7 +1009,7 @@ DatePicker.prototype.nodes = function( isOpen ) {
807
1009
  // If there are months to select, add a dropdown menu.
808
1010
  if ( settings.selectMonths ) {
809
1011
 
810
- return Picker._.node( 'select', Picker._.group({
1012
+ return _.node( 'select', _.group({
811
1013
  min: 0,
812
1014
  max: 11,
813
1015
  i: 1,
@@ -835,7 +1037,7 @@ DatePicker.prototype.nodes = function( isOpen ) {
835
1037
  }
836
1038
 
837
1039
  // If there's a need for a month selector
838
- return Picker._.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month )
1040
+ return _.node( 'div', monthsCollection[ viewsetObject.month ], settings.klass.month )
839
1041
  }, //createMonthLabel
840
1042
 
841
1043
 
@@ -876,7 +1078,7 @@ DatePicker.prototype.nodes = function( isOpen ) {
876
1078
  highestYear = maxYear
877
1079
  }
878
1080
 
879
- return Picker._.node( 'select', Picker._.group({
1081
+ return _.node( 'select', _.group({
880
1082
  min: lowestYear,
881
1083
  max: highestYear,
882
1084
  i: 1,
@@ -895,23 +1097,23 @@ DatePicker.prototype.nodes = function( isOpen ) {
895
1097
  }
896
1098
 
897
1099
  // Otherwise just return the year focused
898
- return Picker._.node( 'div', focusedYear, settings.klass.year )
1100
+ return _.node( 'div', focusedYear, settings.klass.year )
899
1101
  } //createYearLabel
900
1102
 
901
1103
 
902
1104
  // Create and return the entire calendar.
903
- return Picker._.node(
1105
+ return _.node(
904
1106
  'div',
905
1107
  createMonthNav() + createMonthNav( 1 ) +
906
1108
  createMonthLabel( settings.showMonthsShort ? settings.monthsShort : settings.monthsFull ) +
907
1109
  createYearLabel(),
908
1110
  settings.klass.header
909
- ) + Picker._.node(
1111
+ ) + _.node(
910
1112
  'table',
911
1113
  tableHead +
912
- Picker._.node(
1114
+ _.node(
913
1115
  'tbody',
914
- Picker._.group({
1116
+ _.group({
915
1117
  min: 0,
916
1118
  max: WEEKS_IN_CALENDAR - 1,
917
1119
  i: 1,
@@ -922,7 +1124,7 @@ DatePicker.prototype.nodes = function( isOpen ) {
922
1124
  var shiftDateBy = settings.firstDay && calendar.create([ viewsetObject.year, viewsetObject.month, 1 ]).day === 0 ? -7 : 0
923
1125
 
924
1126
  return [
925
- Picker._.group({
1127
+ _.group({
926
1128
  min: DAYS_IN_WEEK * rowCounter - viewsetObject.day + shiftDateBy + 1, // Add 1 for weekday 0index
927
1129
  max: function() {
928
1130
  return this.min + DAYS_IN_WEEK - 1
@@ -934,8 +1136,12 @@ DatePicker.prototype.nodes = function( isOpen ) {
934
1136
  // Convert the time date from a relative date to a target date.
935
1137
  targetDate = calendar.create([ viewsetObject.year, viewsetObject.month, targetDate + ( settings.firstDay ? 1 : 0 ) ])
936
1138
 
1139
+ var isSelected = selectedObject && selectedObject.pick == targetDate.pick,
1140
+ isHighlighted = highlightedObject && highlightedObject.pick == targetDate.pick,
1141
+ isDisabled = disabledCollection && calendar.disabled( targetDate ) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick
1142
+
937
1143
  return [
938
- Picker._.node(
1144
+ _.node(
939
1145
  'div',
940
1146
  targetDate.date,
941
1147
  (function( klasses ) {
@@ -949,23 +1155,33 @@ DatePicker.prototype.nodes = function( isOpen ) {
949
1155
  }
950
1156
 
951
1157
  // Add the `selected` class if something's selected and the time matches.
952
- if ( selectedObject && selectedObject.pick == targetDate.pick ) {
1158
+ if ( isSelected ) {
953
1159
  klasses.push( settings.klass.selected )
954
1160
  }
955
1161
 
956
1162
  // Add the `highlighted` class if something's highlighted and the time matches.
957
- if ( highlightedObject && highlightedObject.pick == targetDate.pick ) {
1163
+ if ( isHighlighted ) {
958
1164
  klasses.push( settings.klass.highlighted )
959
1165
  }
960
1166
 
961
1167
  // Add the `disabled` class if something's disabled and the object matches.
962
- if ( disabledCollection && calendar.disabled( targetDate ) || targetDate.pick < minLimitObject.pick || targetDate.pick > maxLimitObject.pick ) {
1168
+ if ( isDisabled ) {
963
1169
  klasses.push( settings.klass.disabled )
964
1170
  }
965
1171
 
966
1172
  return klasses.join( ' ' )
967
1173
  })([ settings.klass.day ]),
968
- 'data-pick=' + targetDate.pick
1174
+ 'data-pick=' + targetDate.pick + ' ' + _.ariaAttr({
1175
+ role: 'button',
1176
+ controls: calendar.$node[0].id,
1177
+ checked: isSelected && calendar.$node.val() === _.trigger(
1178
+ calendar.formats.toString,
1179
+ calendar,
1180
+ [ settings.format, targetDate ]
1181
+ ) ? true : null,
1182
+ activedescendant: isHighlighted ? true : null,
1183
+ disabled: isDisabled ? true : null
1184
+ })
969
1185
  )
970
1186
  ] //endreturn
971
1187
  }
@@ -978,10 +1194,10 @@ DatePicker.prototype.nodes = function( isOpen ) {
978
1194
  ) +
979
1195
 
980
1196
  // * For Firefox forms to submit, make sure to set the buttons’ `type` attributes as “button”.
981
- Picker._.node(
1197
+ _.node(
982
1198
  'div',
983
- Picker._.node( 'button', settings.today, settings.klass.buttonToday, 'type=button data-pick=' + nowObject.pick + ( isOpen ? '' : ' disabled' ) ) +
984
- Picker._.node( 'button', settings.clear, settings.klass.buttonClear, 'type=button data-clear=1' + ( isOpen ? '' : ' disabled' ) ),
1199
+ _.node( 'button', settings.today, settings.klass.buttonToday, 'type=button data-pick=' + nowObject.pick + ( isOpen ? '' : ' disabled' ) ) +
1200
+ _.node( 'button', settings.clear, settings.klass.buttonClear, 'type=button data-clear=1' + ( isOpen ? '' : ' disabled' ) ),
985
1201
  settings.klass.footer
986
1202
  ) //endreturn
987
1203
  } //DatePicker.prototype.nodes