bootstrap-datepicker-rails 1.4.0 → 1.8.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +5 -5
  2. data/Rakefile +3 -3
  3. data/lib/bootstrap-datepicker-rails/version.rb +1 -1
  4. data/vendor/assets/javascripts/bootstrap-datepicker/core.js +772 -519
  5. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker-en-CA.js +22 -0
  6. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ar-tn.js +15 -0
  7. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.az.js +3 -3
  8. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.bg.js +3 -3
  9. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.bn.js +19 -0
  10. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.br.js +18 -0
  11. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.bs.js +3 -3
  12. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ca.js +4 -3
  13. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.cs.js +5 -4
  14. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.cy.js +3 -3
  15. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.da.js +8 -4
  16. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.de.js +4 -3
  17. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.el.js +3 -3
  18. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.en-AU.js +18 -0
  19. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.en-CA.js +18 -0
  20. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.en-GB.js +4 -3
  21. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.en-IE.js +17 -0
  22. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.en-NZ.js +17 -0
  23. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.en-ZA.js +17 -0
  24. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.eo.js +17 -0
  25. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.es.js +4 -3
  26. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.et.js +3 -3
  27. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.eu.js +10 -6
  28. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.fi.js +4 -3
  29. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.fo.js +3 -3
  30. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.fr-CH.js +4 -3
  31. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.fr.js +4 -3
  32. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.gl.js +3 -3
  33. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.hi.js +18 -0
  34. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.hr.js +3 -3
  35. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.hu.js +8 -6
  36. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.hy.js +5 -4
  37. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.id.js +3 -3
  38. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.is.js +3 -3
  39. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.it-CH.js +3 -3
  40. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.it.js +4 -3
  41. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ja.js +4 -3
  42. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ka.js +4 -4
  43. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.kh.js +9 -3
  44. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.kk.js +4 -4
  45. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.km.js +15 -0
  46. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ko.js +18 -0
  47. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.kr.js +9 -3
  48. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.lt.js +7 -4
  49. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.lv.js +5 -3
  50. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.me.js +3 -3
  51. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.mk.js +3 -3
  52. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.mn.js +17 -0
  53. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ms.js +5 -4
  54. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.nb.js +5 -4
  55. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.nl-BE.js +4 -3
  56. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.nl.js +4 -3
  57. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.no.js +10 -8
  58. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.oc.js +17 -0
  59. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.pl.js +11 -10
  60. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.pt-BR.js +6 -4
  61. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.pt.js +6 -4
  62. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ro.js +5 -4
  63. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.rs-latin.js +7 -3
  64. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.rs.js +7 -3
  65. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ru.js +5 -4
  66. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.si.js +18 -0
  67. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.sk.js +7 -4
  68. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.sl.js +5 -4
  69. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.sq.js +3 -3
  70. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.sr-latin.js +3 -3
  71. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.sr.js +3 -3
  72. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.sv.js +5 -5
  73. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.sw.js +3 -3
  74. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.ta.js +18 -0
  75. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.tg.js +19 -0
  76. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.tk.js +18 -0
  77. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.tr.js +3 -3
  78. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.uk.js +3 -3
  79. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.uz-cyrl.js +18 -0
  80. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.uz-latn.js +18 -0
  81. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.vi.js +3 -3
  82. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.js +7 -6
  83. data/vendor/assets/javascripts/bootstrap-datepicker/locales/bootstrap-datepicker.zh-TW.js +6 -5
  84. data/vendor/assets/stylesheets/bootstrap-datepicker.css +70 -67
  85. data/vendor/assets/stylesheets/bootstrap-datepicker3.css +419 -489
  86. metadata +24 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 12275b3675337b334e802880958e6feed1c83d69
4
- data.tar.gz: 2e857161bcceda4eadcff09b70d4bafc5310bba6
2
+ SHA256:
3
+ metadata.gz: 70c6665475b9b31fc8a1fe921aa52837e05552cbf55fe800253ea9e92da360d5
4
+ data.tar.gz: 1f06c1bac2b05f49bc350fa6e1d2787c1be9953e949702823a7d5d34f3143592
5
5
  SHA512:
6
- metadata.gz: 84753fc92289d03b14ed3cfaf1f525a634eb6d5a46590493cabdd4ac5a93756e47a1df0478a158ea35d342d6d162a170ac4e3f0af89a93c9a847ece3a2e96088
7
- data.tar.gz: 32f8bca100026f3e6f283be25e3ec2de9a5583a7ad65ce5d703e5540d4460606e24d749d6c4193c22bcf32553ec80cefeb0283f9fd2777d3f7d02b1ae4c7e57d
6
+ metadata.gz: d87d48c6eed9e8bdb128e2a77f3cb9a732e367461973bb00811c99983829a07cebd7bfdd1d09a9cb261b47fdef29ab797162773e2c843e1cb7b5d193ae99542a
7
+ data.tar.gz: a3e2ff59d67d76be2aad06713c1c6b1b3defcea5f0731dfe59421c143d88726ec4b2333c31471814291af8a2079d4d7031b20874fad3b10979aa76f65467138e
data/Rakefile CHANGED
@@ -9,13 +9,13 @@ task :update do
9
9
  checkout_branch = "tags/#{ARGV.last}"
10
10
  task ARGV.last.to_sym {}
11
11
  else
12
- checkout_branch = "`git describe --abbrev=0`"
12
+ checkout_branch = "`git describe --abbrev=0 --tags`"
13
13
  end
14
14
 
15
15
  if Dir.exist?('bootstrap-datepicker-src')
16
16
  system("cd bootstrap-datepicker-src && git checkout master && git pull && git checkout #{checkout_branch}")
17
17
  else
18
- system("git clone git://github.com/eternicode/bootstrap-datepicker.git bootstrap-datepicker-src")
18
+ system("git clone git://github.com/uxsolutions/bootstrap-datepicker.git bootstrap-datepicker-src")
19
19
  system("cd bootstrap-datepicker-src && git checkout #{checkout_branch}")
20
20
  end
21
21
 
@@ -26,7 +26,7 @@ task :update do
26
26
  system("git status")
27
27
 
28
28
  puts "\n"
29
- puts "bootstrap-datepicker version: #{JSON.parse(File.read('./bootstrap-datepicker-src/bower.json'))['version']}"
29
+ puts "bootstrap-datepicker version: #{JSON.parse(File.read('./bootstrap-datepicker-src/package.json'))['version']}"
30
30
  puts "bootstrap-datepicker-rails version: #{BootstrapDatepickerRails::Rails::VERSION}"
31
31
  end
32
32
 
@@ -1,5 +1,5 @@
1
1
  module BootstrapDatepickerRails
2
2
  module Rails
3
- VERSION = "1.4.0"
3
+ VERSION = "1.8.0.1"
4
4
  end
5
5
  end
@@ -1,11 +1,18 @@
1
1
  /*!
2
- * Datepicker for Bootstrap v1.4.0 (https://github.com/eternicode/bootstrap-datepicker)
2
+ * Datepicker for Bootstrap v1.8.0 (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($, undefined){
8
-
5
+ */
6
+
7
+ (function(factory){
8
+ if (typeof define === 'function' && define.amd) {
9
+ define(['jquery'], factory);
10
+ } else if (typeof exports === 'object') {
11
+ factory(require('jquery'));
12
+ } else {
13
+ factory(jQuery);
14
+ }
15
+ }(function($, undefined){
9
16
  function UTCDate(){
10
17
  return new Date(Date.UTC.apply(Date, arguments));
11
18
  }
@@ -20,11 +27,18 @@
20
27
  date1.getUTCDate() === date2.getUTCDate()
21
28
  );
22
29
  }
23
- function alias(method){
30
+ function alias(method, deprecationMsg){
24
31
  return function(){
32
+ if (deprecationMsg !== undefined) {
33
+ $.fn.datepicker.deprecated(deprecationMsg);
34
+ }
35
+
25
36
  return this[method].apply(this, arguments);
26
37
  };
27
38
  }
39
+ function isValidDate(d) {
40
+ return d && !isNaN(d.getTime());
41
+ }
28
42
 
29
43
  var DateArray = (function(){
30
44
  var extras = {
@@ -36,7 +50,8 @@
36
50
  // $.inArray doesn't work with Dates
37
51
  var val = d && d.valueOf();
38
52
  for (var i=0, l=this.length; i < l; i++)
39
- 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)
40
55
  return i;
41
56
  return -1;
42
57
  },
@@ -73,6 +88,7 @@
73
88
  // Picker object
74
89
 
75
90
  var Datepicker = function(element, options){
91
+ $.data(element, 'datepicker', this);
76
92
  this._process_options(options);
77
93
 
78
94
  this.dates = new DateArray();
@@ -80,14 +96,24 @@
80
96
  this.focusDate = null;
81
97
 
82
98
  this.element = $(element);
83
- this.isInline = false;
84
99
  this.isInput = this.element.is('input');
100
+ this.inputField = this.isInput ? this.element : this.element.find('input');
85
101
  this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
86
- this.hasInput = this.component && this.element.find('input').length;
87
102
  if (this.component && this.component.length === 0)
88
103
  this.component = false;
104
+ this.isInline = !this.component && this.element.is('div');
89
105
 
90
106
  this.picker = $(DPGlobal.template);
107
+
108
+ // Checking templates and inserting
109
+ if (this._check_template(this.o.templates.leftArrow)) {
110
+ this.picker.find('.prev').html(this.o.templates.leftArrow);
111
+ }
112
+
113
+ if (this._check_template(this.o.templates.rightArrow)) {
114
+ this.picker.find('.next').html(this.o.templates.rightArrow);
115
+ }
116
+
91
117
  this._buildEvents();
92
118
  this._attachEvents();
93
119
 
@@ -102,28 +128,29 @@
102
128
  this.picker.addClass('datepicker-rtl');
103
129
  }
104
130
 
105
- 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
+ }
106
137
 
107
- if (this.o.calendarWeeks)
108
- this.picker.find('tfoot .today, tfoot .clear')
109
- .attr('colspan', function(i, val){
110
- return parseInt(val) + 1;
111
- });
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
+ });
112
145
 
