ndr_ui 4.1.1 → 4.1.3

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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +116 -0
  3. data/CODE_OF_CONDUCT.md +13 -0
  4. data/Rakefile +3 -3
  5. data/lib/ndr_ui/version.rb +1 -1
  6. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/css/bootstrap-datepicker.css +39 -36
  7. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/css/bootstrap-datepicker.css.map +1 -0
  8. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/css/bootstrap-datepicker.min.css +7 -0
  9. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/css/bootstrap-datepicker.standalone.css +40 -37
  10. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/css/bootstrap-datepicker.standalone.css.map +1 -0
  11. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/css/bootstrap-datepicker.standalone.min.css +7 -0
  12. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/css/bootstrap-datepicker3.css +53 -50
  13. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/css/bootstrap-datepicker3.css.map +1 -0
  14. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/css/bootstrap-datepicker3.min.css +7 -0
  15. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/css/bootstrap-datepicker3.standalone.css +55 -52
  16. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/css/bootstrap-datepicker3.standalone.css.map +1 -0
  17. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/css/bootstrap-datepicker3.standalone.min.css +7 -0
  18. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/js/bootstrap-datepicker.js +355 -450
  19. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/js/bootstrap-datepicker.min.js +8 -0
  20. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker-en-CA.min.js +1 -0
  21. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.ar-tn.min.js +1 -0
  22. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.bn.min.js +1 -0
  23. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.br.min.js +1 -0
  24. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.cs.min.js +1 -1
  25. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.da.min.js +1 -0
  26. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.en-IE.min.js +1 -0
  27. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.en-NZ.min.js +1 -0
  28. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.en-ZA.min.js +1 -0
  29. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.eu.min.js +1 -1
  30. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.hi.min.js +1 -0
  31. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.hy.min.js +1 -0
  32. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.ka.min.js +1 -1
  33. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.kh.min.js +1 -0
  34. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.kk.min.js +1 -1
  35. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.km.min.js +1 -0
  36. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.kr.min.js +1 -1
  37. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.lv.min.js +1 -1
  38. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.oc.min.js +1 -0
  39. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.pl.min.js +1 -0
  40. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.ro.min.js +1 -1
  41. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.rs-latin.min.js +1 -1
  42. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.rs.min.js +1 -1
  43. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.ru.min.js +1 -1
  44. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.si.min.js +1 -0
  45. data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.sl.min.js +1 -1
  46. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.ta.min.js +1 -0
  47. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.tg.min.js +1 -0
  48. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.uz-cyrl.min.js +1 -0
  49. data/vendor/assets/bootstrap-datepicker-1.7.1-dist/locales/bootstrap-datepicker.uz-latn.min.js +1 -0
  50. data/vendor/assets/datepicker-scss-fix/bootstrap-datepicker-scss-fix.scss +1 -1
  51. metadata +102 -89
  52. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker.css.map +0 -1
  53. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker.min.css +0 -9
  54. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker.min.css.map +0 -1
  55. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker.standalone.css.map +0 -1
  56. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker.standalone.min.css +0 -9
  57. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker.standalone.min.css.map +0 -1
  58. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker3.css.map +0 -1
  59. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker3.min.css +0 -9
  60. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker3.min.css.map +0 -1
  61. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker3.standalone.css.map +0 -1
  62. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker3.standalone.min.css +0 -9
  63. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/css/bootstrap-datepicker3.standalone.min.css.map +0 -1
  64. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/js/bootstrap-datepicker.min.js +0 -9
  65. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/locales/bootstrap-datepicker.da.min.js +0 -1
  66. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/locales/bootstrap-datepicker.hy.min.js +0 -1
  67. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/locales/bootstrap-datepicker.kh.min.js +0 -1
  68. data/vendor/assets/bootstrap-datepicker-1.6.0-dist/locales/bootstrap-datepicker.pl.min.js +0 -1
  69. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.ar.min.js +0 -0
  70. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.az.min.js +0 -0
  71. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.bg.min.js +0 -0
  72. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.bs.min.js +0 -0
  73. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.ca.min.js +0 -0
  74. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.cy.min.js +0 -0
  75. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.de.min.js +0 -0
  76. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.el.min.js +0 -0
  77. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.en-AU.min.js +0 -0
  78. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.en-GB.min.js +0 -0
  79. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.eo.min.js +0 -0
  80. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.es.min.js +0 -0
  81. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.et.min.js +0 -0
  82. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.fa.min.js +0 -0
  83. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.fi.min.js +0 -0
  84. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.fo.min.js +0 -0
  85. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.fr-CH.min.js +0 -0
  86. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.fr.min.js +0 -0
  87. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.gl.min.js +0 -0
  88. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.he.min.js +0 -0
  89. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.hr.min.js +0 -0
  90. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.hu.min.js +0 -0
  91. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.id.min.js +0 -0
  92. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.is.min.js +0 -0
  93. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.it-CH.min.js +0 -0
  94. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.it.min.js +0 -0
  95. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.ja.min.js +0 -0
  96. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.ko.min.js +0 -0
  97. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.lt.min.js +0 -0
  98. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.me.min.js +0 -0
  99. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.mk.min.js +0 -0
  100. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.mn.min.js +0 -0
  101. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.ms.min.js +0 -0
  102. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.nb.min.js +0 -0
  103. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.nl-BE.min.js +0 -0
  104. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.nl.min.js +0 -0
  105. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.no.min.js +0 -0
  106. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.pt-BR.min.js +0 -0
  107. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.pt.min.js +0 -0
  108. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.sk.min.js +0 -0
  109. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.sq.min.js +0 -0
  110. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.sr-latin.min.js +0 -0
  111. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.sr.min.js +0 -0
  112. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.sv.min.js +0 -0
  113. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.sw.min.js +0 -0
  114. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.th.min.js +0 -0
  115. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.tr.min.js +0 -0
  116. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.uk.min.js +0 -0
  117. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.vi.min.js +0 -0
  118. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.zh-CN.min.js +0 -0
  119. /data/vendor/assets/{bootstrap-datepicker-1.6.0-dist → bootstrap-datepicker-1.7.1-dist}/locales/bootstrap-datepicker.zh-TW.min.js +0 -0
