bootstrap-datepicker-rails 1.6.4.1 → 1.7.1.1

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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bootstrap-datepicker-rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/bootstrap-datepicker/core.js +331 -397
  4. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker-en-CA.js +18 -0
  5. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ar-tn.js +15 -0
  6. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.bn.js +19 -0
  7. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.br.js +18 -0
  8. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.cs.js +1 -0
  9. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.da.js +8 -6
  10. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.eu.js +5 -1
  11. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.hi.js +18 -0
  12. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.hy.js +5 -4
  13. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ka.js +1 -1
  14. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.kh.js +9 -3
  15. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.km.js +15 -0
  16. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.kr.js +2 -0
  17. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.lv.js +1 -0
  18. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.oc.js +17 -0
  19. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.pl.js +7 -7
  20. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ro.js +2 -1
  21. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.rs-latin.js +4 -0
  22. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.rs.js +4 -0
  23. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ru.js +2 -1
  24. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.si.js +18 -0
  25. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.sl.js +2 -1
  26. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ta.js +18 -0
  27. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.tg.js +19 -0
  28. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.uz-cyrl.js +18 -0
  29. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.uz-latn.js +18 -0
  30. data/vendor/assets/stylesheets/bootstrap-datepicker.css +11 -5
  31. data/vendor/assets/stylesheets/bootstrap-datepicker3.css +11 -5
  32. metadata +15 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d6aca95c5f880c6e27ff17d0a0a841d54932bdd
4
- data.tar.gz: 26a0b29b42f6cf351854a6f157a356c8472ebb30
3
+ metadata.gz: e6d9437ec47d901edbc9145062e3b42184ab5d02
4
+ data.tar.gz: 3a409a8beb5c437e7f415a9dc802f13aadb0e261
5
5
  SHA512:
6
- metadata.gz: b819389cee934d6389935caef8dfca0e04df3fc139158a8a5a51de55cdc452b5dc3098dc28cc794a148507f40cbe9cd5bd79176ac13750b8c340422b0c56a44b
7
- data.tar.gz: 7b22978cb0a96675833ced8f09c07a3e60fccc3e7ed10ded7f075970f3be054c2af43252939e98939b57b277a4e7cd5516400fb482a0f994e2936765af0d5ccb
6
+ metadata.gz: 53c13bd180552f76804a8eaea5617ee219bc125db3c486cb6b0f2a1afb642c1ef87bb5e1e42ec51a1ebd3bac067db08acf387e815d58186477de87a1e7f6adb2
7
+ data.tar.gz: ab990de96a3f0ced09c25850b09c48576b04def8834fc17e8b41c6c08760c7009857a4c22fc1917a19ba23ddf9c93e1f33ec1ea97d05c7ab27f92e02720cfa38
@@ -1,5 +1,5 @@
1
1
  module BootstrapDatepickerRails
2
2
  module Rails
3
- VERSION = "1.6.4.1"
3
+ VERSION = "1.7.1.1"
4
4
  end
5
5
  end
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * Datepicker for Bootstrap v1.6.4 (https://github.com/eternicode/bootstrap-datepicker)
2
+ * Datepicker for Bootstrap v1.7.1 (https://github.com/uxsolutions/bootstrap-datepicker)
3
3
  *
4
- * Copyright 2012 Stefan Petre
5
- * Improvements by Andrew Rowls
6
4
  * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
7
- */(function(factory){
5
+ */
6
+
7
+ (function(factory){
8
8
  if (typeof define === "function" && define.amd) {
9
9
  define(["jquery"], factory);
10
10
  } else if (typeof exports === 'object') {
@@ -13,7 +13,6 @@
13
13
  factory(jQuery);
14
14
  }
15
15
  }(function($, undefined){
16
-
17
16
  function UTCDate(){
18
17
  return new Date(Date.UTC.apply(Date, arguments));
19
18
  }
@@ -28,8 +27,12 @@
28
27
  date1.getUTCDate() === date2.getUTCDate()
29
28
  );
30
29
  }
31
- function alias(method){
30
+ function alias(method, deprecationMsg){
32
31
  return function(){
32
+ if (deprecationMsg !== undefined) {
33
+ $.fn.datepicker.deprecated(deprecationMsg);
34
+ }
35
+
33
36
  return this[method].apply(this, arguments);
34
37
  };
35
38
  }
@@ -47,7 +50,8 @@
47
50
  // $.inArray doesn't work with Dates
48
51
  var val = d && d.valueOf();
49
52
  for (var i=0, l=this.length; i < l; i++)
50
- if (this[i].valueOf() === val)
53
+ // Use date arithmetic to allow dates with different times to match
54
+ if (0 <= this[i].valueOf() - val && this[i].valueOf() - val < 1000*60*60*24)
51
55
  return i;
52
56
  return -1;
53
57
  },
@@ -84,7 +88,7 @@
84
88
  // Picker object
85
89
 
86
90
  var Datepicker = function(element, options){
87
- $(element).data('datepicker', this);
91
+ $.data(element, 'datepicker', this);
88
92
  this._process_options(options);
89
93
 
90
94
  this.dates = new DateArray();
@@ -95,7 +99,6 @@
95
99
  this.isInput = this.element.is('input');
96
100
  this.inputField = this.isInput ? this.element : this.element.find('input');
97
101
  this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
98
- this.hasInput = this.component && this.inputField.length;
99
102
  if (this.component && this.component.length === 0)
100
103
  this.component = false;
101
104
  this.isInline = !this.component && this.element.is('div');
@@ -106,6 +109,7 @@
106
109
  if (this._check_template(this.o.templates.leftArrow)) {
107
110
  this.picker.find('.prev').html(this.o.templates.leftArrow);
108
111
  }
112
+
109
113
  if (this._check_template(this.o.templates.rightArrow)) {
110
114
  this.picker.find('.next').html(this.o.templates.rightArrow);
111
115
  }
@@ -124,29 +128,29 @@
124
128
  this.picker.addClass('datepicker-rtl');
125
129
  }
126
130
 
127
- this.viewMode = this.o.startView;
131
+ if (this.o.calendarWeeks) {
132
+ this.picker.find('.datepicker-days .datepicker-switch, thead .datepicker-title, tfoot .today, tfoot .clear')
133
+ .attr('colspan', function(i, val){
134
+ return Number(val) + 1;
135
+ });
136
+ }
128
137
 
129
- if (this.o.calendarWeeks)
130
- this.picker.find('thead .datepicker-title, tfoot .today, tfoot .clear')
131
- .attr('colspan', function(i, val){
132
- return parseInt(val) + 1;
133
- });
138
+ this._process_options({
139
+ startDate: this._o.startDate,
140
+ endDate: this._o.endDate,
141
+ daysOfWeekDisabled: this.o.daysOfWeekDisabled,
142
+ daysOfWeekHighlighted: this.o.daysOfWeekHighlighted,
143
+ datesDisabled: this.o.datesDisabled
144
+ });
134
145
 
135
146
  this._allow_update = false;
136
-
137
- this.setStartDate(this._o.startDate);
138
- this.setEndDate(this._o.endDate);
139
- this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
140
- this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted);
141
- this.setDatesDisabled(this.o.datesDisabled);
147
+ this.setViewMode(this.o.startView);
148
+ this._allow_update = true;
142
149
 
143
150
  this.fillDow();
144
151
  this.fillMonths();
145
152
 
146
- this._allow_update = true;
147
-
148
153
  this.update();
149
- this.showMode();
150
154
 
151
155
  if (this.isInline){
152
156
  this.show();
@@ -156,23 +160,21 @@
156
160
  Datepicker.prototype = {
157
161
  constructor: Datepicker,
158
162
 
159
- _resolveViewName: function(view, default_value){
160
- if (view === 0 || view === 'days' || view === 'month') {
161
- return 0;
162
- }
163
- if (view === 1 || view === 'months' || view === 'year') {
164
- return 1;
165
- }
166
- if (view === 2 || view === 'years' || view === 'decade') {
167
- return 2;
168
- }
169
- if (view === 3 || view === 'decades' || view === 'century') {
170
- return 3;
171
- }
172
- if (view === 4 || view === 'centuries' || view === 'millennium') {
173
- return 4;
174
- }
175
- return default_value === undefined ? false : default_value;
163
+ _resolveViewName: function(view){
164
+ $.each(DPGlobal.viewModes, function(i, viewMode){
165
+ if (view === i || $.inArray(view, viewMode.names) !== -1){
166
+ view = i;
167
+ return false;
168
+ }
169
+ });
170
+
171
+ return view;
172
+ },
173
+
174
+ _resolveDaysOfWeek: function(daysOfWeek){
175
+ if (!$.isArray(daysOfWeek))
176
+ daysOfWeek = daysOfWeek.split(/[,\s]*/);
177
+ return $.map(daysOfWeek, Number);
176
178
  },
177
179
 
178
180
  _check_template: function(tmp){
@@ -211,13 +213,12 @@
211
213
  o.language = lang;
212
214
 
213
215
  // Retrieve view index from any aliases
214
- o.startView = this._resolveViewName(o.startView, 0);
215
- o.minViewMode = this._resolveViewName(o.minViewMode, 0);
216
- o.maxViewMode = this._resolveViewName(o.maxViewMode, 4);
216
+ o.startView = this._resolveViewName(o.startView);
217
+ o.minViewMode = this._resolveViewName(o.minViewMode);
218
+ o.maxViewMode = this._resolveViewName(o.maxViewMode);
217
219
 
218
- // Check that the start view is between min and max
219
- o.startView = Math.min(o.startView, o.maxViewMode);
220
- o.startView = Math.max(o.startView, o.minViewMode);
220
+ // Check view is between min and max
221
+ o.startView = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, o.startView));
221
222
 
222
223
  // true, false, or Number > 0
223
224
  if (o.multidate !== true){
@@ -254,27 +255,14 @@
254
255
  }
255
256
  }
256
257
 
257
- o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
258
- if (!$.isArray(o.daysOfWeekDisabled))
259
- o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
260
- o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
261
- return parseInt(d, 10);
262
- });
263
-
264
- o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[];
265
- if (!$.isArray(o.daysOfWeekHighlighted))
266
- o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/);
267
- o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){
268
- return parseInt(d, 10);
269
- });
258
+ o.daysOfWeekDisabled = this._resolveDaysOfWeek(o.daysOfWeekDisabled||[]);
259
+ o.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted||[]);
270
260
 