113
146
  this._allow_update = false;
114
-
115
- this.setStartDate(this._o.startDate);
116
- this.setEndDate(this._o.endDate);
117
- this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
118
- this.setDatesDisabled(this.o.datesDisabled);
147
+ this.setViewMode(this.o.startView);
148
+ this._allow_update = true;
119
149
 
120
150
  this.fillDow();
121
151
  this.fillMonths();
122
152
 
123
- this._allow_update = true;
124
-
125
153
  this.update();
126
- this.showMode();
127
154
 
128
155
  if (this.isInline){
129
156
  this.show();
@@ -133,6 +160,42 @@
133
160
  Datepicker.prototype = {
134
161
  constructor: Datepicker,
135
162
 
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);
178
+ },
179
+
180
+ _check_template: function(tmp){
181
+ try {
182
+ // If empty
183
+ if (tmp === undefined || tmp === "") {
184
+ return false;
185
+ }
186
+ // If no html, everything ok
187
+ if ((tmp.match(/[<>]/g) || []).length <= 0) {
188
+ return true;
189
+ }
190
+ // Checking if html is fine
191
+ var jDom = $(tmp);
192
+ return jDom.length > 0;
193
+ }
194
+ catch (ex) {
195
+ return false;
196
+ }
197
+ },
198
+
136
199
  _process_options: function(opts){
137
200
  // Store raw options for reference
138
201
  this._o = $.extend({}, this._o, opts);
@@ -149,33 +212,13 @@
149
212
  }
150
213
  o.language = lang;
151
214
 
152
- switch (o.startView){
153
- case 2:
154
- case 'decade':
155
- o.startView = 2;
156
- break;
157
- case 1:
158
- case 'year':
159
- o.startView = 1;
160
- break;
161
- default:
162
- o.startView = 0;
163
- }
215
+ // Retrieve view index from any aliases
216
+ o.startView = this._resolveViewName(o.startView);
217
+ o.minViewMode = this._resolveViewName(o.minViewMode);
218
+ o.maxViewMode = this._resolveViewName(o.maxViewMode);
164
219
 
165
- switch (o.minViewMode){
166
- case 1:
167
- case 'months':
168
- o.minViewMode = 1;
169
- break;
170
- case 2:
171
- case 'years':
172
- o.minViewMode = 2;
173
- break;
174
- default:
175
- o.minViewMode = 0;
176
- }
177
-
178
- 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));
179
222
 
180
223
  // true, false, or Number > 0
181
224
  if (o.multidate !== true){
@@ -186,7 +229,7 @@
186
229
  o.multidateSeparator = String(o.multidateSeparator);
187
230
 
188
231
  o.weekStart %= 7;
189
- o.weekEnd = ((o.weekStart + 6) % 7);
232
+ o.weekEnd = (o.weekStart + 6) % 7;
190
233
 
191
234
  var format = DPGlobal.parseFormat(o.format);
192
235
  if (o.startDate !== -Infinity){
@@ -194,7 +237,7 @@
194
237
  if (o.startDate instanceof Date)
195
238
  o.startDate = this._local_to_utc(this._zero_time(o.startDate));
196
239
  else
197
- o.startDate = DPGlobal.parseDate(o.startDate, format, o.language);
240
+ o.startDate = DPGlobal.parseDate(o.startDate, format, o.language, o.assumeNearbyYear);
198
241
  }
199
242
  else {
200
243
  o.startDate = -Infinity;
@@ -205,28 +248,22 @@
205
248
  if (o.endDate instanceof Date)
206
249
  o.endDate = this._local_to_utc(this._zero_time(o.endDate));
207
250
  else
208
- o.endDate = DPGlobal.parseDate(o.endDate, format, o.language);
251
+ o.endDate = DPGlobal.parseDate(o.endDate, format, o.language, o.assumeNearbyYear);
209
252
  }
210
253
  else {
211
254
  o.endDate = Infinity;
212
255
  }
213
256
  }
214
257
 
215
- o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
216
- if (!$.isArray(o.daysOfWeekDisabled))
217
- o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
218
- o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
219
- return parseInt(d, 10);
220
- });
258
+ o.daysOfWeekDisabled = this._resolveDaysOfWeek(o.daysOfWeekDisabled||[]);
259
+ o.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted||[]);
221
260
 
222
261
  o.datesDisabled = o.datesDisabled||[];
223
262
  if (!$.isArray(o.datesDisabled)) {
224
- var datesDisabled = [];
225
- datesDisabled.push(DPGlobal.parseDate(o.datesDisabled, format, o.language));
226
- o.datesDisabled = datesDisabled;
263
+ o.datesDisabled = o.datesDisabled.split(',');
227
264
  }
228
- o.datesDisabled = $.map(o.datesDisabled,function(d){
229
- return DPGlobal.parseDate(d, format, o.language);
265
+ o.datesDisabled = $.map(o.datesDisabled, function(d){
266
+ return DPGlobal.parseDate(d, format, o.language, o.assumeNearbyYear);
230
267
  });
231
268
 
232
269
  var plc = String(o.orientation).toLowerCase().split(/\s+/g),
@@ -260,7 +297,9 @@
260
297
  });
261
298
  o.orientation.y = _plc[0] || 'auto';
262
299
  }
263
- 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) {
264
303
  var year = o.defaultViewDate.year || new Date().getFullYear();
265
304
  var month = o.defaultViewDate.month || 0;
266
305
  var day = o.defaultViewDate.day || 1;
@@ -268,7 +307,6 @@
268
307
  } else {
269
308
  o.defaultViewDate = UTCToday();
270
309
  }
271
- o.showOnFocus = o.showOnFocus !== undefined ? o.showOnFocus : true;
272
310
  },
273
311
  _events: [],
274
312
  _secondaryEvents: [],
@@ -278,8 +316,7 @@
278
316
  if (evs[i].length === 2){
279
317
  ch = undefined;
280
318
  ev = evs[i][1];
281
- }
282
- else if (evs[i].length === 3){
319
+ } else if (evs[i].length === 3){
283
320
  ch = evs[i][1];
284
321
  ev = evs[i][2];
285
322
  }
@@ -292,8 +329,7 @@
292
329
  if (evs[i].length === 2){
293
330
  ch = undefined;
294
331
  ev = evs[i][1];
295
- }
296
- else if (evs[i].length === 3){
332
+ } else if (evs[i].length === 3){
297
333
  ch = evs[i][1];
298
334
  ev = evs[i][2];
299
335
  }
@@ -306,7 +342,8 @@
306
342
  if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)
307
343
  this.update();
308
344
  }, this),
309
- keydown: $.proxy(this.keydown, this)
345
+ keydown: $.proxy(this.keydown, this),
346
+ paste: $.proxy(this.paste, this)
310
347
  };
311
348
 
312
349
  if (this.o.showOnFocus === true) {
@@ -318,22 +355,21 @@
318
355
  [this.element, events]
319
356
  ];
320
357
  }
321
- else if (this.component && this.hasInput) { // component: input + button
358
+ // component: input + button
359
+ else if (this.component && this.inputField.length) {
322
360
  this._events = [
323
361
  // For components that are not readonly, allow keyboard nav
324
- [this.element.find('input'), events],
362
+ [this.inputField, events],
325
363
  [this.component, {
326
364
  click: $.proxy(this.show, this)
327
365
  }]
328
366
  ];
329
367
  }
330
- else if (this.element.is('div')){ // inline datepicker
331
- this.isInline = true;
332
- }
333
368
  else {
334
369
  this._events = [
335
370
  [this.element, {
336
- click: $.proxy(this.show, this)
371
+ click: $.proxy(this.show, this),
372
+ keydown: $.proxy(this.keydown, this)
337
373
  }]
338
374
  ];
339
375
  }
@@ -352,10 +388,25 @@
352
388
  }]
353
389
  );
354
390
 
391
+ if (this.o.immediateUpdates) {
392
+ // Trigger input updates immediately on changed year/month
393
+ this._events.push([this.element, {
394
+ 'changeYear changeMonth': $.proxy(function(e){
395
+ this.update(e.date);
396
+ }, this)
397
+ }]);
398
+ }
399
+
355
400
  this._secondaryEvents = [
356
401
  [this.picker, {
357
402
  click: $.proxy(this.click, this)
358
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
+ }],
359
410
  [$(window), {
360
411
  resize: $.proxy(this.place, this)
361
412
  }],
@@ -366,7 +417,8 @@
366
417
  this.element.is(e.target) ||
367
418
  this.element.find(e.target).length ||
368
419
  this.picker.is(e.target) ||
369
- this.picker.find(e.target).length
420
+ this.picker.find(e.target).length ||
421
+ this.isInline
370
422
  )){
371
423
  this.hide();
372
424
  }