@@ -1,10 +1,10 @@
1
1
  /*!
2
- * Datepicker for Bootstrap v1.6.0 (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();
@@ -92,12 +96,12 @@
92
96
  this.focusDate = null;
93
97
 
94
98
  this.element = $(element);
95
- this.isInline = false;
96
99
  this.isInput = this.element.is('input');
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.element.find('input').length;
99
102
  if (this.component && this.component.length === 0)
100
103
  this.component = false;
104
+ this.isInline = !this.component && this.element.is('div');
101
105
 
102
106
  this.picker = $(DPGlobal.template);
103
107
 
@@ -105,6 +109,7 @@
105
109
  if (this._check_template(this.o.templates.leftArrow)) {
106
110
  this.picker.find('.prev').html(this.o.templates.leftArrow);
107
111
  }
112
+
108
113
  if (this._check_template(this.o.templates.rightArrow)) {
109
114
  this.picker.find('.next').html(this.o.templates.rightArrow);
110
115
  }
@@ -123,29 +128,29 @@
123
128
  this.picker.addClass('datepicker-rtl');
124
129
  }
125
130
 
126
- 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
+ }
127
137
 
128
- if (this.o.calendarWeeks)
129
- this.picker.find('thead .datepicker-title, tfoot .today, tfoot .clear')
130
- .attr('colspan', function(i, val){
131
- return parseInt(val) + 1;
132
- });
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
+ });
133
145
 
134
146
  this._allow_update = false;
135
-
136
- this.setStartDate(this._o.startDate);
137
- this.setEndDate(this._o.endDate);
138
- this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
139
- this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted);
140
- this.setDatesDisabled(this.o.datesDisabled);
147
+ this.setViewMode(this.o.startView);
148
+ this._allow_update = true;
141
149
 
142
150
  this.fillDow();
143
151
  this.fillMonths();
144
152
 
145
- this._allow_update = true;
146
-
147
153
  this.update();
148
- this.showMode();
149
154
 
150
155
  if (this.isInline){
151
156
  this.show();
@@ -155,23 +160,21 @@
155
160
  Datepicker.prototype = {
156
161
  constructor: Datepicker,
157
162
 
158
- _resolveViewName: function(view, default_value){
159
- if (view === 0 || view === 'days' || view === 'month') {
160
- return 0;
161
- }
162
- if (view === 1 || view === 'months' || view === 'year') {
163
- return 1;
164
- }
165
- if (view === 2 || view === 'years' || view === 'decade') {
166
- return 2;
167
- }
168
- if (view === 3 || view === 'decades' || view === 'century') {
169
- return 3;
170
- }
171
- if (view === 4 || view === 'centuries' || view === 'millennium') {
172
- return 4;
173
- }
174
- 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);
175
178
  },
176
179
 
177
180
  _check_template: function(tmp){
@@ -210,13 +213,12 @@
210
213
  o.language = lang;
211
214
 
212
215
  // Retrieve view index from any aliases
213
- o.startView = this._resolveViewName(o.startView, 0);
214
- o.minViewMode = this._resolveViewName(o.minViewMode, 0);
215
- 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);
216
219
 
217
- // Check that the start view is between min and max
218
- o.startView = Math.min(o.startView, o.maxViewMode);
219
- 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));
220
222
 
221
223
  // true, false, or Number > 0
222
224
  if (o.multidate !== true){
@@ -253,27 +255,14 @@
253
255
  }
254
256
  }
255
257
 
256
- o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
257
- if (!$.isArray(o.daysOfWeekDisabled))
258
- o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
259
- o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
260
- return parseInt(d, 10);
261
- });
262
-
263
- o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[];
264
- if (!$.isArray(o.daysOfWeekHighlighted))
265
- o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/);
266
- o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){
267
- return parseInt(d, 10);
268
- });
258
+ o.daysOfWeekDisabled = this._resolveDaysOfWeek(o.daysOfWeekDisabled||[]);
259
+ o.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted||[]);
269
260
 
270
261
  o.datesDisabled = o.datesDisabled||[];
271
262
  if (!$.isArray(o.datesDisabled)) {
272
- var datesDisabled = [];
273
- datesDisabled.push(DPGlobal.parseDate(o.datesDisabled, format, o.language, o.assumeNearbyYear));
274
- o.datesDisabled = datesDisabled;
263
+ o.datesDisabled = o.datesDisabled.split(',');
275
264
  }
276
- o.datesDisabled = $.map(o.datesDisabled,function(d){
265
+ o.datesDisabled = $.map(o.datesDisabled, function(d){
277
266
  return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);
278
267
  });
279
268
 
@@ -308,7 +297,9 @@
308
297
  });
309
298
  o.orientation.y = _plc[0] || 'auto';
310
299
  }
311
- 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) {
312
303
  var year = o.defaultViewDate.year || new Date().getFullYear();
313
304
  var month = o.defaultViewDate.month || 0;
314
305
  var day = o.defaultViewDate.day || 1;
@@ -325,8 +316,7 @@
325
316
  if (evs[i].length === 2){
326
317
  ch = undefined;
327
318
  ev = evs[i][1];
328
- }
329
- else if (evs[i].length === 3){
319
+ } else if (evs[i].length === 3){
330
320
  ch = evs[i][1];
331
321
  ev = evs[i][2];
332
322
  }
@@ -339,8 +329,7 @@
339
329
  if (evs[i].length === 2){
340
330
  ch = undefined;
341
331
  ev = evs[i][1];
342
- }
343
- else if (evs[i].length === 3){
332
+ } else if (evs[i].length === 3){
344
333
  ch = evs[i][1];
345
334
  ev = evs[i][2];
346
335
  }
@@ -366,22 +355,21 @@
366
355
  [this.element, events]
367
356
  ];
368
357
  }
369
- else if (this.component && this.hasInput) { // component: input + button
358
+ // component: input + button
359
+ else if (this.component && this.inputField.length) {
370
360
  this._events = [
371
361
  // For components that are not readonly, allow keyboard nav
372
- [this.element.find('input'), events],
362
+ [this.inputField, events],
373
363
  [this.component, {
374
364
  click: $.proxy(this.show, this)
375
365
  }]
376
366
  ];
377
367
  }
378
- else if (this.element.is('div')){ // inline datepicker
379
- this.isInline = true;
380
- }
381
368
  else {
382
369
  this._events = [
383
370
  [this.element, {
384
- click: $.proxy(this.show, this)
371
+ click: $.proxy(this.show, this),
372
+ keydown: $.proxy(this.keydown, this)
385
373
  }]
386
374
  ];
387
375
  }
@@ -413,18 +401,24 @@
413
401
  [this.picker, {
414
402
  click: $.proxy(this.click, this)
415
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
+ }],
416
410
  [$(window), {
417
411
  resize: $.proxy(this.place, this)
418
412
  }],
419
413
  [$(document), {
420
- mousedown: $.proxy(function(e){
414
+ 'mousedown touchstart': $.proxy(function(e){
421
415
  // Clicked outside the datepicker, hide it
422
416
  if (!(
423
417
  this.element.is(e.target) ||
424
418
  this.element.find(e.target).length ||
425
419
  this.picker.is(e.target) ||
426
420
  this.picker.find(e.target).length ||
427
- this.picker.hasClass('datepicker-inline')
421
+ this.isInline
428
422
  )){
429
423
  this.hide();
430
424
  }
@@ -453,13 +447,13 @@
453
447
  this.element.trigger({
454
448
  type: event,
455
449
  date: local_date,
450
+ viewMode: this.viewMode,
456
451
  dates: $.map(this.dates, this._utc_to_local),
457
452
  format: $.proxy(function(ix, format){
458
453
  if (arguments.length === 0){
459
454
  ix = this.dates.length - 1;
460
455
  format = this.o.format;
461
- }
462
- else if (typeof ix === 'string'){
456
+ } else if (typeof ix === 'string'){
463
457
  format = ix;
464
458
  ix = this.dates.length - 1;
465
459
  }
@@ -471,8 +465,7 @@
471
465
  },
472
466
 
473
467
  show: function(){
474
- var element = this.component ? this.element.find('input') : this.element;
475
- if (element.attr('readonly') && this.o.enableOnReadonly === false)
468
+ if (this.inputField.prop('disabled') || (this.inputField.prop('readonly') && this.o.enableOnReadonly === false))
476
469
  return;
477
470
  if (!this.isInline)
478
471
  this.picker.appendTo(this.o.container);
@@ -487,23 +480,14 @@
487
480
  },
488
481
 
489
482
  hide: function(){
490
- if (this.isInline)
491
- return this;
492
- if (!this.picker.is(':visible'))
483
+ if (this.isInline || !this.picker.is(':visible'))
493
484
  return this;
494
485
  this.focusDate = null;
495
486
  this.picker.hide().detach();
496
487
  this._detachSecondaryEvents();
497
- this.viewMode = this.o.startView;
498
- this.showMode();
499
-
500
- if (
501
- this.o.forceParse &&
502
- (
503
- this.isInput && this.element.val() ||
504
- this.hasInput && this.element.find('input').val()
505
- )
506
- )
488
+ this.setViewMode(this.o.startView);
489
+
490
+ if (this.o.forceParse && this.inputField.val())
507
491
  this.setValue();
508
492
  this._trigger('hide');
509
493
  return this;
@@ -521,25 +505,33 @@
521
505
  return this;
522
506
  },
523
507
 
524
- paste: function(evt){
508
+ paste: function(e){
525
509
  var dateString;
526
- if (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types
527
- && $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) {
528
- dateString = evt.originalEvent.clipboardData.getData('text/plain');
529
- }
530
- 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) {
531
514
  dateString = window.clipboardData.getData('Text');
532
- }
533
- else {
515
+ } else {
534
516
  return;
535
517
  }
536
518
  this.setDate(dateString);
537
519
  this.update();
538
- evt.preventDefault();
520
+ e.preventDefault();
539
521
  },
540
522
 
541
523
  _utc_to_local: function(utc){
542
- 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;
543
535
  },
544
536
  _local_to_utc: function(local){
545
537
  return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
@@ -548,7 +540,7 @@
548
540
  return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
549
541
  },
550
542
  _zero_utc_time: function(utc){
551
- return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
543
+ return utc && UTCDate(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate());
552
544
  },
553
545
 
554
546
  getDates: function(){
@@ -567,7 +559,7 @@
567
559
 
568
560
  getUTCDate: function(){
569
561
  var selected_date = this.dates.get(-1);
570
- if (typeof selected_date !== 'undefined') {
562
+ if (selected_date !== undefined) {
571
563
  return new Date(selected_date);
572
564
  } else {
573
565
  return null;
@@ -575,17 +567,7 @@
575
567
  },
576
568
 
577
569
  clearDates: function(){
578
- var element;
579
- if (this.isInput) {
580
- element = this.element;
581
- } else if (this.component) {
582
- element = this.element.find('input');
583
- }
584
-
585
- if (element) {
586
- element.val('');
587
- }
588
-
570
+ this.inputField.val('');
589
571
  this.update();
590
572
  this._trigger('changeDate');
591
573
 
@@ -593,6 +575,7 @@
593
575
  this.hide();
594
576
  }
595
577
  },
578
+
596
579
  setDates: function(){
597
580
  var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
598
581
  this.update.apply(this, args);
@@ -603,26 +586,17 @@
603
586
 
604
587
  setUTCDates: function(){
605
588
  var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
606
- this.update.apply(this, $.map(args, this._utc_to_local));
607
- this._trigger('changeDate');
608
- this.setValue();
589
+ this.setDates.apply(this, $.map(args, this._utc_to_local));
609
590
  return this;
610
591
  },
611
592
 
612
593
  setDate: alias('setDates'),
613
594
  setUTCDate: alias('setUTCDates'),
614
- remove: alias('destroy'),
595
+ remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead'),
615
596
 
616
597
  setValue: function(){
617
598
  var formatted = this.getFormattedDate();
618
- if (!this.isInput){
619
- if (this.component){
620
- this.element.find('input').val(formatted);
621
- }
622
- }
623
- else {
624
- this.element.val(formatted);
625
- }
599
+ this.inputField.val(formatted);
626
600
  return this;
627
601
  },
628
602
 
@@ -661,7 +635,6 @@
661
635
  setDaysOfWeekDisabled: function(daysOfWeekDisabled){
662
636
  this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
663
637
  this.update();
664
- this.updateNavArrows();
665
638
  return this;
666
639
  },
667
640
 
@@ -674,7 +647,7 @@
674
647
  setDatesDisabled: function(datesDisabled){
675
648
  this._process_options({datesDisabled: datesDisabled});
676
649
  this.update();
677
- this.updateNavArrows();
650
+ return this;
678
651
  },
679
652
 
680
653
  place: function(){
@@ -688,17 +661,17 @@
688
661
  scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),
689
662
  appendOffset = container.offset();
690
663
 
691
- var parentsZindex = [];
664
+ var parentsZindex = [0];
692
665
  this.element.parents().each(function(){
693
666
  var itemZIndex = $(this).css('z-index');
694
- if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));
667
+ if (itemZIndex !== 'auto' && Number(itemZIndex) !== 0) parentsZindex.push(Number(itemZIndex));
695
668
  });
696
669
  var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;
697
670
  var offset = this.component ? this.component.parent().offset() : this.element.offset();
698
671
  var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
699
672
  var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
700
- var left = offset.left - appendOffset.left,
701
- top = offset.top - appendOffset.top;
673
+ var left = offset.left - appendOffset.left;
674
+ var top = offset.top - appendOffset.top;
702
675
 
703
676
  if (this.o.container !== 'body') {
704
677
  top += scrollTop;
@@ -726,8 +699,13 @@
726
699
  this.picker.addClass('datepicker-orient-right');
727
700
  left += width - calendarWidth;
728
701
  } else {
729
- // Default to left
730
- 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
+ }
731
709
  }
732
710
  }
733
711
 
@@ -778,11 +756,10 @@
778
756
  dates.push(date);
779
757
  }, this));
780
758
  fromArgs = true;
781
- }
782
- else {
759
+ } else {
783
760
  dates = this.isInput
784
761
  ? this.element.val()
785
- : this.element.data('date') || this.element.find('input').val();
762
+ : this.element.data('date') || this.inputField.val();
786
763
  if (dates && this.o.multidate)
787
764
  dates = dates.split(this.o.multidateSeparator);
788
765
  else
@@ -801,59 +778,63 @@
801
778
  }, this), true);
802
779
  this.dates.replace(dates);
803
780
 
804
- if (this.dates.length)
805
- this.viewDate = new Date(this.dates.get(-1));
806
- else if (this.viewDate < this.o.startDate)
807
- this.viewDate = new Date(this.o.startDate);
808
- else if (this.viewDate > this.o.endDate)
809
- this.viewDate = new Date(this.o.endDate);
810
- else
811
- 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
+ }
812
791
 
813
792
  if (fromArgs){
814
793
  // setting date by clicking
815
794
  this.setValue();
795
+ this.element.change();
816
796
  }
817
- else if (dates.length){
797
+ else if (this.dates.length){
818
798
  // setting date by typing
819
- if (String(oldDates) !== String(this.dates))
799
+ if (String(oldDates) !== String(this.dates) && fromArgs) {
820
800
  this._trigger('changeDate');
801
+ this.element.change();
802
+ }
821
803
  }
822
- if (!this.dates.length && oldDates.length)
804
+ if (!this.dates.length && oldDates.length) {
823
805
  this._trigger('clearDate');
806
+ this.element.change();
807
+ }
824
808
 
825
809
  this.fill();
826
- this.element.change();
827
810
  return this;
828
811
  },
829
812
 
830
813
  fillDow: function(){
814
+ if (this.o.showWeekDays) {
831
815
  var dowCnt = this.o.weekStart,
832
816
  html = '<tr>';
833
817
  if (this.o.calendarWeeks){
834
- this.picker.find('.datepicker-days .datepicker-switch')
835
- .attr('colspan', function(i, val){
836
- return parseInt(val) + 1;
837
- });
838
818
  html += '<th class="cw">&#160;</th>';
839
819
  }
840
820
  while (dowCnt < this.o.weekStart + 7){
841
821
  html += '<th class="dow';
842
- if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) > -1)
822
+ if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) !== -1)
843
823
  html += ' disabled';
844
824
  html += '">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
845
825
  }
846
826
  html += '</tr>';
847
827
  this.picker.find('.datepicker-days thead').append(html);
828
+ }
848
829
  },
849
830
 
850
831
  fillMonths: function(){
851
832
  var localDate = this._utc_to_local(this.viewDate);
852
- var html = '',
853
- i = 0;
854
- while (i < 12){
855
- var focused = localDate && localDate.getMonth() === i ? ' focused' : '';
856
- 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>';
857
838
  }
858
839
  this.picker.find('.datepicker-months td').html(html);
859
840
  },
@@ -872,27 +853,26 @@
872
853
  var cls = [],
873
854
  year = this.viewDate.getUTCFullYear(),
874
855
  month = this.viewDate.getUTCMonth(),
875
- today = new Date();
856
+ today = UTCToday();
876
857
  if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
877
858
  cls.push('old');
878
- }
879
- else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
859
+ } else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
880
860
  cls.push('new');
881
861
  }
882
862
  if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
883
863
  cls.push('focused');
884
- // Compare internal UTC date with local today, not UTC today
885
- if (this.o.todayHighlight &&
886
- date.getUTCFullYear() === today.getFullYear() &&
887
- date.getUTCMonth() === today.getMonth() &&
888
- date.getUTCDate() === today.getDate()){
864
+ // Compare internal UTC date with UTC today, not local today
865
+ if (this.o.todayHighlight && isUTCEquals(date, today)) {
889
866
  cls.push('today');
890
867
  }
891
868
  if (this.dates.contains(date) !== -1)
892
869
  cls.push('active');
893
- if (!this.dateWithinRange(date) || this.dateIsDisabled(date)){
870
+ if (!this.dateWithinRange(date)){
894
871
  cls.push('disabled');
895
872
  }
873
+ if (this.dateIsDisabled(date)){
874
+ cls.push('disabled', 'disabled-date');
875
+ }
896
876
  if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){
897
877
  cls.push('highlighted');
898
878
  }
@@ -914,47 +894,44 @@
914
894
  return cls;
915
895
  },
916
896
 
917
- _fill_yearsView: function(selector, cssClass, factor, step, currentYear, startYear, endYear, callback){
918
- var html, view, year, steps, startStep, endStep, thisYear, i, classes, tooltip, before;
919
-
920
- html = '';
921
- view = this.picker.find(selector);
922
- year = parseInt(currentYear / factor, 10) * factor;
923
- startStep = parseInt(startYear / step, 10) * step;
924
- endStep = parseInt(endYear / step, 10) * step;
925
- steps = $.map(this.dates, function(d){
926
- 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;
927
906
  });
928
907
 
929
- view.find('.datepicker-switch').text(year + '-' + (year + step * 9));
930
-
931
- thisYear = year - step;
932
- for (i = -1; i < 11; i += 1) {
908
+ var classes, tooltip, before;
909
+ for (var currVal = startVal - step; currVal <= endVal + step; currVal += step) {
933
910
  classes = [cssClass];
934
911
  tooltip = null;
935
912
 
936
- if (i === -1) {
913
+ if (currVal === startVal - step) {
937
914
  classes.push('old');
938
- } else if (i === 10) {
915
+ } else if (currVal === endVal + step) {
939
916
  classes.push('new');
940
917
  }
941
- if ($.inArray(thisYear, steps) !== -1) {
918
+ if ($.inArray(currVal, selected) !== -1) {
942
919
  classes.push('active');
943
920
  }
944
- if (thisYear < startStep || thisYear > endStep) {
921
+ if (currVal < startYear || currVal > endYear) {
945
922
  classes.push('disabled');
946
923
  }
947
- if (thisYear === this.viewDate.getFullYear()) {
924
+ if (currVal === focusedVal) {
948
925
  classes.push('focused');
949
926
  }
950
927
 
951
- if (callback !== $.noop) {
952
- before = callback(new Date(thisYear, 0, 1));
928
+ if (beforeFn !== $.noop) {
929
+ before = beforeFn(new Date(currVal, 0, 1));
953
930
  if (before === undefined) {
954
931
  before = {};
955
- } else if (typeof(before) === 'boolean') {
932
+ } else if (typeof before === 'boolean') {
956
933
  before = {enabled: before};
957
- } else if (typeof(before) === 'string') {
934
+ } else if (typeof before === 'string') {
958
935
  before = {classes: before};
959
936
  }
960
937
  if (before.enabled === false) {
@@ -968,9 +945,10 @@
968
945
  }
969
946
  }
970
947
 
971
- html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + thisYear + '</span>';
972
- thisYear += step;
948
+ html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + currVal + '</span>';
973
949
  }
950
+
951
+ view.find('.datepicker-switch').text(startVal + '-' + endVal);
974
952
  view.find('td').html(html);
975
953
  },
976
954
 
@@ -993,18 +971,17 @@
993
971
  .text(DPGlobal.formatDate(d, titleFormat, this.o.language));
994
972
  this.picker.find('tfoot .today')
995
973
  .text(todaytxt)
996
- .toggle(this.o.todayBtn !== false);
974
+ .css('display', this.o.todayBtn === true || this.o.todayBtn === 'linked' ? 'table-cell' : 'none');
997
975
  this.picker.find('tfoot .clear')
998
976
  .text(cleartxt)
999
- .toggle(this.o.clearBtn !== false);
977
+ .css('display', this.o.clearBtn === true ? 'table-cell' : 'none');
1000
978
  this.picker.find('thead .datepicker-title')
1001
979
  .text(this.o.title)
1002
- .toggle(this.o.title !== '');
980
+ .css('display', typeof this.o.title === 'string' && this.o.title !== '' ? 'table-cell' : 'none');
1003
981
  this.updateNavArrows();
1004
982
  this.fillMonths();
1005
- var prevMonth = UTCDate(year, month-1, 28),
1006
- day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
1007
- prevMonth.setUTCDate(day);
983
+ var prevMonth = UTCDate(year, month, 0),
984
+ day = prevMonth.getUTCDate();
1008
985
  prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
1009
986
  var nextMonth = new Date(prevMonth);
1010
987
  if (prevMonth.getUTCFullYear() < 100){
@@ -1013,36 +990,38 @@
1013
990
  nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
1014
991
  nextMonth = nextMonth.valueOf();
1015
992
  var html = [];
1016
- var clsName;
993
+ var weekDay, clsName;
1017
994
  while (prevMonth.valueOf() < nextMonth){
1018
- if (prevMonth.getUTCDay() === this.o.weekStart){
995
+ weekDay = prevMonth.getUTCDay();
996
+ if (weekDay === this.o.weekStart){
1019
997
  html.push('<tr>');
1020
998
  if (this.o.calendarWeeks){
1021
999
  // ISO 8601: First week contains first thursday.
1022
1000
  // ISO also states week starts on Monday, but we can be more abstract here.
1023
1001
  var
1024
1002
  // Start of current week: based on weekstart/current date
1025
- ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
1003
+ ws = new Date(+prevMonth + (this.o.weekStart - weekDay - 7) % 7 * 864e5),
1026
1004
  // Thursday of this week
1027
1005
  th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
1028
1006
  // First Thursday of year, year from thursday
1029
- 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),
1030
1008
  // Calendar week: ms between thursdays, div ms per day, div 7 days
1031
- calWeek = (th - yth) / 864e5 / 7 + 1;
1009
+ calWeek = (th - yth) / 864e5 / 7 + 1;
1032
1010
  html.push('<td class="cw">'+ calWeek +'</td>');
1033
-
1034
1011
  }
1035
1012
  }
1036
1013
  clsName = this.getClassNames(prevMonth);
1037
1014
  clsName.push('day');
1038
1015
 
1016
+ var content = prevMonth.getUTCDate();
1017
+
1039
1018
  if (this.o.beforeShowDay !== $.noop){
1040
1019
  before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
1041
1020
  if (before === undefined)
1042
1021
  before = {};
1043
- else if (typeof(before) === 'boolean')
1022
+ else if (typeof before === 'boolean')
1044
1023
  before = {enabled: before};
1045
- else if (typeof(before) === 'string')
1024
+ else if (typeof before === 'string')
1046
1025
  before = {classes: before};
1047
1026
  if (before.enabled === false)
1048
1027
  clsName.push('disabled');
@@ -1050,24 +1029,33 @@
1050
1029
  clsName = clsName.concat(before.classes.split(/\s+/));
1051
1030
  if (before.tooltip)
1052
1031
  tooltip = before.tooltip;
1032
+ if (before.content)
1033
+ content = before.content;
1053
1034
  }
1054
1035
 
1055
- clsName = $.unique(clsName);
1056
- html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
1036
+ //Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2)
1037
+ //Fallback to unique function for older jquery versions
1038
+ if ($.isFunction($.uniqueSort)) {
1039
+ clsName = $.uniqueSort(clsName);
1040
+ } else {
1041
+ clsName = $.unique(clsName);
1042
+ }
1043
+
1044
+ html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + ' data-date="' + prevMonth.getTime().toString() + '">' + content + '</td>');
1057
1045
  tooltip = null;
1058
- if (prevMonth.getUTCDay() === this.o.weekEnd){
1046
+ if (weekDay === this.o.weekEnd){
1059
1047
  html.push('</tr>');
1060
1048
  }
1061
- prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
1049
+ prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
1062
1050
  }
1063
- this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
1051
+ this.picker.find('.datepicker-days tbody').html(html.join(''));
1064
1052
 
1065
1053
  var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';
1066
1054
  var months = this.picker.find('.datepicker-months')
1067
1055
  .find('.datepicker-switch')
1068
1056
  .text(this.o.maxViewMode < 2 ? monthsTitle : year)
1069
1057
  .end()
1070
- .find('span').removeClass('active');
1058
+ .find('tbody span').removeClass('active');
1071
1059
 
1072
1060
  $.each(this.dates, function(i, d){
1073
1061
  if (d.getUTCFullYear() === year)
@@ -1091,9 +1079,9 @@
1091
1079
  var before = that.o.beforeShowMonth(moDate);
1092
1080
  if (before === undefined)
1093
1081
  before = {};
1094
- else if (typeof(before) === 'boolean')
1082
+ else if (typeof before === 'boolean')
1095
1083
  before = {enabled: before};
1096
- else if (typeof(before) === 'string')
1084
+ else if (typeof before === 'string')
1097
1085
  before = {classes: before};
1098
1086
  if (before.enabled === false && !$(month).hasClass('disabled'))
1099
1087
  $(month).addClass('disabled');
@@ -1109,7 +1097,6 @@
1109
1097
  '.datepicker-years',
1110
1098
  'year',
1111
1099
  10,
1112
- 1,
1113
1100
  year,
1114
1101
  startYear,
1115
1102
  endYear,
@@ -1121,7 +1108,6 @@
1121
1108
  '.datepicker-decades',
1122
1109
  'decade',
1123
1110
  100,
1124
- 10,
1125
1111
  year,
1126
1112
  startYear,
1127
1113
  endYear,
@@ -1133,7 +1119,6 @@
1133
1119
  '.datepicker-centuries',
1134
1120
  'century',
1135
1121
  1000,
1136
- 100,
1137
1122
  year,
1138
1123
  startYear,
1139
1124
  endYear,
@@ -1147,73 +1132,53 @@
1147
1132
 
1148
1133
  var d = new Date(this.viewDate),
1149
1134
  year = d.getUTCFullYear(),
1150
- 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;
1151
1143
  switch (this.viewMode){
1152
1144
  case 0:
1153
- if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
1154
- this.picker.find('.prev').css({visibility: 'hidden'});
1155
- }
1156
- else {
1157
- this.picker.find('.prev').css({visibility: 'visible'});
1158
- }
1159
- if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
1160
- this.picker.find('.next').css({visibility: 'hidden'});
1161
- }
1162
- else {
1163
- this.picker.find('.next').css({visibility: 'visible'});
1164
- }
1145
+ prevIsDisabled = year <= startYear && month <= startMonth;
1146
+ nextIsDisabled = year >= endYear && month >= endMonth;
1165
1147
  break;
1166
- case 1:
1167
- case 2:
1168
- case 3:
1169
1148
  case 4:
1170
- if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){
1171
- this.picker.find('.prev').css({visibility: 'hidden'});
1172
- }
1173
- else {
1174
- this.picker.find('.prev').css({visibility: 'visible'});
1175
- }
1176
- if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){
1177
- this.picker.find('.next').css({visibility: 'hidden'});
1178
- }
1179
- else {
1180
- this.picker.find('.next').css({visibility: 'visible'});
1181
- }
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;
1182
1160
  break;
1183
1161
  }
1162
+
1163
+ this.picker.find('.prev').toggleClass('disabled', prevIsDisabled);
1164
+ this.picker.find('.next').toggleClass('disabled', nextIsDisabled);
1184
1165
  },
1185
1166
 
1186
1167
  click: function(e){
1187
1168
  e.preventDefault();
1188
1169
  e.stopPropagation();
1189
1170
 
1190
- var target, dir, day, year, month, monthChanged, yearChanged;
1171
+ var target, dir, day, year, month;
1191
1172
  target = $(e.target);
1192
1173
 
1193
1174
  // Clicked on the switch
1194
- if (target.hasClass('datepicker-switch')){
1195
- this.showMode(1);
1196
- }
1197
-
1198
- // Clicked on prev or next
1199
- var navArrow = target.closest('.prev, .next');
1200
- if (navArrow.length > 0) {
1201
- dir = DPGlobal.modes[this.viewMode].navStep * (navArrow.hasClass('prev') ? -1 : 1);
1202
- if (this.viewMode === 0){
1203
- this.viewDate = this.moveMonth(this.viewDate, dir);
1204
- this._trigger('changeMonth', this.viewDate);
1205
- } else {
1206
- this.viewDate = this.moveYear(this.viewDate, dir);
1207
- if (this.viewMode === 1){
1208
- this._trigger('changeYear', this.viewDate);
1209
- }
1210
- }
1211
- this.fill();
1175
+ if (target.hasClass('datepicker-switch') && this.viewMode !== this.o.maxViewMode){
1176
+ this.setViewMode(this.viewMode + 1);
1212
1177
  }
1213
1178
 
1214
1179
  // Clicked on today button
1215
- if (target.hasClass('today')){
1216
- this.showMode(-2);
1180
+ if (target.hasClass('today') && !target.hasClass('day')){
1181
+ this.setViewMode(0);
1217
1182
  this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');
1218
1183
  }
1219
1184
 
@@ -1223,104 +1188,70 @@
1223
1188
  }
1224
1189
 
1225
1190
  if (!target.hasClass('disabled')){
1226
- // Clicked on a day
1227
- if (target.hasClass('day')){
1228
- day = parseInt(target.text(), 10) || 1;
1229
- year = this.viewDate.getUTCFullYear();
1230
- month = this.viewDate.getUTCMonth();
1231
-
1232
- // From last month
1233
- if (target.hasClass('old')){
1234
- if (month === 0) {
1235
- month = 11;
1236
- year = year - 1;
1237
- monthChanged = true;
1238
- yearChanged = true;
1239
- } else {
1240
- month = month - 1;
1241
- monthChanged = true;
1242
- }
1243
- }
1244
-
1245
- // From next month
1246
- if (target.hasClass('new')) {
1247
- if (month === 11){
1248
- month = 0;
1249
- year = year + 1;
1250
- monthChanged = true;
1251
- yearChanged = true;
1252
- } else {
1253
- month = month + 1;
1254
- monthChanged = true;
1255
- }
1256
- }
1257
- this._setDate(UTCDate(year, month, day));
1258
- if (yearChanged) {
1259
- this._trigger('changeYear', this.viewDate);
1260
- }
1261
- if (monthChanged) {
1262
- this._trigger('changeMonth', this.viewDate);
1263
- }
1264
- }
1265
-
1266
- // Clicked on a month
1267
- if (target.hasClass('month')) {
1268
- this.viewDate.setUTCDate(1);
1269
- day = 1;
1270
- month = target.parent().find('span').index(target);
1271
- year = this.viewDate.getUTCFullYear();
1272
- this.viewDate.setUTCMonth(month);
1273
- this._trigger('changeMonth', this.viewDate);
1274
- if (this.o.minViewMode === 1){
1275
- this._setDate(UTCDate(year, month, day));
1276
- this.showMode();
1277
- } else {
1278
- this.showMode(-1);
1279
- }
1280
- this.fill();
1281
- }
1282
-
1283
- // Clicked on a year
1284
- if (target.hasClass('year')
1191
+ // Clicked on a month, year, decade, century
1192
+ if (target.hasClass('month')
1193
+ || target.hasClass('year')
1285
1194
  || target.hasClass('decade')
1286
1195
  || target.hasClass('century')) {
1287
1196
  this.viewDate.setUTCDate(1);
1288
1197
 
1289
1198
  day = 1;
1290
- month = 0;
1291
- year = parseInt(target.text(), 10)||0;
1292
- this.viewDate.setUTCFullYear(year);
1293
-
1294
- if (target.hasClass('year')){
1295
- this._trigger('changeYear', this.viewDate);
1296
- if (this.o.minViewMode === 2){
1297
- this._setDate(UTCDate(year, month, day));
1298
- }
1299
- }
1300
- if (target.hasClass('decade')){
1301
- this._trigger('changeDecade', this.viewDate);
1302
- if (this.o.minViewMode === 3){
1303
- this._setDate(UTCDate(year, month, day));
1304
- }
1305
- }
1306
- if (target.hasClass('century')){
1307
- this._trigger('changeCentury', this.viewDate);
1308
- if (this.o.minViewMode === 4){
1309
- this._setDate(UTCDate(year, month, day));
1310
- }
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);
1311
1207
  }
1312
1208
 
1313
- this.showMode(-1);
1314
- 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
+ }
1315
1217
  }
1316
1218
  }
1317
1219
 
1318
1220
  if (this.picker.is(':visible') && this._focused_from){
1319
- $(this._focused_from).focus();
1221
+ this._focused_from.focus();
1320
1222
  }
1321
1223
  delete this._focused_from;
1322
1224
  },
1323
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
+
1324
1255
  _toggle_multidate: function(date){
1325
1256
  var ix = this.dates.contains(date);
1326
1257
  if (!date){
@@ -1347,7 +1278,7 @@
1347
1278
  _setDate: function(date, which){
1348
1279
  if (!which || which === 'date')
1349
1280
  this._toggle_multidate(date && new Date(date));
1350
- if (!which || which === 'view')
1281
+ if ((!which && this.o.updateViewDate) || which === 'view')
1351
1282
  this.viewDate = date && new Date(date);
1352
1283
 
1353
1284
  this.fill();
@@ -1355,16 +1286,7 @@
1355
1286
  if (!which || which !== 'view') {
1356
1287
  this._trigger('changeDate');
1357
1288
  }
1358
- var element;
1359
- if (this.isInput){
1360
- element = this.element;
1361
- }
1362
- else if (this.component){
1363
- element = this.element.find('input');
1364
- }
1365
- if (element){
1366
- element.change();
1367
- }
1289
+ this.inputField.trigger('change');
1368
1290
  if (this.o.autoclose && (!which || which === 'date')){
1369
1291
  this.hide();
1370
1292
  }
@@ -1407,8 +1329,7 @@
1407
1329
  new_month = month + dir;
1408
1330
  new_date.setUTCMonth(new_month);
1409
1331
  // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
1410
- if (new_month < 0 || new_month > 11)
1411
- new_month = (new_month + 12) % 12;
1332
+ new_month = (new_month + 12) % 12;
1412
1333
  }
1413
1334
  else {
1414
1335
  // For magnitudes >1, move one month at a time...
@@ -1502,17 +1423,14 @@
1502
1423
 
1503
1424
  if (newViewDate)
1504
1425
  this._trigger('changeYear', this.viewDate);
1505
- }
1506
- else if (e.shiftKey){
1426
+ } else if (e.shiftKey){
1507
1427
  newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
1508
1428
 
1509
1429
  if (newViewDate)
1510
1430
  this._trigger('changeMonth', this.viewDate);
1511
- }
1512
- else if (e.keyCode === 37 || e.keyCode === 39){
1431
+ } else if (e.keyCode === 37 || e.keyCode === 39){
1513
1432
  newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');
1514
- }
1515
- else if (!this.weekOfDateIsDisabled(focusDate)){
1433
+ } else if (!this.weekOfDateIsDisabled(focusDate)){
1516
1434
  newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');
1517
1435
  }
1518
1436
  } else if (this.viewMode === 1) {
@@ -1564,45 +1482,38 @@
1564
1482
  this._trigger('changeDate');
1565
1483
  else
1566
1484
  this._trigger('clearDate');
1567
- var element;
1568
- if (this.isInput){
1569
- element = this.element;
1570
- }
1571
- else if (this.component){
1572
- element = this.element.find('input');
1573
- }
1574
- if (element){
1575
- element.change();
1576
- }
1485
+ this.inputField.trigger('change');
1577
1486
  }
1578
1487
  },
1579
1488
 
1580
- showMode: function(dir){
1581
- if (dir){
1582
- this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir));
1583
- }
1489
+ setViewMode: function(viewMode){
1490
+ this.viewMode = viewMode;
1584
1491
  this.picker
1585
1492
  .children('div')
1586
1493
  .hide()
1587
- .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
1494
+ .filter('.datepicker-' + DPGlobal.viewModes[this.viewMode].clsName)
1588
1495
  .show();
1589
1496
  this.updateNavArrows();
1497
+ this._trigger('changeViewMode', new Date(this.viewDate));
1590
1498
  }
1591
1499
  };
1592
1500
 
1593
1501
  var DateRangePicker = function(element, options){
1594
- $(element).data('datepicker', this);
1502
+ $.data(element, 'datepicker', this);
1595
1503
  this.element = $(element);
1596
1504
  this.inputs = $.map(options.inputs, function(i){
1597
1505
  return i.jquery ? i[0] : i;
1598
1506
  });
1599
1507
  delete options.inputs;
1600
1508
 
1509
+ this.keepEmptyValues = options.keepEmptyValues;
1510
+ delete options.keepEmptyValues;
1511
+
1601
1512
  datepickerPlugin.call($(this.inputs), options)
1602
1513
  .on('changeDate', $.proxy(this.dateUpdated, this));
1603
1514
 
1604
1515
  this.pickers = $.map(this.inputs, function(i){
1605
- return $(i).data('datepicker');
1516
+ return $.data(i, 'datepicker');
1606
1517
  });
1607
1518
  this.updateDates();
1608
1519
  };
@@ -1629,13 +1540,14 @@
1629
1540
  return;
1630
1541
  this.updating = true;
1631
1542
 
1632
- var dp = $(e.target).data('datepicker');
1543
+ var dp = $.data(e.target, 'datepicker');
1633
1544
 
1634
- if (typeof(dp) === "undefined") {
1545
+ if (dp === undefined) {
1635
1546
  return;
1636
1547
  }
1637
1548
 
1638
1549
  var new_date = dp.getUTCDate(),
1550
+ keep_empty_values = this.keepEmptyValues,
1639
1551
  i = $.inArray(e.target, this.inputs),
1640
1552
  j = i - 1,
1641
1553
  k = i + 1,
@@ -1644,7 +1556,7 @@
1644
1556
  return;
1645
1557
 
1646
1558
  $.each(this.pickers, function(i, p){
1647
- if (!p.getUTCDate())
1559
+ if (!p.getUTCDate() && (p === dp || !keep_empty_values))
1648
1560
  p.setUTCDate(new_date);
1649
1561
  });
1650
1562
 
@@ -1653,8 +1565,7 @@
1653
1565
  while (j >= 0 && new_date < this.dates[j]){
1654
1566
  this.pickers[j--].setUTCDate(new_date);
1655
1567
  }
1656
- }
1657
- else if (new_date > this.dates[k]){
1568
+ } else if (new_date > this.dates[k]){
1658
1569
  // Date being moved later/right
1659
1570
  while (k < l && new_date > this.dates[k]){
1660
1571
  this.pickers[k++].setUTCDate(new_date);
@@ -1664,10 +1575,12 @@
1664
1575
 
1665
1576
  delete this.updating;
1666
1577
  },
1667
- remove: function(){
1668
- $.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);
1669
1581
  delete this.element.data().datepicker;
1670
- }
1582
+ },
1583
+ remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead')
1671
1584
  };
1672
1585
 
1673
1586
  function opts_from_el(el, prefix){
@@ -1768,6 +1681,7 @@
1768
1681
  endDate: Infinity,
1769
1682
  forceParse: true,
1770
1683
  format: 'mm/dd/yyyy',
1684
+ keepEmptyValues: false,
1771
1685
  keyboardNavigation: true,
1772
1686
  language: 'en',
1773
1687
  minViewMode: 0,
@@ -1780,6 +1694,7 @@
1780
1694
  startView: 0,
1781
1695
  todayBtn: false,
1782
1696
  todayHighlight: false,
1697
+ updateViewDate: true,
1783
1698
  weekStart: 0,
1784
1699
  disableTouchKeyboard: false,
1785
1700
  enableOnReadonly: true,
@@ -1789,9 +1704,10 @@
1789
1704
  immediateUpdates: false,
1790
1705
  title: '',
1791
1706
  templates: {
1792
- leftArrow: '&laquo;',
1793
- rightArrow: '&raquo;'
1794
- }
1707
+ leftArrow: '&#x00AB;',
1708
+ rightArrow: '&#x00BB;'
1709
+ },
1710
+ showWeekDays: true
1795
1711
  };
1796
1712
  var locale_opts = $.fn.datepicker.locale_opts = [
1797
1713
  'format',
@@ -1813,38 +1729,37 @@
1813
1729
  };
1814
1730
 
1815
1731
  var DPGlobal = {
1816
- modes: [
1732
+ viewModes: [
1817
1733
  {
1734
+ names: ['days', 'month'],
1818
1735
  clsName: 'days',
1819
- navFnc: 'Month',
1820
- navStep: 1
1736
+ e: 'changeMonth'
1821
1737
  },
1822
1738
  {
1739
+ names: ['months', 'year'],
1823
1740
  clsName: 'months',
1824
- navFnc: 'FullYear',
1741
+ e: 'changeYear',
1825
1742
  navStep: 1
1826
1743
  },
1827
1744
  {
1745
+ names: ['years', 'decade'],
1828
1746
  clsName: 'years',
1829
- navFnc: 'FullYear',
1747
+ e: 'changeDecade',
1830
1748
  navStep: 10
1831
1749
  },
1832
1750
  {
1751
+ names: ['decades', 'century'],
1833
1752
  clsName: 'decades',
1834
- navFnc: 'FullDecade',
1753
+ e: 'changeCentury',
1835
1754
  navStep: 100
1836
1755
  },
1837
1756
  {
1757
+ names: ['centuries', 'millennium'],
1838
1758
  clsName: 'centuries',
1839
- navFnc: 'FullCentury',
1759
+ e: 'changeMillennium',
1840
1760
  navStep: 1000
1841
- }],
1842
- isLeapYear: function(year){
1843
- return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
1844
- },
1845
- getDaysInMonth: function(year, month){
1846
- return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
1847
- },
1761
+ }
1762
+ ],
1848
1763
  validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
1849
1764
  nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g,
1850
1765
  parseFormat: function(format){
@@ -1867,10 +1782,8 @@
1867
1782
  if (typeof format === 'string')
1868
1783
  format = DPGlobal.parseFormat(format);
1869
1784
  if (format.toValue)
1870
- return format.toValue(date, format, language);
1871
- var part_re = /([\-+]\d+)([dmwy])/,
1872
- parts = date.match(/([\-+]\d+)([dmwy])/g),
1873
- fn_map = {
1785
+ return format.toValue(date, format, language);
1786
+ var fn_map = {
1874
1787
  d: 'moveDay',
1875
1788
  m: 'moveMonth',
1876
1789
  w: 'moveWeek',
@@ -1881,37 +1794,23 @@
1881
1794
  today: '+0d',
1882
1795
  tomorrow: '+1d'
1883
1796
  },
1884
- part, dir, i, fn;
1885
- 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);
1886
1803
  date = new Date();
1887
1804
  for (i=0; i < parts.length; i++){
1888
- part = part_re.exec(parts[i]);
1889
- dir = parseInt(part[1]);
1890
- 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()];
1891
1808
  date = Datepicker.prototype[fn](date, dir);
1892
1809
  }
1893
- return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
1894
- }
1895
-
1896
- if (typeof dateAliases[date] !== 'undefined') {
1897
- date = dateAliases[date];
1898
- parts = date.match(/([\-+]\d+)([dmwy])/g);
1899
-
1900
- if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
1901
- date = new Date();
1902
- for (i=0; i < parts.length; i++){
1903
- part = part_re.exec(parts[i]);
1904
- dir = parseInt(part[1]);
1905
- fn = fn_map[part[2]];
1906
- date = Datepicker.prototype[fn](date, dir);
1907
- }
1908
-
1909
- return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
1910
- }
1810
+ return Datepicker.prototype._zero_utc_time(date);
1911
1811
  }
1912
1812
 
1913
1813
  parts = date && date.match(this.nonpunctuation) || [];
1914
- date = new Date();
1915
1814
 
1916
1815
  function applyNearbyYear(year, threshold){
1917
1816
  if (threshold === true)
@@ -1935,9 +1834,6 @@
1935
1834
  yyyy: function(d,v){
1936
1835
  return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
1937
1836
  },
1938
- yy: function(d,v){
1939
- return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
1940
- },
1941
1837
  m: function(d,v){
1942
1838
  if (isNaN(d))
1943
1839
  return d;
@@ -1954,6 +1850,7 @@
1954
1850
  }
1955
1851
  },
1956
1852
  val, filtered;
1853
+ setters_map['yy'] = setters_map['yyyy'];
1957
1854
  setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1958
1855
  setters_map['dd'] = setters_map['d'];
1959
1856
  date = UTCToday();
@@ -2035,9 +1932,9 @@
2035
1932
  '<th colspan="7" class="datepicker-title"></th>'+
2036
1933
  '</tr>'+
2037
1934
  '<tr>'+
2038
- '<th class="prev">&laquo;</th>'+
1935
+ '<th class="prev">'+defaults.templates.leftArrow+'</th>'+
2039
1936
  '<th colspan="5" class="datepicker-switch"></th>'+
2040
- '<th class="next">&raquo;</th>'+
1937
+ '<th class="next">'+defaults.templates.rightArrow+'</th>'+
2041
1938
  '</tr>'+
2042
1939
  '</thead>',
2043
1940
  contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
@@ -2052,7 +1949,7 @@
2052
1949
  };
2053
1950
  DPGlobal.template = '<div class="datepicker">'+
2054
1951
  '<div class="datepicker-days">'+
2055
- '<table class=" table-condensed">'+
1952
+ '<table class="table-condensed">'+
2056
1953
  DPGlobal.headTemplate+
2057
1954
  '<tbody></tbody>'+
2058
1955
  DPGlobal.footTemplate+
@@ -2101,7 +1998,15 @@
2101
1998
 
2102
1999
  /* DATEPICKER VERSION
2103
2000
  * =================== */
2104
- $.fn.datepicker.version = '1.6.0';
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
+
2105
2010
 
2106
2011
  /* DATEPICKER DATA-API
2107
2012
  * ================== */