271
261
  o.datesDisabled = o.datesDisabled||[];
272
262
  if (!$.isArray(o.datesDisabled)) {
273
- o.datesDisabled = [
274
- o.datesDisabled
275
- ];
263
+ o.datesDisabled = o.datesDisabled.split(',');
276
264
  }
277
- o.datesDisabled = $.map(o.datesDisabled,function(d){
265
+ o.datesDisabled = $.map(o.datesDisabled, function(d){
278
266
  return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);
279
267
  });
280
268
 
@@ -309,7 +297,9 @@
309
297
  });
310
298
  o.orientation.y = _plc[0] || 'auto';
311
299
  }
312
- if (o.defaultViewDate) {
300
+ if (o.defaultViewDate instanceof Date || typeof o.defaultViewDate === 'string') {
301
+ o.defaultViewDate = DPGlobal.parseDate(o.defaultViewDate, format, o.language, o.assumeNearbyYear);
302
+ } else if (o.defaultViewDate) {
313
303
  var year = o.defaultViewDate.year || new Date().getFullYear();
314
304
  var month = o.defaultViewDate.month || 0;
315
305
  var day = o.defaultViewDate.day || 1;
@@ -326,8 +316,7 @@
326
316
  if (evs[i].length === 2){
327
317
  ch = undefined;
328
318
  ev = evs[i][1];
329
- }
330
- else if (evs[i].length === 3){
319
+ } else if (evs[i].length === 3){
331
320
  ch = evs[i][1];
332
321
  ev = evs[i][2];
333
322
  }
@@ -340,8 +329,7 @@
340
329
  if (evs[i].length === 2){
341
330
  ch = undefined;
342
331
  ev = evs[i][1];
343
- }
344
- else if (evs[i].length === 3){
332
+ } else if (evs[i].length === 3){
345
333
  ch = evs[i][1];
346
334
  ev = evs[i][2];
347
335
  }
@@ -367,7 +355,8 @@
367
355
  [this.element, events]
368
356
  ];
369
357
  }