@@ -395,13 +447,13 @@
395
447
  this.element.trigger({
396
448
  type: event,
397
449
  date: local_date,
450
+ viewMode: this.viewMode,
398
451
  dates: $.map(this.dates, this._utc_to_local),
399
452
  format: $.proxy(function(ix, format){
400
453
  if (arguments.length === 0){
401
454
  ix = this.dates.length - 1;
402
455
  format = this.o.format;
403
- }
404
- else if (typeof ix === 'string'){
456
+ } else if (typeof ix === 'string'){
405
457
  format = ix;
406
458
  ix = this.dates.length - 1;
407
459
  }
@@ -413,7 +465,7 @@
413
465
  },
414
466
 
415
467
  show: function(){
416
- if (this.element.attr('readonly') && this.o.enableOnReadonly === false)
468
+ if (this.inputField.prop('disabled') || (this.inputField.prop('readonly') && this.o.enableOnReadonly === false))
417
469
  return;
418
470
  if (!this.isInline)
419
471
  this.picker.appendTo(this.o.container);
@@ -428,29 +480,20 @@
428
480
  },
429
481
 
430
482
  hide: function(){
431
- if (this.isInline)
432
- return this;
433
- if (!this.picker.is(':visible'))
483
+ if (this.isInline || !this.picker.is(':visible'))
434
484
  return this;
435
485
  this.focusDate = null;
436
486
  this.picker.hide().detach();
437
487
  this._detachSecondaryEvents();
438
- this.viewMode = this.o.startView;
439
- this.showMode();
440
-
441
- if (
442
- this.o.forceParse &&
443
- (
444
- this.isInput && this.element.val() ||
445
- this.hasInput && this.element.find('input').val()
446
- )
447
- )
488
+ this.setViewMode(this.o.startView);
489
+
490
+ if (this.o.forceParse && this.inputField.val())
448
491
  this.setValue();
449
492
  this._trigger('hide');
450
493
  return this;
451
494
  },
452
495
 
453
- remove: function(){
496
+ destroy: function(){
454
497
  this.hide();
455
498
  this._detachEvents();
456
499
  this._detachSecondaryEvents();
@@ -462,8 +505,33 @@
462
505
  return this;
463
506
  },
464
507
 
508
+ paste: function(e){
509
+ var dateString;
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) {
514
+ dateString = window.clipboardData.getData('Text');
515
+ } else {
516
+ return;
517
+ }
518
+ this.setDate(dateString);
519
+ this.update();
520
+ e.preventDefault();
521
+ },
522
+
465
523
  _utc_to_local: function(utc){
466
- 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;
467
535
  },
468
536
  _local_to_utc: function(local){
469
537
  return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
@@ -472,7 +540,7 @@
472
540
  return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
473
541
  },
474
542
  _zero_utc_time: function(utc){
475
- return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
543
+ return utc && UTCDate(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate());
476
544
  },
477
545
 
478
546
  getDates: function(){
@@ -491,7 +559,7 @@
491
559
 
492
560
  getUTCDate: function(){
493
561
  var selected_date = this.dates.get(-1);
494
- if (typeof selected_date !== 'undefined') {
562
+ if (selected_date !== undefined) {
495
563
  return new Date(selected_date);
496
564
  } else {
497
565
  return null;
@@ -499,17 +567,7 @@
499
567
  },
500
568
 
501
569
  clearDates: function(){
502
- var element;
503
- if (this.isInput) {
504
- element = this.element;
505
- } else if (this.component) {
506
- element = this.element.find('input');
507
- }
508
-
509
- if (element) {
510
- element.val('').change();
511
- }
512
-
570
+ this.inputField.val('');
513
571
  this.update();
514
572
  this._trigger('changeDate');
515
573
 
@@ -517,6 +575,7 @@
517
575
  this.hide();
518
576
  }
519
577
  },
578
+
520
579
  setDates: function(){
521
580
  var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
522
581
  this.update.apply(this, args);
@@ -527,25 +586,17 @@
527
586
 
528
587
  setUTCDates: function(){
529
588
  var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
530
- this.update.apply(this, $.map(args, this._utc_to_local));
531
- this._trigger('changeDate');
532
- this.setValue();
589
+ this.setDates.apply(this, $.map(args, this._utc_to_local));
533
590
  return this;
534
591
  },
535
592
 
536
593
  setDate: alias('setDates'),
537
594
  setUTCDate: alias('setUTCDates'),
595
+ remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead'),
538
596
 
539
597
  setValue: function(){
540
598
  var formatted = this.getFormattedDate();
541
- if (!this.isInput){
542
- if (this.component){
543
- this.element.find('input').val(formatted).change();
544
- }
545
- }
546
- else {
547
- this.element.val(formatted).change();
548
- }
599
+ this.inputField.val(formatted);
549
600
  return this;
550
601
  },
551
602
 
@@ -559,6 +610,10 @@
559
610
  }).join(this.o.multidateSeparator);
560
611
  },
561
612
 
613
+ getStartDate: function(){
614
+ return this.o.startDate;
615
+ },
616
+
562
617
  setStartDate: function(startDate){
563
618
  this._process_options({startDate: startDate});
564
619
  this.update();
@@ -566,6 +621,10 @@
566
621
  return this;
567
622
  },
568
623
 
624
+ getEndDate: function(){
625
+ return this.o.endDate;
626
+ },
627
+
569
628
  setEndDate: function(endDate){
570
629
  this._process_options({endDate: endDate});
571
630
  this.update();
@@ -576,14 +635,19 @@
576
635
  setDaysOfWeekDisabled: function(daysOfWeekDisabled){
577
636
  this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
578
637
  this.update();
579
- this.updateNavArrows();
638
+ return this;
639
+ },
640
+
641
+ setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){
642
+ this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted});
643
+ this.update();
580
644
  return this;
581
645
  },
582
646
 
583
647
  setDatesDisabled: function(datesDisabled){
584
648
  this._process_options({datesDisabled: datesDisabled});
585
649
  this.update();
586
- this.updateNavArrows();
650
+ return this;
587
651
  },
588
652
 
589
653
  place: function(){
@@ -592,22 +656,26 @@
592
656
  var calendarWidth = this.picker.outerWidth(),
593
657
  calendarHeight = this.picker.outerHeight(),
594
658
  visualPadding = 10,
595
- windowWidth = $(this.o.container).width(),
596
- windowHeight = $(this.o.container).height(),
597
- scrollTop = $(this.o.container).scrollTop(),
598
- appendOffset = $(this.o.container).offset();
659
+ container = $(this.o.container),
660
+ windowWidth = container.width(),
661
+ scrollTop = this.o.container === 'body' ? $(document).scrollTop() : container.scrollTop(),
662
+ appendOffset = container.offset();
599
663
 
600
- var parentsZindex = [];
664
+ var parentsZindex = [0];
601
665
  this.element.parents().each(function(){
602
666
  var itemZIndex = $(this).css('z-index');
603
- if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));
667
+ if (itemZIndex !== 'auto' && Number(itemZIndex) !== 0) parentsZindex.push(Number(itemZIndex));
604
668
  });
605
- var zIndex = Math.max.apply(Math, parentsZindex) + 10;
669
+ var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;
606
670
  var offset = this.component ? this.component.parent().offset() : this.element.offset();
607
671
  var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
608
672
  var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
609
- var left = offset.left - appendOffset.left,
610
- top = offset.top - appendOffset.top;
673
+ var left = offset.left - appendOffset.left;
674
+ var top = offset.top - appendOffset.top;
675
+
676
+ if (this.o.container !== 'body') {
677
+ top += scrollTop;
678
+ }
611
679
 
612
680
  this.picker.removeClass(
613
681
  'datepicker-orient-top datepicker-orient-bottom '+
@@ -629,30 +697,32 @@
629
697
  } else if (left + calendarWidth > windowWidth) {
630
698
  // the calendar passes the widow right edge. Align it to component right side
631
699
  this.picker.addClass('datepicker-orient-right');
632
- left = offset.left + width - calendarWidth;
700
+ left += width - calendarWidth;
633
701
  } else {
634
- // Default to left
635
- 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
+ }
636
709
  }
637
710
  }
638
711
 
639
712
  // auto y orientation is best-situation: top or bottom, no fudging,
640
713
  // decision based on which shows more of the calendar
641
714
  var yorient = this.o.orientation.y,
642
- top_overflow, bottom_overflow;
715
+ top_overflow;
643
716
  if (yorient === 'auto'){
644
717
  top_overflow = -scrollTop + top - calendarHeight;
645
- bottom_overflow = scrollTop + windowHeight - (top + height + calendarHeight);
646
- if (Math.max(top_overflow, bottom_overflow) === bottom_overflow)
647
- yorient = 'top';
648
- else
649
- yorient = 'bottom';
718
+ yorient = top_overflow < 0 ? 'bottom' : 'top';
650
719
  }
720
+
651
721
  this.picker.addClass('datepicker-orient-' + yorient);
652
722
  if (yorient === 'top')
653
- top += height;
654
- else
655
723
  top -= calendarHeight + parseInt(this.picker.css('padding-top'));
724
+ else
725
+ top += height;
656
726
 
657
727
  if (this.o.rtl) {
658
728
  var right = windowWidth - (left + width);
@@ -686,11 +756,10 @@
686
756
  dates.push(date);
687
757
  }, this));
688
758
  fromArgs = true;
689
- }
690
- else {
759
+ } else {
691
760
  dates = this.isInput
692
761
  ? this.element.val()
693
- : this.element.data('date') || this.element.find('input').val();
762
+ : this.element.data('date') || this.inputField.val();
694
763
  if (dates && this.o.multidate)
695
764
  dates = dates.split(this.o.multidateSeparator);
696
765
  else
@@ -699,63 +768,73 @@
699
768
  }
700
769
 
701
770
  dates = $.map(dates, $.proxy(function(date){
702
- return DPGlobal.parseDate(date, this.o.format, this.o.language);
771
+ return DPGlobal.parseDate(date, this.o.format, this.o.language, this.o.assumeNearbyYear);
703
772
  }, this));
704
773
  dates = $.grep(dates, $.proxy(function(date){
705
774
  return (
706
- date < this.o.startDate ||
707
- date > this.o.endDate ||
775
+ !this.dateWithinRange(date) ||
708
776
  !date
709
777
  );
710
778
  }, this), true);
711
779
  this.dates.replace(dates);
712
780
 
713
- if (this.dates.length)
714
- this.viewDate = new Date(this.dates.get(-1));
715
- else if (this.viewDate < this.o.startDate)
716
- this.viewDate = new Date(this.o.startDate);
717
- else if (this.viewDate > this.o.endDate)
718
- this.viewDate = new Date(this.o.endDate);
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
+ }
719
791
 
720
792
  if (fromArgs){
721
793
  // setting date by clicking
722
794
  this.setValue();
795
+ this.element.change();
723
796
  }
724
- else if (dates.length){
797
+ else if (this.dates.length){
725
798
  // setting date by typing
726
- if (String(oldDates) !== String(this.dates))
799
+ if (String(oldDates) !== String(this.dates) && fromArgs) {
727
800
  this._trigger('changeDate');
801
+ this.element.change();
802
+ }
728
803
  }
729
- if (!this.dates.length && oldDates.length)
804
+ if (!this.dates.length && oldDates.length) {
730
805
  this._trigger('clearDate');
806
+ this.element.change();
807
+ }
731
808
 
732
809
  this.fill();
733
810
  return this;
734
811
  },
735
812
 
736
813
  fillDow: function(){
814
+ if (this.o.showWeekDays) {
737
815
  var dowCnt = this.o.weekStart,
738
816
  html = '<tr>';
739
817
  if (this.o.calendarWeeks){
740
- this.picker.find('.datepicker-days thead tr:first-child .datepicker-switch')
741
- .attr('colspan', function(i, val){
742
- return parseInt(val) + 1;
743
- });
744
- var cell = '<th class="cw">&#160;</th>';
745
- html += cell;
818
+ html += '<th class="cw">&#160;</th>';
746
819
  }
747
820
  while (dowCnt < this.o.weekStart + 7){
748
- html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
821
+ html += '<th class="dow';
822
+ if ($.inArray(dowCnt, this.o.daysOfWeekDisabled) !== -1)
823
+ html += ' disabled';
824
+ html += '">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
749
825
  }
750
826
  html += '</tr>';
751
827
  this.picker.find('.datepicker-days thead').append(html);
828
+ }
752
829
  },
753
830
 
754
831
  fillMonths: function(){
755
- var html = '',
756
- i = 0;
757
- while (i < 12){
758
- html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>';
832
+ var localDate = this._utc_to_local(this.viewDate);
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>';
759
838
  }
760
839
  this.picker.find('.datepicker-months td').html(html);
761
840
  },
@@ -774,33 +853,29 @@
774
853
  var cls = [],
775
854
  year = this.viewDate.getUTCFullYear(),
776
855
  month = this.viewDate.getUTCMonth(),
777
- today = new Date();
856
+ today = UTCToday();
778
857
  if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
779
858
  cls.push('old');
780
- }
781
- else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
859
+ } else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
782
860
  cls.push('new');
783
861
  }
784
862
  if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
785
863
  cls.push('focused');
786
- // Compare internal UTC date with local today, not UTC today
787
- if (this.o.todayHighlight &&
788
- date.getUTCFullYear() === today.getFullYear() &&
789
- date.getUTCMonth() === today.getMonth() &&
790
- date.getUTCDate() === today.getDate()){
864
+ // Compare internal UTC date with UTC today, not local today
865
+ if (this.o.todayHighlight && isUTCEquals(date, today)) {
791
866
  cls.push('today');
792
867
  }
793
868
  if (this.dates.contains(date) !== -1)
794
869
  cls.push('active');
795
- if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||
796
- $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){
870
+ if (!this.dateWithinRange(date)){
797
871
  cls.push('disabled');
798
872
  }
799
- if (this.o.datesDisabled.length > 0 &&
800
- $.grep(this.o.datesDisabled, function(d){
801
- return isUTCEquals(date, d); }).length > 0) {
873
+ if (this.dateIsDisabled(date)){
802
874
  cls.push('disabled', 'disabled-date');
803
875
  }
876
+ if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){
877
+ cls.push('highlighted');
878
+ }
804
879
 
805
880
  if (this.range){
806
881
  if (date > this.range[0] && date < this.range[this.range.length-1]){
@@ -809,10 +884,74 @@
809
884
  if ($.inArray(date.valueOf(), this.range) !== -1){
810
885
  cls.push('selected');
811
886
  }
887
+ if (date.valueOf() === this.range[0]){
888
+ cls.push('range-start');
889
+ }
890
+ if (date.valueOf() === this.range[this.range.length-1]){
891
+ cls.push('range-end');
892
+ }
812
893
  }
813
894
  return cls;
814
895
  },
815
896
 
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
+ });
907
+
908
+ var classes, tooltip, before;
909
+ for (var currVal = startVal - step; currVal <= endVal + step; currVal += step) {
910
+ classes = [cssClass];
911
+ tooltip = null;
912
+
913
+ if (currVal === startVal - step) {
914
+ classes.push('old');
915
+ } else if (currVal === endVal + step) {
916
+ classes.push('new');
917
+ }
918
+ if ($.inArray(currVal, selected) !== -1) {
919
+ classes.push('active');
920
+ }
921
+ if (currVal < startYear || currVal > endYear) {
922
+ classes.push('disabled');
923
+ }
924
+ if (currVal === focusedVal) {
925
+ classes.push('focused');
926
+ }
927
+
928
+ if (beforeFn !== $.noop) {
929
+ before = beforeFn(new Date(currVal, 0, 1));
930
+ if (before === undefined) {
931
+ before = {};
932
+ } else if (typeof before === 'boolean') {
933
+ before = {enabled: before};
934
+ } else if (typeof before === 'string') {
935
+ before = {classes: before};
936
+ }
937
+ if (before.enabled === false) {
938
+ classes.push('disabled');
939
+ }
940
+ if (before.classes) {
941
+ classes = classes.concat(before.classes.split(/\s+/));
942
+ }
943
+ if (before.tooltip) {
944
+ tooltip = before.tooltip;
945
+ }
946
+ }
947
+
948
+ html += '<span class="' + classes.join(' ') + '"' + (tooltip ? ' title="' + tooltip + '"' : '') + '>' + currVal + '</span>';
949
+ }
950
+
951
+ view.find('.datepicker-switch').text(startVal + '-' + endVal);
952
+ view.find('td').html(html);
953
+ },
954
+
816
955
  fill: function(){
817
956
  var d = new Date(this.viewDate),
818
957
  year = d.getUTCFullYear(),
@@ -823,57 +962,66 @@
823
962
  endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
824
963
  todaytxt = dates[this.o.language].today || dates['en'].today || '',
825
964
  cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
826
- tooltip;
965
+ titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat,
966
+ tooltip,
967
+ before;
827
968
  if (isNaN(year) || isNaN(month))
828
969
  return;
829
- this.picker.find('.datepicker-days thead .datepicker-switch')
830
- .text(dates[this.o.language].months[month]+' '+year);
970
+ this.picker.find('.datepicker-days .datepicker-switch')
971
+ .text(DPGlobal.formatDate(d, titleFormat, this.o.language));
831
972
  this.picker.find('tfoot .today')
832
973
  .text(todaytxt)
833
- .toggle(this.o.todayBtn !== false);
974
+ .css('display', this.o.todayBtn === true || this.o.todayBtn === 'linked' ? 'table-cell' : 'none');
834
975
  this.picker.find('tfoot .clear')
835
976
  .text(cleartxt)
836
- .toggle(this.o.clearBtn !== false);
977
+ .css('display', this.o.clearBtn === true ? 'table-cell' : 'none');
978
+ this.picker.find('thead .datepicker-title')
979
+ .text(this.o.title)
980
+ .css('display', typeof this.o.title === 'string' && this.o.title !== '' ? 'table-cell' : 'none');
837
981
  this.updateNavArrows();
838
982
  this.fillMonths();
839
- var prevMonth = UTCDate(year, month-1, 28),
840
- day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
841
- prevMonth.setUTCDate(day);
983
+ var prevMonth = UTCDate(year, month, 0),
984
+ day = prevMonth.getUTCDate();
842
985
  prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
843
986
  var nextMonth = new Date(prevMonth);
987
+ if (prevMonth.getUTCFullYear() < 100){
988
+ nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());
989
+ }
844
990
  nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
845
991
  nextMonth = nextMonth.valueOf();
846
992
  var html = [];
847
- var clsName;
993
+ var weekDay, clsName;
848
994
  while (prevMonth.valueOf() < nextMonth){
849
- if (prevMonth.getUTCDay() === this.o.weekStart){
995
+ weekDay = prevMonth.getUTCDay();
996
+ if (weekDay === this.o.weekStart){
850
997
  html.push('<tr>');
851
998
  if (this.o.calendarWeeks){
852
999
  // ISO 8601: First week contains first thursday.
853
1000
  // ISO also states week starts on Monday, but we can be more abstract here.
854
1001
  var
855
1002
  // Start of current week: based on weekstart/current date
856
- ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
1003
+ ws = new Date(+prevMonth + (this.o.weekStart - weekDay - 7) % 7 * 864e5),
857
1004
  // Thursday of this week
858
1005
  th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
859
1006
  // First Thursday of year, year from thursday
860
- 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),
861
1008
  // Calendar week: ms between thursdays, div ms per day, div 7 days
862
- calWeek = (th - yth) / 864e5 / 7 + 1;
1009
+ calWeek = (th - yth) / 864e5 / 7 + 1;
863
1010
  html.push('<td class="cw">'+ calWeek +'</td>');
864
-
865
1011
  }
866
1012
  }
867
1013
  clsName = this.getClassNames(prevMonth);
868
1014
  clsName.push('day');
869
1015
 
1016
+ var content = prevMonth.getUTCDate();
1017
+
870
1018
  if (this.o.beforeShowDay !== $.noop){
871
- var before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
1019
+ before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
872
1020
  if (before === undefined)
873
1021
  before = {};
874
- else if (typeof(before) === 'boolean')
1022
+ else if (typeof before === 'boolean')
875
1023
  before = {enabled: before};
876
- else if (typeof(before) === 'string')
1024
+ else if (typeof before === 'string')
877
1025
  before = {classes: before};
878
1026
  if (before.enabled === false)
879
1027
  clsName.push('disabled');
@@ -881,23 +1029,33 @@
881
1029
  clsName = clsName.concat(before.classes.split(/\s+/));
882
1030
  if (before.tooltip)
883
1031
  tooltip = before.tooltip;
1032
+ if (before.content)
1033
+ content = before.content;
1034
+ }
1035
+
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);
884
1042
  }