370
- else if (this.component && this.hasInput) { // component: input + button
358
+ // component: input + button
359
+ else if (this.component && this.inputField.length) {
371
360
  this._events = [
372
361
  // For components that are not readonly, allow keyboard nav
373
362
  [this.inputField, events],
@@ -412,11 +401,17 @@
412
401
  [this.picker, {
413
402
  click: $.proxy(this.click, this)
414
403
  }],
404
+ [this.picker, '.prev, .next', {
405
+ click: $.proxy(this.navArrowsClick, this)
406
+ }],
407
+ [this.picker, '.day:not(.disabled)', {
408
+ click: $.proxy(this.dayCellClick, this)
409
+ }],
415
410
  [$(window), {
416
411
  resize: $.proxy(this.place, this)
417
412
  }],
418
413
  [$(document), {
419
- mousedown: $.proxy(function(e){
414
+ 'mousedown touchstart': $.proxy(function(e){
420
415
  // Clicked outside the datepicker, hide it
421
416
  if (!(
422
417
  this.element.is(e.target) ||
@@ -452,13 +447,13 @@
452
447
  this.element.trigger({
453
448
  type: event,
454
449
  date: local_date,
450
+ viewMode: this.viewMode,
455
451
  dates: $.map(this.dates, this._utc_to_local),
456
452
  format: $.proxy(function(ix, format){
457
453
  if (arguments.length === 0){
458
454
  ix = this.dates.length - 1;
459
455
  format = this.o.format;
460
- }
461
- else if (typeof ix === 'string'){
456
+ } else if (typeof ix === 'string'){
462
457
  format = ix;
463
458
  ix = this.dates.length - 1;
464
459
  }
@@ -490,8 +485,7 @@
490
485
  this.focusDate = null;
491
486
  this.picker.hide().detach();
492
487
  this._detachSecondaryEvents();
493
- this.viewMode = this.o.startView;
494
- this.showMode();
488
+ this.setViewMode(this.o.startView);
495
489
 
496
490
  if (this.o.forceParse && this.inputField.val())
497
491
  this.setValue();
@@ -511,25 +505,33 @@
511
505
  return this;
512
506
  },
513
507
 
514
- paste: function(evt){
508
+ paste: function(e){
515
509
  var dateString;
516
- if (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types
517
- && $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) {
518
- dateString = evt.originalEvent.clipboardData.getData('text/plain');
519
- }
520
- else if (window.clipboardData) {
510
+ if (e.originalEvent.clipboardData && e.originalEvent.clipboardData.types
511
+ && $.inArray('text/plain', e.originalEvent.clipboardData.types) !== -1) {
512
+ dateString = e.originalEvent.clipboardData.getData('text/plain');
513
+ } else if (window.clipboardData) {
521
514
  dateString = window.clipboardData.getData('Text');
522
- }
523
- else {
515
+ } else {
524
516
  return;
525
517
  }
526
518
  this.setDate(dateString);
527
519
  this.update();
528
- evt.preventDefault();
520
+ e.preventDefault();
529
521
  },
530
522
 
531
523
  _utc_to_local: function(utc){
532
- return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));
524
+ if (!utc) {
525
+ return utc;
526
+ }
527
+
528
+ var local = new Date(utc.getTime() + (utc.getTimezoneOffset() * 60000));
529
+
530
+ if (local.getTimezoneOffset() !== utc.getTimezoneOffset()) {
531
+ local = new Date(utc.getTime() + (local.getTimezoneOffset() * 60000));
532
+ }
533
+
534
+ return local;
533
535
  },
534
536
  _local_to_utc: function(local){
535
537
  return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
@@ -538,7 +540,7 @@
538
540
  return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
539
541
  },
540
542
  _zero_utc_time: function(utc){
541
- return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
543
+ return utc && UTCDate(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate());
542
544
  },
543
545
 
544
546
  getDates: function(){
@@ -557,7 +559,7 @@
557
559
 
558
560
  getUTCDate: function(){
559
561
  var selected_date = this.dates.get(-1);
560
- if (typeof selected_date !== 'undefined') {
562
+ if (selected_date !== undefined) {
561
563
  return new Date(selected_date);
562
564
  } else {
563
565
  return null;
@@ -565,10 +567,7 @@
565
567
  },
566
568
 
567
569
  clearDates: function(){
568
- if (this.inputField) {
569
- this.inputField.val('');
570
- }
571
-
570
+ this.inputField.val('');
572
571
  this.update();
573
572
  this._trigger('changeDate');
574
573
 
@@ -576,6 +575,7 @@
576
575
  this.hide();
577
576
  }
578
577
  },
578
+
579
579
  setDates: function(){
580
580
  var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
581
581
  this.update.apply(this, args);
@@ -586,15 +586,13 @@
586
586
 
587
587
  setUTCDates: function(){
588
588
  var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
589
- this.update.apply(this, $.map(args, this._utc_to_local));
590
- this._trigger('changeDate');
591
- this.setValue();
589
+ this.setDates.apply(this, $.map(args, this._utc_to_local));
592
590
  return this;
593
591
  },
594
592
 
595
593
  setDate: alias('setDates'),
596
594
  setUTCDate: alias('setUTCDates'),
597
- remove: alias('destroy'),
595
+ remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead'),
598
596
 
599
597
  setValue: function(){
600
598
  var formatted = this.getFormattedDate();
@@ -637,7 +635,6 @@
637
635
  setDaysOfWeekDisabled: function(daysOfWeekDisabled){
638
636
  this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
639
637
  this.update();
640
- this.updateNavArrows();
641
638
  return this;
642
639
  },
643
640
 
@@ -650,7 +647,7 @@
650
647
  setDatesDisabled: function(datesDisabled){
651
648
  this._process_options({datesDisabled: datesDisabled});
652
649
  this.update();
653
- this.updateNavArrows();
650
+ return this;
654
651
  },
655
652
 
656
653
  place: function(){
@@ -664,17 +661,17 @@
664
661
  scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),
665
662
  appendOffset = container.offset();
666
663
 
667
- var parentsZindex = [];
664
+ var parentsZindex = [0];
668
665
  this.element.parents().each(function(){
669
666
  var itemZIndex = $(this).css('z-index');
670
- if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));
667
+ if (itemZIndex !== 'auto' && Number(itemZIndex) !== 0) parentsZindex.push(Number(itemZIndex));
671
668
  });
672
669
  var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;
673
670
  var offset = this.component ? this.component.parent().offset() : this.element.offset();
674
671
  var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
675
672
  var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
676
- var left = offset.left - appendOffset.left,
677
- top = offset.top - appendOffset.top;
673
+ var left = offset.left - appendOffset.left;
674
+ var top = offset.top - appendOffset.top;
678
675
 
679
676
  if (this.o.container !== 'body') {
680
677
  top += scrollTop;
@@ -702,8 +699,13 @@
702
699
  this.picker.addClass('datepicker-orient-right');
703
700
  left += width - calendarWidth;
704
701
  } else {
705
- // Default to left
706
- this.picker.addClass('datepicker-orient-left');
702
+ if (this.o.rtl) {
703
+ // Default to right
704
+ this.picker.addClass('datepicker-orient-right');
705
+ } else {
706
+ // Default to left
707
+ this.picker.addClass('datepicker-orient-left');
708
+ }
707
709
  }
708
710
  }
709
711
 
@@ -754,8 +756,7 @@
754
756
  dates.push(date);
755
757
  }, this));
756
758
  fromArgs = true;
757
- }
758
- else {
759
+ } else {
759
760
  dates = this.isInput
760
761
  ? this.element.val()
761
762
  : this.element.data('date') || this.inputField.val();
@@ -777,59 +778,63 @@
777
778
  }, this), true);
778
779
  this.dates.replace(dates);
779
780
 
780
- if (this.dates.length)
781
- this.viewDate = new Date(this.dates.get(-1));
782
- else if (this.viewDate < this.o.startDate)
783
- this.viewDate = new Date(this.o.startDate);
784
- else if (this.viewDate > this.o.endDate)
785
- this.viewDate = new Date(this.o.endDate);
786
- else
787
- this.viewDate = this.o.defaultViewDate;
781
+ if (this.o.updateViewDate) {
782
+ if (this.dates.length)
783
+ this.viewDate = new Date(this.dates.get(-1));
784
+ else if (this.viewDate < this.o.startDate)
785
+ this.viewDate = new Date(this.o.startDate);
786
+ else if (this.viewDate > this.o.endDate)
787
+ this.viewDate = new Date(this.o.endDate);
788
+ else
789
+ this.viewDate = this.o.defaultViewDate;
790
+ }
788
791
 
789
792
  if (fromArgs){
790
793
  // setting date by clicking
791
794
  this.setValue();
795
+ this.element.change();
792
796
  }
793
- else if (dates.length){
797
+ else if (this.dates.length){
794
798
  // setting date by typing
795
- if (String(oldDates) !== String(this.dates))
799
+ if (String(oldDates) !== String(this.dates) && fromArgs) {
796
800
  this._trigger('changeDate');
801
+ this.element.change();
802
+ }
797
803
  }
798
- if (!this.dates.length && oldDates.length)
804
+ if (!this.dates.length && oldDates.length) {
799
805
  this._trigger('clearDate');
806
+ this.element.change();
807
+ }
800
808
 
801
809
  this.fill();
802
- this.element.change();
803
810
  return this;
804
811
  },
805
812
 
806
813
  fillDow: function(){
814
+ if (this.o.showWeekDays) {
807
815
  var dowCnt = this.o.weekStart,
808
816
  html = '<tr>';
809
817
  if (this.o.calendarWeeks){
810
- this.picker.find('.datepicker-days .datepicker-switch')
811
- .attr('colspan', function(i, val){
812
- return parseInt(val) + 1;
813
- });
814
818
  html += '<th class="cw">&#160;</th>';
815
819
  }
816
820
  while (dowCnt < this.o.weekStart + 7){
817
821
  html += '<th class="dow';
818
- if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) > -1)
822
+ if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) !== -1)
819
823
  html += ' disabled';
820
824
  html += '">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
821
825
  }
822
826
  html += '</tr>';
823
827
  this.picker.find('.datepicker-days thead').append(html);
828
+ }
824
829
  },
825
830
 
826
831
  fillMonths: function(){
827
832
  var localDate = this._utc_to_local(this.viewDate);
828
- var html = '',
829
- i = 0;
830
- while (i < 12){
831
- var focused = localDate && localDate.getMonth() === i ? ' focused' : '';
832
- html += '<span class="month' + focused + '">' + dates[this.o.language].monthsShort[i++]+'</span>';
833
+ var html = '';
834
+ var focused;
835
+ for (var i = 0; i < 12; i++){
836
+ focused = localDate && localDate.getMonth() === i ? ' focused' : '';
837
+ html += '<span class="month' + focused + '">' + dates[this.o.language].monthsShort[i] + '</span>';
833
838
  }
834
839
  this.picker.find('.datepicker-months td').html(html);
835
840
  },
@@ -848,20 +853,16 @@
848
853
  var cls = [],
849
854
  year = this.viewDate.getUTCFullYear(),
850
855
  month = this.viewDate.getUTCMonth(),
851
- today = new Date();
856
+ today = UTCToday();
852
857
  if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
853
858
  cls.push('old');
854
- }
855
- else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
859
+ } else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
856
860
  cls.push('new');
857
861
  }
858
862
  if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
859
863
  cls.push('focused');
860
- // Compare internal UTC date with local today, not UTC today
861
- if (this.o.todayHighlight &&
862
- date.getUTCFullYear() === today.getFullYear() &&
863
- date.getUTCMonth() === today.getMonth() &&
864
- date.getUTCDate() === today.getDate()){
864
+ // Compare internal UTC date with UTC today, not local today
865
+ if (this.o.todayHighlight && isUTCEquals(date, today)) {
865
866
  cls.push('today');
866
867
  }
867
868
  if (this.dates.contains(date) !== -1)
@@ -870,8 +871,8 @@
870
871
  cls.push('disabled');
871
872
  }
872
873
  if (this.dateIsDisabled(date)){
873
- cls.push('disabled', 'disabled-date');
874
- }
874
+ cls.push('disabled', 'disabled-date');
875
+ }
875
876
  if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){
876
877
  cls.push('highlighted');
877
878
  }
@@ -893,47 +894,44 @@
893
894
  return cls;
894
895
  },