885
1043
 
886
- clsName = $.unique(clsName);
887
- 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>');
888
1045
  tooltip = null;
889
- if (prevMonth.getUTCDay() === this.o.weekEnd){
1046
+ if (weekDay === this.o.weekEnd){
890
1047
  html.push('</tr>');
891
1048
  }
892
- prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
1049
+ prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
893
1050
  }
894
- this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
1051
+ this.picker.find('.datepicker-days tbody').html(html.join(''));
895
1052
 
1053
+ var monthsTitle = dates[this.o.language].monthsTitle || dates['en'].monthsTitle || 'Months';
896
1054
  var months = this.picker.find('.datepicker-months')
897
- .find('th:eq(1)')
898
- .text(year)
1055
+ .find('.datepicker-switch')
1056
+ .text(this.o.maxViewMode < 2 ? monthsTitle : year)
899
1057
  .end()
900
- .find('span').removeClass('active');
1058
+ .find('tbody span').removeClass('active');
901
1059
 
902
1060
  $.each(this.dates, function(i, d){
903
1061
  if (d.getUTCFullYear() === year)
@@ -917,41 +1075,55 @@
917
1075
  if (this.o.beforeShowMonth !== $.noop){
918
1076
  var that = this;
919
1077
  $.each(months, function(i, month){
920
- if (!$(month).hasClass('disabled')) {
921
- var moDate = new Date(year, i, 1);
922
- var before = that.o.beforeShowMonth(moDate);
923
- if (before === false)
924
- $(month).addClass('disabled');
925
- }
1078
+ var moDate = new Date(year, i, 1);
1079
+ var before = that.o.beforeShowMonth(moDate);
1080
+ if (before === undefined)
1081
+ before = {};
1082
+ else if (typeof before === 'boolean')
1083
+ before = {enabled: before};
1084
+ else if (typeof before === 'string')
1085
+ before = {classes: before};
1086
+ if (before.enabled === false && !$(month).hasClass('disabled'))
1087
+ $(month).addClass('disabled');
1088
+ if (before.classes)
1089
+ $(month).addClass(before.classes);
1090
+ if (before.tooltip)
1091
+ $(month).prop('title', before.tooltip);
926
1092
  });
927
1093
  }
928
1094
 
929
- html = '';
930
- year = parseInt(year/10, 10) * 10;
931
- var yearCont = this.picker.find('.datepicker-years')
932
- .find('th:eq(1)')
933
- .text(year + '-' + (year + 9))
934
- .end()
935
- .find('td');
936
- year -= 1;
937
- var years = $.map(this.dates, function(d){
938
- return d.getUTCFullYear();
939
- }),
940
- classes;
941
- for (var i = -1; i < 11; i++){
942
- classes = ['year'];
943
- if (i === -1)
944
- classes.push('old');
945
- else if (i === 10)
946
- classes.push('new');
947
- if ($.inArray(year, years) !== -1)
948
- classes.push('active');
949
- if (year < startYear || year > endYear)
950
- classes.push('disabled');
951
- html += '<span class="' + classes.join(' ') + '">' + year + '</span>';
952
- year += 1;
953
- }
954
- yearCont.html(html);
1095
+ // Generating decade/years picker
1096
+ this._fill_yearsView(
1097
+ '.datepicker-years',
1098
+ 'year',
1099
+ 10,
1100
+ year,
1101
+ startYear,
1102
+ endYear,
1103
+ this.o.beforeShowYear
1104
+ );
1105
+
1106
+ // Generating century/decades picker
1107
+ this._fill_yearsView(
1108
+ '.datepicker-decades',
1109
+ 'decade',
1110
+ 100,
1111
+ year,
1112
+ startYear,
1113
+ endYear,
1114
+ this.o.beforeShowDecade
1115
+ );
1116
+
1117
+ // Generating millennium/centuries picker
1118
+ this._fill_yearsView(
1119
+ '.datepicker-centuries',
1120
+ 'century',
1121
+ 1000,
1122
+ year,
1123
+ startYear,
1124
+ endYear,
1125
+ this.o.beforeShowCentury
1126
+ );
955
1127
  },
956
1128
 
957
1129
  updateNavArrows: function(){
@@ -960,142 +1132,126 @@
960
1132
 
961
1133
  var d = new Date(this.viewDate),
962
1134
  year = d.getUTCFullYear(),
963
- 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;
964
1143
  switch (this.viewMode){
965
- case 0:
966
- if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
967
- this.picker.find('.prev').css({visibility: 'hidden'});
968
- }
969
- else {
970
- this.picker.find('.prev').css({visibility: 'visible'});
971
- }
972
- if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
973
- this.picker.find('.next').css({visibility: 'hidden'});
974
- }
975
- else {
976
- this.picker.find('.next').css({visibility: 'visible'});
977
- }
978
- break;
979
- case 1:
1144
+ case 4:
1145
+ factor *= 10;
1146
+ /* falls through */
1147
+ case 3:
1148
+ factor *= 10;
1149
+ /* falls through */
980
1150
  case 2:
981
- if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()){
982
- this.picker.find('.prev').css({visibility: 'hidden'});
983
- }
984
- else {
985
- this.picker.find('.prev').css({visibility: 'visible'});
986
- }
987
- if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()){
988
- this.picker.find('.next').css({visibility: 'hidden'});
989
- }
990
- else {
991
- this.picker.find('.next').css({visibility: 'visible'});
992
- }
1151
+ factor *= 10;
1152
+ /* falls through */
1153
+ case 1:
1154
+ prevIsDisabled = Math.floor(year / factor) * factor < startYear;
1155
+ nextIsDisabled = Math.floor(year / factor) * factor + factor > endYear;
1156
+ break;
1157
+ case 0:
1158
+ prevIsDisabled = year <= startYear && month < startMonth;
1159
+ nextIsDisabled = year >= endYear && month > endMonth;
993
1160
  break;
994
1161
  }
1162
+
1163
+ this.picker.find('.prev').toggleClass('disabled', prevIsDisabled);
1164
+ this.picker.find('.next').toggleClass('disabled', nextIsDisabled);
995
1165
  },
996
1166
 
997
1167
  click: function(e){
998
1168
  e.preventDefault();
999
- var target = $(e.target).closest('span, td, th'),
1000
- year, month, day;
1001
- if (target.length === 1){
1002
- switch (target[0].nodeName.toLowerCase()){
1003
- case 'th':
1004
- switch (target[0].className){
1005
- case 'datepicker-switch':
1006
- this.showMode(1);
1007
- break;
1008
- case 'prev':
1009
- case 'next':
1010
- var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);
1011
- switch (this.viewMode){
1012
- case 0:
1013
- this.viewDate = this.moveMonth(this.viewDate, dir);
1014
- this._trigger('changeMonth', this.viewDate);
1015
- break;
1016
- case 1:
1017
- case 2:
1018
- this.viewDate = this.moveYear(this.viewDate, dir);
1019
- if (this.viewMode === 1)
1020
- this._trigger('changeYear', this.viewDate);
1021
- break;
1022
- }
1023
- this.fill();
1024
- break;
1025
- case 'today':
1026
- var date = new Date();
1027
- date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
1169
+ e.stopPropagation();
1028
1170
 
1029
- this.showMode(-2);
1030
- var which = this.o.todayBtn === 'linked' ? null : 'view';
1031
- this._setDate(date, which);
1032
- break;
1033
- case 'clear':
1034
- this.clearDates();
1035
- break;
1036
- }
1037
- break;
1038
- case 'span':
1039
- if (!target.hasClass('disabled')){
1040
- this.viewDate.setUTCDate(1);
1041
- if (target.hasClass('month')){
1042
- day = 1;
1043
- month = target.parent().find('span').index(target);
1044
- year = this.viewDate.getUTCFullYear();
1045
- this.viewDate.setUTCMonth(month);
1046
- this._trigger('changeMonth', this.viewDate);
1047
- if (this.o.minViewMode === 1){
1048
- this._setDate(UTCDate(year, month, day));
1049
- }
1050
- }
1051
- else {
1052
- day = 1;
1053
- month = 0;
1054
- year = parseInt(target.text(), 10)||0;
1055
- this.viewDate.setUTCFullYear(year);
1056
- this._trigger('changeYear', this.viewDate);
1057
- if (this.o.minViewMode === 2){
1058
- this._setDate(UTCDate(year, month, day));
1059
- }
1060
- }
1061
- this.showMode(-1);
1062
- this.fill();
1063
- }
1064
- break;
1065
- case 'td':
1066
- if (target.hasClass('day') && !target.hasClass('disabled')){
1067
- day = parseInt(target.text(), 10)||1;
1068
- year = this.viewDate.getUTCFullYear();
1069
- month = this.viewDate.getUTCMonth();
1070
- if (target.hasClass('old')){
1071
- if (month === 0){
1072
- month = 11;
1073
- year -= 1;
1074
- }
1075
- else {
1076
- month -= 1;
1077
- }
1078
- }
1079
- else if (target.hasClass('new')){
1080
- if (month === 11){
1081
- month = 0;
1082
- year += 1;
1083
- }
1084
- else {
1085
- month += 1;
1086
- }
1087
- }
1088
- this._setDate(UTCDate(year, month, day));
1089
- }
1090
- break;
1171
+ var target, dir, day, year, month;
1172
+ target = $(e.target);
1173
+
1174
+ // Clicked on the switch
1175
+ if (target.hasClass('datepicker-switch') && this.viewMode !== this.o.maxViewMode){
1176
+ this.setViewMode(this.viewMode + 1);
1177
+ }
1178
+
1179
+ // Clicked on today button
1180
+ if (target.hasClass('today') && !target.hasClass('day')){
1181
+ this.setViewMode(0);
1182
+ this._setDate(UTCToday(), this.o.todayBtn === 'linked' ? null : 'view');
1183
+ }
1184
+
1185
+ // Clicked on clear button
1186
+ if (target.hasClass('clear')){
1187
+ this.clearDates();
1188
+ }
1189
+
1190
+ if (!target.hasClass('disabled')){
1191
+ // Clicked on a month, year, decade, century
1192
+ if (target.hasClass('month')
1193
+ || target.hasClass('year')
1194
+ || target.hasClass('decade')
1195
+ || target.hasClass('century')) {
1196
+ this.viewDate.setUTCDate(1);
1197
+
1198
+ day = 1;
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);
1207
+ }
1208
+
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
+ }
1091
1217
  }
1092
1218
  }
1219
+
1093
1220
  if (this.picker.is(':visible') && this._focused_from){
1094
- $(this._focused_from).focus();
1221
+ this._focused_from.focus();
1095
1222
  }
1096
1223
  delete this._focused_from;
1097
1224
  },
1098
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
+
1099
1255
  _toggle_multidate: function(date){
1100
1256
  var ix = this.dates.contains(date);
1101
1257
  if (!date){
@@ -1122,32 +1278,34 @@
1122
1278
  _setDate: function(date, which){
1123
1279
  if (!which || which === 'date')
1124
1280
  this._toggle_multidate(date && new Date(date));
1125
- if (!which || which === 'view')
1281
+ if ((!which && this.o.updateViewDate) || which === 'view')
1126
1282
  this.viewDate = date && new Date(date);
1127
1283
 
1128
1284
  this.fill();
1129
1285
  this.setValue();
1130
- if (!which || which !== 'view') {
1286
+ if (!which || which !== 'view') {
1131
1287
  this._trigger('changeDate');
1132
1288
  }
1133
- var element;
1134
- if (this.isInput){
1135
- element = this.element;
1136
- }
1137
- else if (this.component){
1138
- element = this.element.find('input');
1139
- }
1140
- if (element){
1141
- element.change();
1142
- }
1289
+ this.inputField.trigger('change');
1143
1290
  if (this.o.autoclose && (!which || which === 'date')){
1144
1291
  this.hide();
1145
1292
  }
1146
1293
  },
1147
1294
 
1295
+ moveDay: function(date, dir){
1296
+ var newDate = new Date(date);
1297
+ newDate.setUTCDate(date.getUTCDate() + dir);
1298
+
1299
+ return newDate;
1300
+ },
1301
+
1302
+ moveWeek: function(date, dir){
1303
+ return this.moveDay(date, dir * 7);
1304
+ },
1305
+
1148
1306
  moveMonth: function(date, dir){
1149
- if (!date)
1150
- return undefined;
1307
+ if (!isValidDate(date))
1308
+ return this.o.defaultViewDate;
1151
1309
  if (!dir)
1152
1310
  return date;
1153
1311
  var new_date = new Date(date.valueOf()),
@@ -1171,8 +1329,7 @@
1171
1329
  new_month = month + dir;
1172
1330
  new_date.setUTCMonth(new_month);
1173
1331
  // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
1174
- if (new_month < 0 || new_month > 11)
1175
- new_month = (new_month + 12) % 12;
1332
+ new_month = (new_month + 12) % 12;
1176
1333
  }
1177
1334
  else {
1178
1335
  // For magnitudes >1, move one month at a time...
@@ -1199,18 +1356,47 @@
1199
1356
  return this.moveMonth(date, dir*12);
1200
1357
  },
1201
1358
 
1359
+ moveAvailableDate: function(date, dir, fn){
1360
+ do {
1361
+ date = this[fn](date, dir);
1362
+
1363
+ if (!this.dateWithinRange(date))
1364
+ return false;
1365
+
1366
+ fn = 'moveDay';
1367
+ }
1368
+ while (this.dateIsDisabled(date));
1369
+
1370
+ return date;
1371
+ },
1372
+
1373
+ weekOfDateIsDisabled: function(date){
1374
+ return $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1;
1375
+ },
1376
+
1377
+ dateIsDisabled: function(date){
1378
+ return (
1379
+ this.weekOfDateIsDisabled(date) ||
1380
+ $.grep(this.o.datesDisabled, function(d){
1381
+ return isUTCEquals(date, d);
1382
+ }).length > 0
1383
+ );
1384
+ },
1385
+
1202
1386
  dateWithinRange: function(date){
1203
1387
  return date >= this.o.startDate && date <= this.o.endDate;
1204
1388
  },
1205
1389
 
1206
1390
  keydown: function(e){
1207
1391
  if (!this.picker.is(':visible')){
1208
- if (e.keyCode === 27) // allow escape to hide and re-show picker
1392
+ if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker
1209
1393
  this.show();
1394
+ e.stopPropagation();
1395
+ }
1210
1396
  return;
1211
1397
  }
1212
1398
  var dateChanged = false,
1213
- dir, newDate, newViewDate,
1399
+ dir, newViewDate,
1214
1400
  focusDate = this.focusDate || this.viewDate;
1215
1401
  switch (e.keyCode){
1216
1402
  case 27: // escape
@@ -1222,68 +1408,52 @@
1222
1408
  else
1223
1409
  this.hide();
1224
1410
  e.preventDefault();
1411
+ e.stopPropagation();
1225
1412
  break;
1226
1413
  case 37: // left
1227
- case 39: // right
1228
- if (!this.o.keyboardNavigation)
1229
- break;
1230
- dir = e.keyCode === 37 ? -1 : 1;
1231
- if (e.ctrlKey){
1232
- newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
1233
- newViewDate = this.moveYear(focusDate, dir);
1234
- this._trigger('changeYear', this.viewDate);
1235
- }
1236
- else if (e.shiftKey){
1237
- newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
1238
- newViewDate = this.moveMonth(focusDate, dir);
1239
- this._trigger('changeMonth', this.viewDate);
1240
- }
1241
- else {
1242
- newDate = new Date(this.dates.get(-1) || UTCToday());
1243
- newDate.setUTCDate(newDate.getUTCDate() + dir);
1244
- newViewDate = new Date(focusDate);
1245
- newViewDate.setUTCDate(focusDate.getUTCDate() + dir);
1246
- }
1247
- if (this.dateWithinRange(newViewDate)){
1248
- this.focusDate = this.viewDate = newViewDate;
1249
- this.setValue();
1250
- this.fill();
1251
- e.preventDefault();
1252
- }
1253
- break;
1254
1414
  case 38: // up
1415
+ case 39: // right
1255
1416
  case 40: // down
1256
- if (!this.o.keyboardNavigation)
1417
+ if (!this.o.keyboardNavigation || this.o.daysOfWeekDisabled.length === 7)
1257
1418
  break;
1258
- dir = e.keyCode === 38 ? -1 : 1;
1259
- if (e.ctrlKey){
1260
- newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
1261
- newViewDate = this.moveYear(focusDate, dir);
1262
- this._trigger('changeYear', this.viewDate);
1263
- }
1264
- else if (e.shiftKey){
1265
- newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
1266
- newViewDate = this.moveMonth(focusDate, dir);
1267
- this._trigger('changeMonth', this.viewDate);
1268
- }
1269
- else {
1270
- newDate = new Date(this.dates.get(-1) || UTCToday());
1271
- newDate.setUTCDate(newDate.getUTCDate() + dir * 7);
1272
- newViewDate = new Date(focusDate);
1273
- newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7);
1274
- }
1275
- if (this.dateWithinRange(newViewDate)){
1419
+ dir = e.keyCode === 37 || e.keyCode === 38 ? -1 : 1;
1420
+ if (this.viewMode === 0) {
1421
+ if (e.ctrlKey){
1422
+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
1423
+
1424
+ if (newViewDate)
1425
+ this._trigger('changeYear', this.viewDate);
1426
+ } else if (e.shiftKey){
1427
+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
1428
+
1429
+ if (newViewDate)
1430
+ this._trigger('changeMonth', this.viewDate);
1431
+ } else if (e.keyCode === 37 || e.keyCode === 39){
1432
+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveDay');
1433
+ } else if (!this.weekOfDateIsDisabled(focusDate)){
1434
+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveWeek');
1435
+ }
1436
+ } else if (this.viewMode === 1) {
1437
+ if (e.keyCode === 38 || e.keyCode === 40) {
1438
+ dir = dir * 4;
1439
+ }
1440
+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveMonth');
1441
+ } else if (this.viewMode === 2) {
1442
+ if (e.keyCode === 38 || e.keyCode === 40) {
1443
+ dir = dir * 4;
1444
+ }
1445
+ newViewDate = this.moveAvailableDate(focusDate, dir, 'moveYear');
1446
+ }
1447
+ if (newViewDate){
1276
1448
  this.focusDate = this.viewDate = newViewDate;
1277
1449
  this.setValue();
1278
1450
  this.fill();
1279
1451
  e.preventDefault();
1280
1452
  }
1281
1453
  break;
1282
- case 32: // spacebar
1283
- // Spacebar is used in manually typing dates in some formats.
1284
- // As such, its behavior should not be hijacked.
1285
- break;
1286
1454
  case 13: // enter
1455
+ if (!this.o.forceParse)
1456
+ break;
1287
1457
  focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
1288
1458
  if (this.o.keyboardNavigation) {
1289
1459
  this._toggle_multidate(focusDate);
@@ -1295,11 +1465,7 @@
1295
1465
  this.fill();
1296
1466
  if (this.picker.is(':visible')){
1297
1467
  e.preventDefault();
1298
- if (typeof e.stopPropagation === 'function') {
1299
- e.stopPropagation(); // All modern browsers, IE9+
1300
- } else {
1301
- e.cancelBubble = true; // IE6,7,8 ignore "stopPropagation"
1302
- }
1468
+ e.stopPropagation();
1303
1469
  if (this.o.autoclose)
1304
1470
  this.hide();
1305
1471
  }
@@ -1316,44 +1482,38 @@
1316
1482
  this._trigger('changeDate');
1317
1483
  else
1318
1484
  this._trigger('clearDate');
1319
- var element;
1320
- if (this.isInput){
1321
- element = this.element;
1322
- }
1323
- else if (this.component){
1324
- element = this.element.find('input');
1325
- }
1326
- if (element){
1327
- element.change();
1328
- }
1485
+ this.inputField.trigger('change');
1329
1486
  }
1330
1487
  },
1331
1488
 
1332
- showMode: function(dir){
1333
- if (dir){
1334
- this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));
1335
- }
1489
+ setViewMode: function(viewMode){
1490
+ this.viewMode = viewMode;
1336
1491
  this.picker
1337
1492
  .children('div')
1338
1493
  .hide()
1339
- .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
1340
- .css('display', 'block');
1494
+ .filter('.datepicker-' + DPGlobal.viewModes[this.viewMode].clsName)
1495
+ .show();
1341
1496
  this.updateNavArrows();
1497
+ this._trigger('changeViewMode', new Date(this.viewDate));
1342
1498
  }
1343
1499
  };
1344
1500
 
1345
1501
  var DateRangePicker = function(element, options){
1502
+ $.data(element, 'datepicker', this);
1346
1503
  this.element = $(element);
1347
1504
  this.inputs = $.map(options.inputs, function(i){
1348
1505
  return i.jquery ? i[0] : i;
1349
1506
  });
1350
1507
  delete options.inputs;
1351
1508
 
1509
+ this.keepEmptyValues = options.keepEmptyValues;
1510
+ delete options.keepEmptyValues;
1511
+
1352
1512
  datepickerPlugin.call($(this.inputs), options)
1353
- .bind('changeDate', $.proxy(this.dateUpdated, this));
1513
+ .on('changeDate', $.proxy(this.dateUpdated, this));
1354
1514
 
1355
1515
  this.pickers = $.map(this.inputs, function(i){
1356
- return $(i).data('datepicker');
1516
+ return $.data(i, 'datepicker');
1357
1517
  });
1358
1518
  this.updateDates();
1359
1519
  };
@@ -1372,6 +1532,11 @@
1372
1532
  p.setRange(range);
1373
1533
  });