895
896
 
896
- _fill_yearsView: function(selector, cssClass, factor, step, currentYear, startYear, endYear, callback){
897
- var html, view, year, steps, startStep, endStep, thisYear, i, classes, tooltip, before;
898
-
899
- html = '';
900
- view = this.picker.find(selector);
901
- year = parseInt(currentYear / factor, 10) * factor;
902
- startStep = parseInt(startYear / step, 10) * step;
903
- endStep = parseInt(endYear / step, 10) * step;
904
- steps = $.map(this.dates, function(d){
905
- return parseInt(d.getUTCFullYear() / step, 10) * step;
897
+ _fill_yearsView: function(selector, cssClass, factor, year, startYear, endYear, beforeFn){
898
+ var html = '';
899
+ var step = factor / 10;
900
+ var view = this.picker.find(selector);
901
+ var startVal = Math.floor(year / factor) * factor;
902
+ var endVal = startVal + step * 9;
903
+ var focusedVal = Math.floor(this.viewDate.getFullYear() / step) * step;
904
+ var selected = $.map(this.dates, function(d){
905
+ return Math.floor(d.getUTCFullYear() / step) * step;
906
906
  });
907
907
 
908
- view.find('.datepicker-switch').text(year + '-' + (year + step * 9));
909
-
910
- thisYear = year - step;
911
- for (i = -1; i < 11; i += 1) {
908
+ var classes, tooltip, before;
909
+ for (var currVal = startVal - step; currVal <= endVal + step; currVal += step) {
912
910
  classes = [cssClass];
913
911
  tooltip = null;
914
912
 
915
- if (i === -1) {
913
+ if (currVal === startVal - step) {
916
914
  classes.push('old');
917
- } else if (i === 10) {
915
+ } else if (currVal === endVal + step) {
918
916
  classes.push('new');
919
917
  }
920
- if ($.inArray(thisYear, steps) !== -1) {
918
+ if ($.inArray(currVal, selected) !== -1) {
921
919
  classes.push('active');
922
920
  }
923
- if (thisYear < startStep || thisYear > endStep) {
921
+ if (currVal < startYear || currVal > endYear) {
924
922
  classes.push('disabled');
925
923
  }
926
- if (thisYear === this.viewDate.getFullYear()) {
924
+ if (currVal === focusedVal) {
927
925
  classes.push('focused');
928
926
  }
929
927
 
930
- if (callback !== $.noop) {
931
- before = callback(new Date(thisYear, 0, 1));
928
+ if (beforeFn !== $.noop) {
929
+ before = beforeFn(new Date(currVal, 0, 1));
932
930
  if (before === undefined) {
933
931
  before = {};
934
- } else if (typeof(before) === 'boolean') {
932
+ } else if (typeof before === 'boolean') {
935
933
  before = {enabled: before};
936
- } else if (typeof(before) === 'string') {
934
+ } else if (typeof before === 'string') {
937
935
  before = {classes: before};
938
936
  }
939
937
  if (before.enabled === false) {
@@ -947,9 +945,10 @@
947
945
  }
948
946
  }
949
947
 
950
- html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + thisYear + '</span>';
951
- thisYear += step;
948
+ html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + currVal + '</span>';
952
949
  }
950
+
951
+ view.find('.datepicker-switch').text(startVal + '-' + endVal);
953
952
  view.find('td').html(html);
954
953
  },
955
954
 
@@ -972,18 +971,17 @@
972
971
  .text(DPGlobal.formatDate(d, titleFormat, this.o.language));
973
972
  this.picker.find('tfoot .today')
974
973
  .text(todaytxt)
975
- .toggle(this.o.todayBtn !== false);
974
+ .css('display', this.o.todayBtn === true || this.o.todayBtn === 'linked' ? 'table-cell' : 'none');
976
975
  this.picker.find('tfoot .clear')
977
976
  .text(cleartxt)
978
- .toggle(this.o.clearBtn !== false);
977
+ .css('display', this.o.clearBtn === true ? 'table-cell' : 'none');
979
978
  this.picker.find('thead .datepicker-title')
980
979
  .text(this.o.title)
981
- .toggle(this.o.title !== '');
980
+ .css('display', typeof this.o.title === 'string' && this.o.title !== '' ? 'table-cell' : 'none');
982
981
  this.updateNavArrows();
983
982
  this.fillMonths();
984
- var prevMonth = UTCDate(year, month-1, 28),
985
- day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
986
- prevMonth.setUTCDate(day);
983
+ var prevMonth = UTCDate(year, month, 0),
984
+ day = prevMonth.getUTCDate();
987
985
  prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
988
986
  var nextMonth = new Date(prevMonth);
989
987
  if (prevMonth.getUTCFullYear() < 100){
@@ -992,35 +990,38 @@
992
990
  nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
993
991
  nextMonth = nextMonth.valueOf();
994
992
  var html = [];
995
- var clsName;
993
+ var weekDay, clsName;
996
994
  while (prevMonth.valueOf() < nextMonth){
997
- if (prevMonth.getUTCDay() === this.o.weekStart){
995
+ weekDay = prevMonth.getUTCDay();
996
+ if (weekDay === this.o.weekStart){
998
997
  html.push('<tr>');
999
998
  if (this.o.calendarWeeks){
1000
999
  // ISO 8601: First week contains first thursday.
1001
1000
  // ISO also states week starts on Monday, but we can be more abstract here.
1002
1001
  var
1003
1002
  // Start of current week: based on weekstart/current date
1004
- ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
1003
+ ws = new Date(+prevMonth + (this.o.weekStart - weekDay - 7) % 7 * 864e5),
1005
1004
  // Thursday of this week
1006
1005
  th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
1007
1006
  // First Thursday of year, year from thursday
1008
- yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
1007
+ yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay()) % 7 * 864e5),
1009
1008
  // Calendar week: ms between thursdays, div ms per day, div 7 days
1010
- calWeek = (th - yth) / 864e5 / 7 + 1;
1009
+ calWeek = (th - yth) / 864e5 / 7 + 1;
1011
1010
  html.push('<td class="cw">'+ calWeek +'</td>');
1012
1011
  }
1013
1012
  }
1014
1013
  clsName = this.getClassNames(prevMonth);
1015
1014
  clsName.push('day');
1016
1015
 
1016
+ var content = prevMonth.getUTCDate();
1017
+
1017
1018
  if (this.o.beforeShowDay !== $.noop){
1018
1019
  before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
1019
1020
  if (before === undefined)
1020
1021
  before = {};
1021
- else if (typeof(before) === 'boolean')
1022
+ else if (typeof before === 'boolean')
1022
1023
  before = {enabled: before};
1023
- else if (typeof(before) === 'string')
1024
+ else if (typeof before === 'string')
1024
1025
  before = {classes: before};
1025
1026
  if (before.enabled === false)
1026
1027
  clsName.push('disabled');
@@ -1028,6 +1029,8 @@
1028
1029
  clsName = clsName.concat(before.classes.split(/\s+/));
1029
1030
  if (before.tooltip)
1030
1031
  tooltip = before.tooltip;
1032
+ if (before.content)
1033
+ content = before.content;
1031
1034
  }
1032
1035
 
1033
1036
  //Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2)
@@ -1038,21 +1041,21 @@
1038
1041
  clsName = $.unique(clsName);
1039
1042
  }
1040
1043
 
1041
- html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
1044
+ html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + ' data-date="' + prevMonth.getTime().toString() + '">' + content + '</td>');
1042
1045
  tooltip = null;
1043
- if (prevMonth.getUTCDay() === this.o.weekEnd){
1046
+ if (weekDay === this.o.weekEnd){
1044
1047
  html.push('</tr>');
1045
1048
  }
1046
- prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
1049
+ prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
1047
1050
  }
1048
- this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
1051
+ this.picker.find('.datepicker-days tbody').html(html.join(''));
1049
1052
 
1050
1053
  var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';
1051
1054
  var months = this.picker.find('.datepicker-months')
1052
1055
  .find('.datepicker-switch')
1053
1056
  .text(this.o.maxViewMode < 2 ? monthsTitle : year)
1054
1057
  .end()
1055
- .find('span').removeClass('active');
1058
+ .find('tbody span').removeClass('active');
1056
1059
 
1057
1060
  $.each(this.dates, function(i, d){
1058
1061
  if (d.getUTCFullYear() === year)
@@ -1076,9 +1079,9 @@
1076
1079
  var before = that.o.beforeShowMonth(moDate);
1077
1080
  if (before === undefined)
1078
1081
  before = {};
1079
- else if (typeof(before) === 'boolean')
1082
+ else if (typeof before === 'boolean')
1080
1083
  before = {enabled: before};
1081
- else if (typeof(before) === 'string')
1084
+ else if (typeof before === 'string')
1082
1085
  before = {classes: before};
1083
1086
  if (before.enabled === false && !$(month).hasClass('disabled'))
1084
1087
  $(month).addClass('disabled');
@@ -1094,7 +1097,6 @@
1094
1097
  '.datepicker-years',
1095
1098
  'year',
1096
1099
  10,
1097
- 1,
1098
1100
  year,
1099
1101
  startYear,
1100
1102
  endYear,
@@ -1106,7 +1108,6 @@
1106
1108
  '.datepicker-decades',
1107
1109
  'decade',
1108
1110
  100,
1109
- 10,
1110
1111
  year,
1111
1112
  startYear,
1112
1113
  endYear,
@@ -1118,7 +1119,6 @@
1118
1119
  '.datepicker-centuries',
1119
1120
  'century',
1120
1121
  1000,
1121
- 100,
1122
1122
  year,
1123
1123
  startYear,
1124
1124
  endYear,
@@ -1132,73 +1132,53 @@
1132
1132
 
1133
1133
  var d = new Date(this.viewDate),
1134
1134
  year = d.getUTCFullYear(),
1135
- month = d.getUTCMonth();
1135
+ month = d.getUTCMonth(),
1136
+ startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
1137
+ startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
1138
+ endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
1139
+ endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
1140
+ prevIsDisabled,
1141
+ nextIsDisabled,
1142
+ factor = 1;
1136
1143
  switch (this.viewMode){
1137
1144
  case 0:
1138
- if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
1139
- this.picker.find('.prev').css({visibility: 'hidden'});
1140
- }
1141
- else {
1142
- this.picker.find('.prev').css({visibility: 'visible'});
1143
- }
1144
- if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
1145
- this.picker.find('.next').css({visibility: 'hidden'});
1146
- }
1147
- else {
1148
- this.picker.find('.next').css({visibility: 'visible'});
1149
- }
1145
+ prevIsDisabled = year <= startYear && month <= startMonth;
1146
+ nextIsDisabled = year >= endYear && month >= endMonth;
1150
1147
  break;
1151
- case 1:
1152
- case 2:
1153
- case 3:
1154
1148
  case 4:
1155
- if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){
1156
- this.picker.find('.prev').css({visibility: 'hidden'});
1157
- }
1158
- else {
1159
- this.picker.find('.prev').css({visibility: 'visible'});
1160
- }
1161
- if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){
1162
- this.picker.find('.next').css({visibility: 'hidden'});
1163
- }
1164
- else {
1165
- this.picker.find('.next').css({visibility: 'visible'});
1166
- }
1149
+ factor *= 10;
1150
+ /* falls through */
1151
+ case 3:
1152
+ factor *= 10;
1153
+ /* falls through */
1154
+ case 2:
1155
+ factor *= 10;
1156
+ /* falls through */
1157
+ case 1:
1158
+ prevIsDisabled = Math.floor(year / factor) * factor <= startYear;
1159
+ nextIsDisabled = Math.floor(year / factor) * factor + factor >= endYear;
1167
1160
  break;
1168
1161
  }
1162
+
1163
+ this.picker.find('.prev').toggleClass('disabled', prevIsDisabled);
1164
+ this.picker.find('.next').toggleClass('disabled', nextIsDisabled);
1169
1165
  },
1170
1166
 
1171
1167
  click: function(e){
1172
1168
  e.preventDefault();
1173
1169
  e.stopPropagation();
1174
1170
 
1175
- var target, dir, day, year, month, monthChanged, yearChanged;
1171
+ var target, dir, day, year, month;
1176
1172
  target = $(e.target);
1177
1173
 
1178
1174
  // Clicked on the switch
1179
- if (target.hasClass('datepicker-switch')){
1180
- this.showMode(1);
1181
- }
1182
-
1183
- // Clicked on prev or next
1184
- var navArrow = target.closest('.prev, .next');
1185
- if (navArrow.length > 0) {
1186
- dir = DPGlobal.modes[this.viewMode].navStep * (navArrow.hasClass('prev') ? -1 : 1);
1187
- if (this.viewMode === 0){
1188
- this.viewDate = this.moveMonth(this.viewDate, dir);
1189
- this._trigger('changeMonth', this.viewDate);
1190
- } else {
1191
- this.viewDate = this.moveYear(this.viewDate, dir);
1192
- if (this.viewMode === 1){
1193
- this._trigger('changeYear', this.viewDate);
1194
- }
1195
- }
1196
- this.fill();
1175
+ if (target.hasClass('datepicker-switch') && this.viewMode !== this.o.maxViewMode){
1176
+ this.setViewMode(this.viewMode + 1);
1197
1177
  }
1198
1178
 
1199
1179
  // Clicked on today button
1200
1180
  if (target.hasClass('today') && !target.hasClass('day')){
1201
- this.showMode(-2);
1181
+ this.setViewMode(0);
1202
1182
  this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');
1203
1183
  }
1204
1184
 
@@ -1208,104 +1188,70 @@
1208
1188
  }
1209
1189
 
1210
1190
  if (!target.hasClass('disabled')){
1211
- // Clicked on a day
1212
- if (target.hasClass('day')){
1213
- day = parseInt(target.text(), 10) || 1;
1214
- year = this.viewDate.getUTCFullYear();
1215
- month = this.viewDate.getUTCMonth();
1216
-
1217
- // From last month
1218
- if (target.hasClass('old')){
1219
- if (month === 0) {
1220
- month = 11;
1221
- year = year - 1;
1222
- monthChanged = true;
1223
- yearChanged = true;
1224
- } else {
1225
- month = month - 1;
1226
- monthChanged = true;
1227
- }
1228
- }
1229
-
1230
- // From next month
1231
- if (target.hasClass('new')) {
1232
- if (month === 11){
1233
- month = 0;
1234
- year = year + 1;
1235
- monthChanged = true;
1236
- yearChanged = true;
1237
- } else {
1238
- month = month + 1;
1239
- monthChanged = true;
1240
- }
1241
- }
1242
- this._setDate(UTCDate(year, month, day));
1243
- if (yearChanged) {
1244
- this._trigger('changeYear', this.viewDate);
1245
- }
1246
- if (monthChanged) {
1247
- this._trigger('changeMonth', this.viewDate);
1248
- }
1249
- }
1250
-
1251
- // Clicked on a month
1252
- if (target.hasClass('month')) {
1253
- this.viewDate.setUTCDate(1);
1254
- day = 1;
1255
- month = target.parent().find('span').index(target);
1256
- year = this.viewDate.getUTCFullYear();
1257
- this.viewDate.setUTCMonth(month);
1258
- this._trigger('changeMonth', this.viewDate);
1259
- if (this.o.minViewMode === 1){
1260
- this._setDate(UTCDate(year, month, day));
1261
- this.showMode();
1262
- } else {
1263
- this.showMode(-1);
1264
- }
1265
- this.fill();
1266
- }
1267
-
1268
- // Clicked on a year
1269
- if (target.hasClass('year')
1191
+ // Clicked on a month, year, decade, century
1192
+ if (target.hasClass('month')
1193
+ || target.hasClass('year')
1270
1194
  || target.hasClass('decade')
1271
1195
  || target.hasClass('century')) {
1272
1196
  this.viewDate.setUTCDate(1);
1273
1197
 
1274
1198
  day = 1;
1275
- month = 0;
1276
- year = parseInt(target.text(), 10)||0;
1277
- this.viewDate.setUTCFullYear(year);
1278
-
1279
- if (target.hasClass('year')){
1280
- this._trigger('changeYear', this.viewDate);
1281
- if (this.o.minViewMode === 2){
1282
- this._setDate(UTCDate(year, month, day));
1283
- }
1284
- }
1285
- if (target.hasClass('decade')){
1286
- this._trigger('changeDecade', this.viewDate);
1287
- if (this.o.minViewMode === 3){
1288
- this._setDate(UTCDate(year, month, day));
1289
- }
1290
- }
1291
- if (target.hasClass('century')){
1292
- this._trigger('changeCentury', this.viewDate);
1293
- if (this.o.minViewMode === 4){
1294
- this._setDate(UTCDate(year, month, day));
1295
- }
1199
+ if (this.viewMode === 1){
1200
+ month = target.parent().find('span').index(target);
1201
+ year = this.viewDate.getUTCFullYear();
1202
+ this.viewDate.setUTCMonth(month);
1203
+ } else {
1204
+ month = 0;
1205
+ year = Number(target.text());
1206
+ this.viewDate.setUTCFullYear(year);
1296
1207
  }
1297
1208
 
1298
- this.showMode(-1);
1299
- this.fill();
1209
+ this._trigger(DPGlobal.viewModes[this.viewMode - 1].e, this.viewDate);
1210
+
1211
+ if (this.viewMode === this.o.minViewMode){
1212
+ this._setDate(UTCDate(year, month, day));
1213
+ } else {
1214
+ this.setViewMode(this.viewMode - 1);
1215
+ this.fill();
1216
+ }
1300
1217
  }
1301
1218
  }
1302
1219
 
1303
1220
  if (this.picker.is(':visible') && this._focused_from){
1304
- $(this._focused_from).focus();
1221
+ this._focused_from.focus();
1305
1222
  }
1306
1223
  delete this._focused_from;
1307
1224
  },
1308
1225
 
1226
+ dayCellClick: function(e){
1227
+ var $target = $(e.currentTarget);
1228
+ var timestamp = $target.data('date');
1229
+ var date = new Date(timestamp);
1230
+
1231
+ if (this.o.updateViewDate) {
1232
+ if (date.getUTCFullYear() !== this.viewDate.getUTCFullYear()) {
1233
+ this._trigger('changeYear', this.viewDate);
1234
+ }
1235
+
1236
+ if (date.getUTCMonth() !== this.viewDate.getUTCMonth()) {
1237
+ this._trigger('changeMonth', this.viewDate);
1238
+ }
1239
+ }
1240
+ this._setDate(date);
1241
+ },
1242
+
1243
+ // Clicked on prev or next
1244
+ navArrowsClick: function(e){
1245
+ var $target = $(e.currentTarget);
1246
+ var dir = $target.hasClass('prev') ? -1 : 1;
1247
+ if (this.viewMode !== 0){
1248
+ dir *= DPGlobal.viewModes[this.viewMode].navStep * 12;
1249
+ }
1250
+ this.viewDate = this.moveMonth(this.viewDate, dir);
1251
+ this._trigger(DPGlobal.viewModes[this.viewMode].e, this.viewDate);
1252
+ this.fill();
1253
+ },
1254
+
1309
1255
  _toggle_multidate: function(date){
1310
1256
  var ix = this.dates.contains(date);
1311
1257
  if (!date){
@@ -1332,7 +1278,7 @@
1332
1278
  _setDate: function(date, which){
1333
1279
  if (!which || which === 'date')
1334
1280
  this._toggle_multidate(date && new Date(date));
1335
- if (!which || which === 'view')
1281
+ if ((!which && this.o.updateViewDate) || which === 'view')
1336
1282
  this.viewDate = date && new Date(date);
1337
1283
 
1338
1284
  this.fill();
@@ -1340,9 +1286,7 @@
1340
1286
  if (!which || which !== 'view') {
1341
1287
  this._trigger('changeDate');
1342
1288
  }
1343
- if (this.inputField){
1344
- this.inputField.change();
1345
- }
1289
+ this.inputField.trigger('change');
1346
1290
  if (this.o.autoclose && (!which || which === 'date')){
1347
1291
  this.hide();
1348
1292
  }
@@ -1385,8 +1329,7 @@
1385
1329
  new_month = month + dir;
1386
1330
  new_date.setUTCMonth(new_month);
1387
1331
  // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
1388
- if (new_month < 0 || new_month > 11)
1389
- new_month = (new_month + 12) % 12;
1332
+ new_month = (new_month + 12) % 12;
1390
1333
  }
1391
1334
  else {
1392
1335
  // For magnitudes >1, move one month at a time...
@@ -1480,17 +1423,14 @@
1480
1423
 
1481
1424
  if (newViewDate)
1482
1425
  this._trigger('changeYear', this.viewDate);
1483
- }
1484
- else if (e.shiftKey){
1426
+ } else if (e.shiftKey){
1485
1427
  newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
1486
1428
 
1487
1429
  if (newViewDate)
1488
1430
  this._trigger('changeMonth', this.viewDate);
1489
- }
1490
- else if (e.keyCode === 37 || e.keyCode === 39){
1431
+ } else if (e.keyCode === 37 || e.keyCode === 39){
1491
1432
  newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');
1492
- }
1493
- else if (!this.weekOfDateIsDisabled(focusDate)){
1433
+ } else if (!this.weekOfDateIsDisabled(focusDate)){
1494
1434
  newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');
1495
1435
  }
1496
1436
  } else if (this.viewMode === 1) {
@@ -1542,38 +1482,38 @@
1542
1482
  this._trigger('changeDate');
1543
1483
  else
1544
1484
  this._trigger('clearDate');
1545
- if (this.inputField){
1546
- this.inputField.change();
1547
- }
1485
+ this.inputField.trigger('change');
1548
1486
  }
1549
1487
  },
1550
1488
 
1551
- showMode: function(dir){
1552
- if (dir){
1553
- this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir));
1554
- }
1489
+ setViewMode: function(viewMode){
1490
+ this.viewMode = viewMode;
1555
1491
  this.picker
1556
1492
  .children('div')
1557
1493
  .hide()
1558
- .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
1494
+ .filter('.datepicker-' + DPGlobal.viewModes[this.viewMode].clsName)
1559
1495
  .show();
1560
1496
  this.updateNavArrows();
1497
+ this._trigger('changeViewMode', new Date(this.viewDate));
1561
1498
  }
1562
1499
  };
1563
1500
 
1564
1501
  var DateRangePicker = function(element, options){
1565
- $(element).data('datepicker', this);
1502
+ $.data(element, 'datepicker', this);
1566
1503
  this.element = $(element);
1567
1504
  this.inputs = $.map(options.inputs, function(i){
1568
1505
  return i.jquery ? i[0] : i;
1569
1506
  });
1570
1507
  delete options.inputs;
1571
1508
 
1509
+ this.keepEmptyValues = options.keepEmptyValues;
1510
+ delete options.keepEmptyValues;
1511
+
1572
1512
  datepickerPlugin.call($(this.inputs), options)
1573
1513
  .on('changeDate', $.proxy(this.dateUpdated, this));
1574
1514
 
1575
1515
  this.pickers = $.map(this.inputs, function(i){
1576
- return $(i).data('datepicker');
1516
+ return $.data(i, 'datepicker');
1577
1517
  });
1578
1518
  this.updateDates();
1579
1519
  };
@@ -1600,13 +1540,14 @@
1600
1540
  return;
1601
1541
  this.updating = true;
1602
1542
 
1603
- var dp = $(e.target).data('datepicker');
1543
+ var dp = $.data(e.target, 'datepicker');
1604
1544
 
1605
- if (typeof(dp) === "undefined") {
1545
+ if (dp === undefined) {
1606
1546
  return;
1607
1547
  }
1608
1548
 
1609
1549
  var new_date = dp.getUTCDate(),
1550
+ keep_empty_values = this.keepEmptyValues,
1610
1551
  i = $.inArray(e.target, this.inputs),
1611
1552
  j = i - 1,
1612
1553
  k = i + 1,
@@ -1615,7 +1556,7 @@
1615
1556
  return;
1616
1557
 
1617
1558
  $.each(this.pickers, function(i, p){
1618
- if (!p.getUTCDate())
1559
+ if (!p.getUTCDate() && (p === dp || !keep_empty_values))
1619
1560
  p.setUTCDate(new_date);
1620
1561
  });
1621
1562
 
@@ -1624,8 +1565,7 @@
1624
1565
  while (j >= 0 && new_date < this.dates[j]){
1625
1566
  this.pickers[j--].setUTCDate(new_date);
1626
1567
  }
1627
- }
1628
- else if (new_date > this.dates[k]){
1568
+ } else if (new_date > this.dates[k]){
1629
1569
  // Date being moved later/right
1630
1570
  while (k < l && new_date > this.dates[k]){
1631
1571
  this.pickers[k++].setUTCDate(new_date);
@@ -1635,10 +1575,12 @@
1635
1575
 
1636
1576
  delete this.updating;
1637
1577
  },
1638
- remove: function(){
1639
- $.map(this.pickers, function(p){ p.remove(); });
1578
+ destroy: function(){
1579
+ $.map(this.pickers, function(p){ p.destroy(); });
1580
+ $(this.inputs).off('changeDate', this.dateUpdated);
1640
1581
  delete this.element.data().datepicker;
1641
- }
1582
+ },
1583
+ remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead')
1642
1584
  };
1643
1585
 
1644
1586
  function opts_from_el(el, prefix){
@@ -1739,6 +1681,7 @@
1739
1681
  endDate: Infinity,
1740
1682
  forceParse: true,
1741
1683
  format: 'mm/dd/yyyy',
1684
+ keepEmptyValues: false,
1742
1685
  keyboardNavigation: true,
1743
1686
  language: 'en',
1744
1687
  minViewMode: 0,
@@ -1751,6 +1694,7 @@
1751
1694
  startView: 0,
1752
1695
  todayBtn: false,
1753
1696
  todayHighlight: false,
1697
+ updateViewDate: true,
1754
1698
  weekStart: 0,
1755
1699
  disableTouchKeyboard: false,
1756
1700
  enableOnReadonly: true,
@@ -1760,9 +1704,10 @@
1760
1704
  immediateUpdates: false,
1761
1705
  title: '',
1762
1706
  templates: {
1763
- leftArrow: '&laquo;',
1764
- rightArrow: '&raquo;'
1765
- }
1707
+ leftArrow: '&#x00AB;',
1708
+ rightArrow: '&#x00BB;'
1709
+ },
1710
+ showWeekDays: true
1766
1711
  };
1767
1712
  var locale_opts = $.fn.datepicker.locale_opts = [
1768
1713
  'format',
@@ -1784,38 +1729,37 @@
1784
1729
  };
1785
1730
 
1786
1731
  var DPGlobal = {
1787
- modes: [
1732
+ viewModes: [
1788
1733
  {
1734
+ names: ['days', 'month'],
1789
1735
  clsName: 'days',
1790
- navFnc: 'Month',
1791
- navStep: 1
1736
+ e: 'changeMonth'
1792
1737
  },
1793
1738
  {
1739
+ names: ['months', 'year'],
1794
1740
  clsName: 'months',
1795
- navFnc: 'FullYear',
1741
+ e: 'changeYear',
1796
1742
  navStep: 1
1797
1743
  },
1798
1744
  {
1745
+ names: ['years', 'decade'],
1799
1746
  clsName: 'years',
1800
- navFnc: 'FullYear',
1747
+ e: 'changeDecade',
1801
1748
  navStep: 10
1802
1749
  },
1803
1750
  {
1751
+ names: ['decades', 'century'],
1804
1752
  clsName: 'decades',
1805
- navFnc: 'FullDecade',
1753
+ e: 'changeCentury',
1806
1754
  navStep: 100
1807
1755
  },
1808
1756
  {
1757
+ names: ['centuries', 'millennium'],
1809
1758
  clsName: 'centuries',
1810
- navFnc: 'FullCentury',
1759
+ e: 'changeMillennium',
1811
1760
  navStep: 1000
1812
- }],
1813
- isLeapYear: function(year){
1814
- return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
1815
- },
1816
- getDaysInMonth: function(year, month){
1817
- return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
1818
- },
1761
+ }
1762
+ ],
1819
1763
  validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
1820
1764
  nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g,
1821
1765
  parseFormat: function(format){
@@ -1838,10 +1782,8 @@
1838
1782
  if (typeof format === 'string')
1839
1783
  format = DPGlobal.parseFormat(format);
1840
1784
  if (format.toValue)
1841
- return format.toValue(date, format, language);
1842
- var part_re = /([\-+]\d+)([dmwy])/,
1843
- parts = date.match(/([\-+]\d+)([dmwy])/g),
1844
- fn_map = {
1785
+ return format.toValue(date, format, language);
1786
+ var fn_map = {
1845
1787
  d: 'moveDay',
1846
1788
  m: 'moveMonth',
1847
1789
  w: 'moveWeek',
@@ -1852,37 +1794,23 @@
1852
1794
  today: '+0d',
1853
1795
  tomorrow: '+1d'
1854
1796
  },
1855
- part, dir, i, fn;
1856
- if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
1797
+ parts, part, dir, i, fn;
1798
+ if (date in dateAliases){
1799
+ date = dateAliases[date];
1800
+ }
1801
+ if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/i.test(date)){
1802
+ parts = date.match(/([\-+]\d+)([dmwy])/gi);
1857
1803
  date = new Date();
1858
1804
  for (i=0; i < parts.length; i++){
1859
- part = part_re.exec(parts[i]);
1860
- dir = parseInt(part[1]);
1861
- fn = fn_map[part[2]];
1805
+ part = parts[i].match(/([\-+]\d+)([dmwy])/i);
1806
+ dir = Number(part[1]);
1807
+ fn = fn_map[part[2].toLowerCase()];
1862
1808
  date = Datepicker.prototype[fn](date, dir);
1863
1809
  }
1864
- return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
1865
- }
1866
-
1867
- if (typeof dateAliases[date] !== 'undefined') {
1868
- date = dateAliases[date];
1869
- parts = date.match(/([\-+]\d+)([dmwy])/g);
1870
-
1871
- if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
1872
- date = new Date();
1873
- for (i=0; i < parts.length; i++){
1874
- part = part_re.exec(parts[i]);
1875
- dir = parseInt(part[1]);
1876
- fn = fn_map[part[2]];
1877
- date = Datepicker.prototype[fn](date, dir);
1878
- }
1879
-
1880
- return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
1881
- }
1810
+ return Datepicker.prototype._zero_utc_time(date);
1882
1811
  }
1883
1812
 
1884
1813
  parts = date && date.match(this.nonpunctuation) || [];
1885
- date = new Date();
1886
1814
 
1887
1815
  function applyNearbyYear(year, threshold){
1888
1816
  if (threshold === true)
@@ -1906,9 +1834,6 @@
1906
1834
  yyyy: function(d,v){
1907
1835
  return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
1908
1836
  },
1909
- yy: function(d,v){
1910
- return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
1911
- },
1912
1837
  m: function(d,v){
1913
1838
  if (isNaN(d))
1914
1839
  return d;
@@ -1925,6 +1850,7 @@
1925
1850
  }
1926
1851
  },
1927
1852
  val, filtered;
1853
+ setters_map['yy'] = setters_map['yyyy'];
1928
1854
  setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1929
1855
  setters_map['dd'] = setters_map['d'];
1930
1856
  date = UTCToday();
@@ -2006,9 +1932,9 @@
2006
1932
  '<th colspan="7" class="datepicker-title"></th>'+
2007
1933
  '</tr>'+
2008
1934
  '<tr>'+
2009
- '<th class="prev">&laquo;</th>'+
1935
+ '<th class="prev">'+defaults.templates.leftArrow+'</th>'+
2010
1936
  '<th colspan="5" class="datepicker-switch"></th>'+
2011
- '<th class="next">&raquo;</th>'+
1937
+ '<th class="next">'+defaults.templates.rightArrow+'</th>'+
2012
1938
  '</tr>'+
2013
1939
  '</thead>',
2014
1940
  contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
@@ -2072,7 +1998,15 @@
2072
1998
 
2073
1999
  /* DATEPICKER VERSION
2074
2000
  * =================== */
2075
- $.fn.datepicker.version = '1.6.4';
2001
+ $.fn.datepicker.version = '1.7.1';
2002
+
2003
+ $.fn.datepicker.deprecated = function(msg){
2004
+ var console = window.console;
2005
+ if (console && console.warn) {
2006
+ console.warn('DEPRECATED: ' + msg);
2007
+ }
2008
+ };
2009
+
2076
2010
 
2077
2011
  /* DATEPICKER DATA-API
2078
2012
  * ================== */