1374
1534
  },
1535
+ clearDates: function(){
1536
+ $.each(this.pickers, function(i, p){
1537
+ p.clearDates();
1538
+ });
1539
+ },
1375
1540
  dateUpdated: function(e){
1376
1541
  // `this.updating` is a workaround for preventing infinite recursion
1377
1542
  // between `changeDate` triggering and `setUTCDate` calling. Until
@@ -1380,8 +1545,14 @@
1380
1545
  return;
1381
1546
  this.updating = true;
1382
1547
 
1383
- var dp = $(e.target).data('datepicker'),
1384
- new_date = dp.getUTCDate(),
1548
+ var dp = $.data(e.target, 'datepicker');
1549
+
1550
+ if (dp === undefined) {
1551
+ return;
1552
+ }
1553
+
1554
+ var new_date = dp.getUTCDate(),
1555
+ keep_empty_values = this.keepEmptyValues,
1385
1556
  i = $.inArray(e.target, this.inputs),
1386
1557
  j = i - 1,
1387
1558
  k = i + 1,
@@ -1390,7 +1561,7 @@
1390
1561
  return;
1391
1562
 
1392
1563
  $.each(this.pickers, function(i, p){
1393
- if (!p.getUTCDate())
1564
+ if (!p.getUTCDate() && (p === dp || !keep_empty_values))
1394
1565
  p.setUTCDate(new_date);
1395
1566
  });
1396
1567
 
@@ -1399,8 +1570,7 @@
1399
1570
  while (j >= 0 && new_date < this.dates[j]){
1400
1571
  this.pickers[j--].setUTCDate(new_date);
1401
1572
  }
1402
- }
1403
- else if (new_date > this.dates[k]){
1573
+ } else if (new_date > this.dates[k]){
1404
1574
  // Date being moved later/right
1405
1575
  while (k < l && new_date > this.dates[k]){
1406
1576
  this.pickers[k++].setUTCDate(new_date);
@@ -1410,10 +1580,12 @@
1410
1580
 
1411
1581
  delete this.updating;
1412
1582
  },
1413
- remove: function(){
1414
- $.map(this.pickers, function(p){ p.remove(); });
1583
+ destroy: function(){
1584
+ $.map(this.pickers, function(p){ p.destroy(); });
1585
+ $(this.inputs).off('changeDate', this.dateUpdated);
1415
1586
  delete this.element.data().datepicker;
1416
- }
1587
+ },
1588
+ remove: alias('destroy', 'Method `remove` is deprecated and will be removed in version 2.0. Use `destroy` instead')
1417
1589
  };
1418
1590
 
1419
1591
  function opts_from_el(el, prefix){
@@ -1468,43 +1640,57 @@
1468
1640
  // Options priority: js args, data-attrs, locales, defaults
1469
1641
  opts = $.extend({}, defaults, locopts, elopts, options);
1470
1642
  if ($this.hasClass('input-daterange') || opts.inputs){
1471
- var ropts = {
1643
+ $.extend(opts, {
1472
1644
  inputs: opts.inputs || $this.find('input').toArray()
1473
- };
1474
- $this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));
1645
+ });
1646
+ data = new DateRangePicker(this, opts);
1475
1647
  }
1476
1648
  else {
1477
- $this.data('datepicker', (data = new Datepicker(this, opts)));
1649
+ data = new Datepicker(this, opts);
1478
1650
  }
1651
+ $this.data('datepicker', data);
1479
1652
  }
1480
1653
  if (typeof option === 'string' && typeof data[option] === 'function'){
1481
1654
  internal_return = data[option].apply(data, args);
1482
- if (internal_return !== undefined)
1483
- return false;
1484
1655
  }
1485
1656
  });
1486
- if (internal_return !== undefined)
1487
- return internal_return;
1488
- else
1657
+
1658
+ if (
1659
+ internal_return === undefined ||
1660
+ internal_return instanceof Datepicker ||
1661
+ internal_return instanceof DateRangePicker
1662
+ )
1489
1663
  return this;
1664
+
1665
+ if (this.length > 1)
1666
+ throw new Error('Using only allowed for the collection of a single element (' + option + ' function)');
1667
+ else
1668
+ return internal_return;
1490
1669
  };
1491
1670
  $.fn.datepicker = datepickerPlugin;
1492
1671
 
1493
1672
  var defaults = $.fn.datepicker.defaults = {
1673
+ assumeNearbyYear: false,
1494
1674
  autoclose: false,
1495
1675
  beforeShowDay: $.noop,
1496
1676
  beforeShowMonth: $.noop,
1677
+ beforeShowYear: $.noop,
1678
+ beforeShowDecade: $.noop,
1679
+ beforeShowCentury: $.noop,
1497
1680
  calendarWeeks: false,
1498
1681
  clearBtn: false,
1499
1682
  toggleActive: false,
1500
1683
  daysOfWeekDisabled: [],
1684
+ daysOfWeekHighlighted: [],
1501
1685
  datesDisabled: [],
1502
1686
  endDate: Infinity,
1503
1687
  forceParse: true,
1504
1688
  format: 'mm/dd/yyyy',
1689
+ keepEmptyValues: false,
1505
1690
  keyboardNavigation: true,
1506
1691
  language: 'en',
1507
1692
  minViewMode: 0,
1693
+ maxViewMode: 4,
1508
1694
  multidate: false,
1509
1695
  multidateSeparator: ',',
1510
1696
  orientation: "auto",
@@ -1513,10 +1699,20 @@
1513
1699
  startView: 0,
1514
1700
  todayBtn: false,
1515
1701
  todayHighlight: false,
1702
+ updateViewDate: true,
1516
1703
  weekStart: 0,
1517
1704
  disableTouchKeyboard: false,
1518
- enableOnReadonly: true,
1519
- container: 'body'
1705
+ enableOnReadonly: true,
1706
+ showOnFocus: true,
1707
+ zIndexOffset: 10,
1708
+ container: 'body',
1709
+ immediateUpdates: false,
1710
+ title: '',
1711
+ templates: {
1712
+ leftArrow: '&#x00AB;',
1713
+ rightArrow: '&#x00BB;'
1714
+ },
1715
+ showWeekDays: true
1520
1716
  };
1521
1717
  var locale_opts = $.fn.datepicker.locale_opts = [
1522
1718
  'format',
@@ -1526,43 +1722,55 @@
1526
1722
  $.fn.datepicker.Constructor = Datepicker;
1527
1723
  var dates = $.fn.datepicker.dates = {
1528
1724
  en: {
1529
- days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
1530
- daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
1531
- daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
1725
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
1726
+ daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
1727
+ daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
1532
1728
  months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
1533
1729
  monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
1534
1730
  today: "Today",
1535
- clear: "Clear"
1731
+ clear: "Clear",
1732
+ titleFormat: "MM yyyy"
1536
1733
  }
1537
1734
  };
1538
1735
 
1539
1736
  var DPGlobal = {
1540
- modes: [
1737
+ viewModes: [
1541
1738
  {
1739
+ names: ['days', 'month'],
1542
1740
  clsName: 'days',
1543
- navFnc: 'Month',
1544
- navStep: 1
1741
+ e: 'changeMonth'
1545
1742
  },
1546
1743
  {
1744
+ names: ['months', 'year'],
1547
1745
  clsName: 'months',
1548
- navFnc: 'FullYear',
1746
+ e: 'changeYear',
1549
1747
  navStep: 1
1550
1748
  },
1551
1749
  {
1750
+ names: ['years', 'decade'],
1552
1751
  clsName: 'years',
1553
- navFnc: 'FullYear',
1752
+ e: 'changeDecade',
1554
1753
  navStep: 10
1555
- }],
1556
- isLeapYear: function(year){
1557
- return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
1558
- },
1559
- getDaysInMonth: function(year, month){
1560
- return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
1561
- },
1754
+ },
1755
+ {
1756
+ names: ['decades', 'century'],
1757
+ clsName: 'decades',
1758
+ e: 'changeCentury',
1759
+ navStep: 100
1760
+ },
1761
+ {
1762
+ names: ['centuries', 'millennium'],
1763
+ clsName: 'centuries',
1764
+ e: 'changeMillennium',
1765
+ navStep: 1000
1766
+ }
1767
+ ],
1562
1768
  validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
1563
- nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
1769
+ nonpunctuation: /[^ -\/:-@\u5e74\u6708\u65e5\[-`{-~\t\n\r]+/g,
1564
1770
  parseFormat: function(format){
1565
- // IE treats \0 as a string end in inputs (truncating the value),
1771
+ if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function')
1772
+ return format;
1773
+ // IE treats \0 as a string end in inputs (truncating the value),
1566
1774
  // so it's a bad format delimiter, anyway
1567
1775
  var separators = format.replace(this.validParts, '\0').split('\0'),
1568
1776
  parts = format.match(this.validParts);
@@ -1571,48 +1779,65 @@
1571
1779
  }
1572
1780
  return {separators: separators, parts: parts};
1573
1781
  },
1574
- parseDate: function(date, format, language){
1782
+ parseDate: function(date, format, language, assumeNearby){
1575
1783
  if (!date)
1576
1784
  return undefined;
1577
1785
  if (date instanceof Date)
1578
1786
  return date;
1579
1787
  if (typeof format === 'string')
1580
1788
  format = DPGlobal.parseFormat(format);
1581
- var part_re = /([\-+]\d+)([dmwy])/,
1582
- parts = date.match(/([\-+]\d+)([dmwy])/g),
1583
- part, dir, i;
1584
- if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
1789
+ if (format.toValue)
1790
+ return format.toValue(date, format, language);
1791
+ var fn_map = {
1792
+ d: 'moveDay',
1793
+ m: 'moveMonth',
1794
+ w: 'moveWeek',
1795
+ y: 'moveYear'
1796
+ },
1797
+ dateAliases = {
1798
+ yesterday: '-1d',
1799
+ today: '+0d',
1800
+ tomorrow: '+1d'
1801
+ },
1802
+ parts, part, dir, i, fn;
1803
+ if (date in dateAliases){
1804
+ date = dateAliases[date];
1805
+ }
1806
+ if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/i.test(date)){
1807
+ parts = date.match(/([\-+]\d+)([dmwy])/gi);
1585
1808
  date = new Date();
1586
1809
  for (i=0; i < parts.length; i++){
1587
- part = part_re.exec(parts[i]);
1588
- dir = parseInt(part[1]);
1589
- switch (part[2]){
1590
- case 'd':
1591
- date.setUTCDate(date.getUTCDate() + dir);
1592
- break;
1593
- case 'm':
1594
- date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);
1595
- break;
1596
- case 'w':
1597
- date.setUTCDate(date.getUTCDate() + dir * 7);
1598
- break;
1599
- case 'y':
1600
- date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);
1601
- break;
1602
- }
1810
+ part = parts[i].match(/([\-+]\d+)([dmwy])/i);
1811
+ dir = Number(part[1]);
1812
+ fn = fn_map[part[2].toLowerCase()];
1813
+ date = Datepicker.prototype[fn](date, dir);
1603
1814
  }
1604
- return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
1815
+ return Datepicker.prototype._zero_utc_time(date);
1605
1816
  }
1817
+
1606
1818
  parts = date && date.match(this.nonpunctuation) || [];
1607
- date = new Date();
1819
+
1820
+ function applyNearbyYear(year, threshold){
1821
+ if (threshold === true)
1822
+ threshold = 10;
1823
+
1824
+ // if year is 2 digits or less, than the user most likely is trying to get a recent century
1825
+ if (year < 100){
1826
+ year += 2000;
1827
+ // if the new year is more than threshold years in advance, use last century
1828
+ if (year > ((new Date()).getFullYear()+threshold)){
1829
+ year -= 100;
1830
+ }
1831
+ }
1832
+
1833
+ return year;
1834
+ }
1835
+
1608
1836
  var parsed = {},
1609
1837
  setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
1610
1838
  setters_map = {
1611
1839
  yyyy: function(d,v){
1612
- return d.setUTCFullYear(v);
1613
- },
1614
- yy: function(d,v){
1615
- return d.setUTCFullYear(2000+v);
1840
+ return d.setUTCFullYear(assumeNearby ? applyNearbyYear(v, assumeNearby) : v);
1616
1841
  },
1617
1842
  m: function(d,v){
1618
1843
  if (isNaN(d))
@@ -1630,9 +1855,10 @@
1630
1855
  }
1631
1856
  },
1632
1857
  val, filtered;
1858
+ setters_map['yy'] = setters_map['yyyy'];
1633
1859
  setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1634
1860
  setters_map['dd'] = setters_map['d'];
1635
- date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
1861
+ date = UTCToday();
1636
1862
  var fparts = format.parts.slice();
1637
1863
  // Remove noop parts
1638
1864
  if (parts.length !== fparts.length){
@@ -1683,7 +1909,9 @@
1683
1909
  return '';
1684
1910
  if (typeof format === 'string')
1685
1911
  format = DPGlobal.parseFormat(format);
1686
- var val = {
1912
+ if (format.toDisplay)
1913
+ return format.toDisplay(date, format, language);
1914
+ var val = {
1687
1915
  d: date.getUTCDate(),
1688
1916
  D: dates[language].daysShort[date.getUTCDay()],
1689
1917
  DD: dates[language].days[date.getUTCDay()],
@@ -1705,10 +1933,13 @@
1705
1933
  return date.join('');
1706
1934
  },
1707
1935
  headTemplate: '<thead>'+
1936
+ '<tr>'+
1937
+ '<th colspan="7" class="datepicker-title"></th>'+
1938
+ '</tr>'+
1708
1939
  '<tr>'+
1709
- '<th class="prev">&#171;</th>'+
1940
+ '<th class="prev">'+defaults.templates.leftArrow+'</th>'+
1710
1941
  '<th colspan="5" class="datepicker-switch"></th>'+
1711
- '<th class="next">&#187;</th>'+
1942
+ '<th class="next">'+defaults.templates.rightArrow+'</th>'+
1712
1943
  '</tr>'+
1713
1944
  '</thead>',
1714
1945
  contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
@@ -1723,7 +1954,7 @@
1723
1954
  };
1724
1955
  DPGlobal.template = '<div class="datepicker">'+
1725
1956
  '<div class="datepicker-days">'+
1726
- '<table class=" table-condensed">'+
1957
+ '<table class="table-condensed">'+
1727
1958
  DPGlobal.headTemplate+
1728
1959
  '<tbody></tbody>'+
1729
1960
  DPGlobal.footTemplate+
@@ -1743,6 +1974,20 @@
1743
1974
  DPGlobal.footTemplate+
1744
1975
  '</table>'+
1745
1976
  '</div>'+
1977
+ '<div class="datepicker-decades">'+
1978
+ '<table class="table-condensed">'+
1979
+ DPGlobal.headTemplate+
1980
+ DPGlobal.contTemplate+
1981
+ DPGlobal.footTemplate+
1982
+ '</table>'+
1983
+ '</div>'+
1984
+ '<div class="datepicker-centuries">'+
1985
+ '<table class="table-condensed">'+
1986
+ DPGlobal.headTemplate+
1987
+ DPGlobal.contTemplate+
1988
+ DPGlobal.footTemplate+
1989
+ '</table>'+
1990
+ '</div>'+
1746
1991
  '</div>';
1747
1992
 
1748
1993
  $.fn.datepicker.DPGlobal = DPGlobal;
@@ -1758,7 +2003,15 @@
1758
2003
 
1759
2004
  /* DATEPICKER VERSION
1760
2005
  * =================== */
1761
- $.fn.datepicker.version = "1.4.0";
2006
+ $.fn.datepicker.version = '1.8.0';
2007
+
2008
+ $.fn.datepicker.deprecated = function(msg){
2009
+ var console = window.console;
2010
+ if (console && console.warn) {
2011
+ console.warn('DEPRECATED: ' + msg);
2012
+ }
2013
+ };
2014
+
1762
2015
 
1763
2016
  /* DATEPICKER DATA-API
1764
2017
  * ================== */
@@ -1779,4 +2032,4 @@
1779
2032
  datepickerPlugin.call($('[data-provide="datepicker-inline"]'));
1780
2033
  });
1781
2034
 
1782
- }(window.jQuery));
2035
+ }));