foundation-datetimepicker-rails 0.1.2 → 0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3941b14c28a26201d9b2681a552e35d3172d40d5
4
+ data.tar.gz: d941402997cdde5058c7c893deca40c9c72bbda1
5
+ SHA512:
6
+ metadata.gz: 8ae29558c3798e8d9aa66deb0dc73a7e564df4789cf5d0a6df86bde5b0cda222883a9f05abed4c98f4fe81b87c5725526fcb2cee84f132db76709e95880ea372
7
+ data.tar.gz: c4cb9c8617aca85e6d5fe3a961dda5590b4d05fbbe71136f68a6430d913a62037fcc424a545b4f226db045a9eb21321a37fa0dd1e874db4f2b93ba06aeb34d61
data/README.md CHANGED
@@ -19,6 +19,17 @@ Add the following line to your stylesheet file (`foundation_and_overrides.scss`)
19
19
  @import 'foundation-datetimepicker';
20
20
  ```
21
21
 
22
+ ##Quick instructions
23
+
24
+ Call the datetimepicker via javascript:
25
+
26
+ $('.datetimepicker').fdatetimepicker()
27
+
28
+
29
+ Call the datepicker via javascript:
30
+
31
+ $('.datepicker').fdatepicker()
32
+
22
33
  ## Usage
23
34
 
24
35
  See the excellent demo provided by plugin's author - [here](http://foundation-datepicker.peterbeno.com/example/example.html).
@@ -1,5 +1,5 @@
1
1
  module FoundationDatetimepicker
2
2
  module Rails
3
- VERSION = "0.1.2"
3
+ VERSION = "0.1.3"
4
4
  end
5
5
  end
@@ -1,12 +1,11 @@
1
1
  /* =========================================================
2
- * foundation-datepicker.js
3
- * Copyright 2013 Peter Beno, najlepsiwebdesigner@gmail.com, @benopeter
4
- * project website http://foundation-datepicker.peterbeno.com
5
- *
6
- * original project:
7
- * Copyright 2012 Stefan Petre
8
- * Improvements by Andrew Rowls
9
- * Improvements by Sébastien Malot
2
+ * bootstrap-datetimepicker.js
3
+ * =========================================================
4
+ * Copyright 2012 Stefan Petre
5
+ * Improvements by Andrew Rowls
6
+ * Improvements by Sébastien Malot
7
+ * Improvements by Yun Lai
8
+ * Project URL : http://www.malot.fr/bootstrap-datetimepicker
10
9
  *
11
10
  * Licensed under the Apache License, Version 2.0 (the "License");
12
11
  * you may not use this file except in compliance with the License.
@@ -21,42 +20,58 @@
21
20
  * limitations under the License.
22
21
  * ========================================================= */
23
22
 
24
- !function( $ ) {
25
23
 
26
- function UTCDate(){
24
+ !function ($) {
25
+
26
+ function UTCDate() {
27
27
  return new Date(Date.UTC.apply(Date, arguments));
28
28
  }
29
- function UTCToday(){
29
+
30
+ function UTCToday() {
30
31
  var today = new Date();
31
- return UTCDate(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate(), today.getUTCHours(), today.getUTCMinutes(), today.getUTCSeconds());
32
+ return UTCDate(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate(), today.getUTCHours(), today.getUTCMinutes(), today.getUTCSeconds(), 0);
32
33
  }
33
34
 
34
35
  // Picker object
35
36
 
36
- var Datetimepicker = function(element, options) {
37
+ var Datetimepicker = function (element, options) {
37
38
  var that = this;
38
39
 
39
40
  this.element = $(element);
40
- this.closeButton = options.closeButton;
41
+
41
42
  this.language = options.language || this.element.data('date-language') || "en";
42
43
  this.language = this.language in dates ? this.language : "en";
43
44
  this.isRTL = dates[this.language].rtl || false;
44
- this.format = DPGlobal.parseFormat(options.format || this.element.data('date-format') || 'yyyy-mm-dd hh:ii');
45
+ this.formatType = options.formatType || this.element.data('format-type') || 'standard';
46
+ this.format = DPGlobal.parseFormat(options.format || this.element.data('date-format') || dates[this.language].format || DPGlobal.getDefaultFormat(this.formatType, 'input'), this.formatType);
45
47
  this.isInline = false;
48
+ this.isVisible = false;
46
49
  this.isInput = this.element.is('input');
47
- this.component = this.element.is('.date') ? this.element.find('.prefix').parent() : false;
48
- this.componentReset = this.element.is('.date') ? this.element.find('.prefix').parent() : false;
50
+
51
+ this.bootcssVer = this.isInput ? (this.element.is('.form-control') ? 3 : 2) : ( this.bootcssVer = this.element.is('.input-group') ? 3 : 2 );
52
+
53
+ this.component = this.element.is('.date') ? ( this.bootcssVer == 3 ? this.element.find('.input-group-addon .glyphicon-th, .input-group-addon .glyphicon-time, .input-group-addon .glyphicon-calendar').parent() : this.element.find('.add-on .icon-th, .add-on .icon-time, .add-on .icon-calendar').parent()) : false;
54
+ this.componentReset = this.element.is('.date') ? ( this.bootcssVer == 3 ? this.element.find('.input-group-addon .glyphicon-remove').parent() : this.element.find('.add-on .icon-remove').parent()) : false;
49
55
  this.hasInput = this.component && this.element.find('input').length;
50
56
  if (this.component && this.component.length === 0) {
51
57
  this.component = false;
52
58
  }
53
59
  this.linkField = options.linkField || this.element.data('link-field') || false;
54
- this.linkFormat = DPGlobal.parseFormat(options.linkFormat || this.element.data('link-format') || 'yyyy-mm-dd hh:ii:ss');
60
+ this.linkFormat = DPGlobal.parseFormat(options.linkFormat || this.element.data('link-format') || DPGlobal.getDefaultFormat(this.formatType, 'link'), this.formatType);
55
61
  this.minuteStep = options.minuteStep || this.element.data('minute-step') || 5;
56
62
  this.pickerPosition = options.pickerPosition || this.element.data('picker-position') || 'bottom-right';
63
+ this.showMeridian = options.showMeridian || this.element.data('show-meridian') || false;
64
+ this.initialDate = options.initialDate || new Date();
57
65
 
58
66
  this._attachEvents();
59
67
 
68
+ this.formatViewType = "datetime";
69
+ if ('formatViewType' in options) {
70
+ this.formatViewType = options.formatViewType;
71
+ } else if ('formatViewType' in this.element.data()) {
72
+ this.formatViewType = this.element.data('formatViewType');
73
+ }
74
+
60
75
  this.minView = 0;
61
76
  if ('minView' in options) {
62
77
  this.minView = options.minView;
@@ -65,7 +80,7 @@
65
80
  }
66
81
  this.minView = DPGlobal.convertViewMode(this.minView);
67
82
 
68
- this.maxView = DPGlobal.modes.length-1;
83
+ this.maxView = DPGlobal.modes.length - 1;
69
84
  if ('maxView' in options) {
70
85
  this.maxView = options.maxView;
71
86
  } else if ('maxView' in this.element.data()) {
@@ -73,6 +88,28 @@
73
88
  }
74
89
  this.maxView = DPGlobal.convertViewMode(this.maxView);
75
90
 
91
+ this.wheelViewModeNavigation = false;
92
+ if ('wheelViewModeNavigation' in options) {
93
+ this.wheelViewModeNavigation = options.wheelViewModeNavigation;
94
+ } else if ('wheelViewModeNavigation' in this.element.data()) {
95
+ this.wheelViewModeNavigation = this.element.data('view-mode-wheel-navigation');
96
+ }
97
+
98
+ this.wheelViewModeNavigationInverseDirection = false;
99
+
100
+ if ('wheelViewModeNavigationInverseDirection' in options) {
101
+ this.wheelViewModeNavigationInverseDirection = options.wheelViewModeNavigationInverseDirection;
102
+ } else if ('wheelViewModeNavigationInverseDirection' in this.element.data()) {
103
+ this.wheelViewModeNavigationInverseDirection = this.element.data('view-mode-wheel-navigation-inverse-dir');
104
+ }
105
+
106
+ this.wheelViewModeNavigationDelay = 100;
107
+ if ('wheelViewModeNavigationDelay' in options) {
108
+ this.wheelViewModeNavigationDelay = options.wheelViewModeNavigationDelay;
109
+ } else if ('wheelViewModeNavigationDelay' in this.element.data()) {
110
+ this.wheelViewModeNavigationDelay = this.element.data('view-mode-wheel-navigation-delay');
111
+ }
112
+
76
113
  this.startViewMode = 2;
77
114
  if ('startView' in options) {
78
115
  this.startViewMode = options.startView;
@@ -82,6 +119,14 @@
82
119
  this.startViewMode = DPGlobal.convertViewMode(this.startViewMode);
83
120
  this.viewMode = this.startViewMode;
84
121
 
122
+ this.viewSelect = this.minView;
123
+ if ('viewSelect' in options) {
124
+ this.viewSelect = options.viewSelect;
125
+ } else if ('viewSelect' in this.element.data()) {
126
+ this.viewSelect = this.element.data('view-select');
127
+ }
128
+ this.viewSelect = DPGlobal.convertViewMode(this.viewSelect);
129
+
85
130
  this.forceParse = true;
86
131
  if ('forceParse' in options) {
87
132
  this.forceParse = options.forceParse;
@@ -89,30 +134,37 @@
89
134
  this.forceParse = this.element.data('date-force-parse');
90
135
  }
91
136
 
92
- this.picker = $(DPGlobal.template)
93
- .appendTo(this.isInline ? this.element : 'body')
94
- .on({
95
- click: $.proxy(this.click, this),
96
- mousedown: $.proxy(this.mousedown, this)
97
- });
98
- if (this.closeButton){
99
- this.picker.find('a.datetimepicker-close').show();
137
+ this.picker = $((this.bootcssVer == 3) ? DPGlobal.templateV3 : DPGlobal.template)
138
+ .appendTo(this.isInline ? this.element : 'body')
139
+ .on({
140
+ click: $.proxy(this.click, this),
141
+ mousedown: $.proxy(this.mousedown, this)
142
+ });
143
+
144
+ if (this.wheelViewModeNavigation) {
145
+ if ($.fn.mousewheel) {
146
+ this.picker.on({mousewheel: $.proxy(this.mousewheel, this)});
147
+ } else {
148
+ console.log("Mouse Wheel event is not supported. Please include the jQuery Mouse Wheel plugin before enabling this option");
149
+ }
100
150
  }
101
-
151
+
102
152
  if (this.isInline) {
103
153
  this.picker.addClass('datetimepicker-inline');
104
-
105
154
  } else {
106
- if (this.component && this.pickerPosition == 'bottom-left') {
107
- this.picker.addClass('datetimepicker-dropdown-left dropdown-menu');
108
- } else {
109
- this.picker.addClass('datetimepicker-dropdown dropdown-menu');
110
- }
155
+ this.picker.addClass('datetimepicker-dropdown-' + this.pickerPosition + ' dropdown-menu');
111
156
  }
112
- if (this.isRTL){
157
+ if (this.isRTL) {
113
158
  this.picker.addClass('datetimepicker-rtl');
114
- this.picker.find('.prev i, .next i')
115
- .toggleClass('icon-chevron-left icon-chevron-right');
159
+ if (this.bootcssVer == 3) {
160
+ this.picker.find('.prev span, .next span')
161
+ .toggleClass('glyphicon-arrow-left glyphicon-arrow-right');
162
+ } else {
163
+ this.picker.find('.prev i, .next i')
164
+ .toggleClass('icon-arrow-left icon-arrow-right');
165
+ }
166
+ ;
167
+
116
168
  }
117
169
  $(document).on('mousedown', function (e) {
118
170
  // Clicked outside the datetimepicker, hide it
@@ -121,7 +173,7 @@
121
173
  }
122
174
  });
123
175
 
124
- this.autoclose = true;
176
+ this.autoclose = false;
125
177
  if ('autoclose' in options) {
126
178
  this.autoclose = options.autoclose;
127
179
  } else if ('dateAutoclose' in this.element.data()) {
@@ -151,32 +203,32 @@
151
203
  this.update();
152
204
  this.showMode();
153
205
 
154
- if(this.isInline) {
155
- this.picker.show();
206
+ if (this.isInline) {
207
+ this.show();
156
208
  }
157
209
  };
158
210
 
159
211
  Datetimepicker.prototype = {
160
212
  constructor: Datetimepicker,
161
213
 
162
- _events: [],
163
- _attachEvents: function(){
214
+ _events: [],
215
+ _attachEvents: function () {
164
216
  this._detachEvents();
165
217
  if (this.isInput) { // single input
166
218
  this._events = [
167
219
  [this.element, {
168
- focus: $.proxy(this.show, this),
169
- keyup: $.proxy(this.update, this),
220
+ focus: $.proxy(this.show, this),
221
+ keyup: $.proxy(this.update, this),
170
222
  keydown: $.proxy(this.keydown, this)
171
223
  }]
172
224
  ];
173
225
  }
174
- else if (this.component && this.hasInput){ // component: input + button
226
+ else if (this.component && this.hasInput) { // component: input + button
175
227
  this._events = [
176
228
  // For components that are not readonly, allow keyboard nav
177
229
  [this.element.find('input'), {
178
- focus: $.proxy(this.show, this),
179
- keyup: $.proxy(this.update, this),
230
+ focus: $.proxy(this.show, this),
231
+ keyup: $.proxy(this.update, this),
180
232
  keydown: $.proxy(this.keydown, this)
181
233
  }],
182
234
  [this.component, {
@@ -200,15 +252,15 @@
200
252
  }]
201
253
  ];
202
254
  }
203
- for (var i=0, el, ev; i<this._events.length; i++){
255
+ for (var i = 0, el, ev; i < this._events.length; i++) {
204
256
  el = this._events[i][0];
205
257
  ev = this._events[i][1];
206
258
  el.on(ev);
207
259
  }
208
260
  },
209
-
210
- _detachEvents: function(){
211
- for (var i=0, el, ev; i<this._events.length; i++){
261
+
262
+ _detachEvents: function () {
263
+ for (var i = 0, el, ev; i < this._events.length; i++) {
212
264
  el = this._events[i][0];
213
265
  ev = this._events[i][1];
214
266
  el.off(ev);
@@ -216,7 +268,7 @@
216
268
  this._events = [];
217
269
  },
218
270
 
219
- show: function(e) {
271
+ show: function (e) {
220
272
  this.picker.show();
221
273
  this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
222
274
  if (this.forceParse) {
@@ -228,14 +280,16 @@
228
280
  e.stopPropagation();
229
281
  e.preventDefault();
230
282
  }
283
+ this.isVisible = true;
231
284
  this.element.trigger({
232
285
  type: 'show',
233
286
  date: this.date
234
287
  });
235
288
  },
236
289
 
237
- hide: function(e){
238
- if(this.isInline) return;
290
+ hide: function (e) {
291
+ if (!this.isVisible) return;
292
+ if (this.isInline) return;
239
293
  this.picker.hide();
240
294
  $(window).off('resize', this.place);
241
295
  this.viewMode = this.startViewMode;
@@ -246,38 +300,40 @@
246
300
 
247
301
  if (
248
302
  this.forceParse &&
249
- (
250
- this.isInput && this.element.val() ||
251
- this.hasInput && this.element.find('input').val()
303
+ (
304
+ this.isInput && this.element.val() ||
305
+ this.hasInput && this.element.find('input').val()
306
+ )
252
307
  )
253
- )
254
308
  this.setValue();
309
+ this.isVisible = false;
255
310
  this.element.trigger({
256
311
  type: 'hide',
257
312
  date: this.date
258
313
  });
259
314
  },
260
315
 
261
- remove: function() {
316
+ remove: function () {
262
317
  this._detachEvents();
263
318
  this.picker.remove();
319
+ delete this.picker;
264
320
  delete this.element.data().datetimepicker;
265
321
  },
266
322
 
267
- getDate: function() {
323
+ getDate: function () {
268
324
  var d = this.getUTCDate();
269
- return new Date(d.getTime() + (d.getTimezoneOffset()*60000));
325
+ return new Date(d.getTime() + (d.getTimezoneOffset() * 60000));
270
326
  },
271
327
 
272
- getUTCDate: function() {
328
+ getUTCDate: function () {
273
329
  return this.date;
274
330
  },
275
331
 
276
- setDate: function(d) {
277
- this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset()*60000)));
332
+ setDate: function (d) {
333
+ this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset() * 60000)));
278
334
  },
279
335
 
280
- setUTCDate: function(d) {
336
+ setUTCDate: function (d) {
281
337
  if (d >= this.startDate && d <= this.endDate) {
282
338
  this.date = d;
283
339
  this.setValue();
@@ -285,53 +341,66 @@
285
341
  this.fill();
286
342
  } else {
287
343
  this.element.trigger({
288
- type: 'outOfRange',
289
- date: d,
344
+ type: 'outOfRange',
345
+ date: d,
290
346
  startDate: this.startDate,
291
- endDate: this.endDate
347
+ endDate: this.endDate
292
348
  });
293
349
  }
294
350
  },
295
351
 
296
- setValue: function() {
352
+ setFormat: function (format) {
353
+ this.format = DPGlobal.parseFormat(format, this.formatType);
354
+ var element;
355
+ if (this.isInput) {
356
+ element = this.element;
357
+ } else if (this.component) {
358
+ element = this.element.find('input');
359
+ }
360
+ if (element && element.val()) {
361
+ this.setValue();
362
+ }
363
+ },
364
+
365
+ setValue: function () {
297
366
  var formatted = this.getFormattedDate();
298
367
  if (!this.isInput) {
299
- if (this.component){
300
- this.element.find('input').prop('value', formatted);
368
+ if (this.component) {
369
+ this.element.find('input').val(formatted);
301
370
  }
302
371
  this.element.data('date', formatted);
303
372
  } else {
304
- this.element.prop('value', formatted);
373
+ this.element.val(formatted);
305
374
  }
306
375
  if (this.linkField) {
307
376
  $('#' + this.linkField).val(this.getFormattedDate(this.linkFormat));
308
377
  }
309
378
  },
310
379
 
311
- getFormattedDate: function(format) {
312
- if(format == undefined) format = this.format;
313
- return DPGlobal.formatDate(this.date, format, this.language);
380
+ getFormattedDate: function (format) {
381
+ if (format == undefined) format = this.format;
382
+ return DPGlobal.formatDate(this.date, format, this.language, this.formatType);
314
383
  },
315
384
 
316
- setStartDate: function(startDate){
385
+ setStartDate: function (startDate) {
317
386
  this.startDate = startDate || -Infinity;
318
387
  if (this.startDate !== -Infinity) {
319
- this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language);
388
+ this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language, this.formatType);
320
389
  }
321
390
  this.update();
322
391
  this.updateNavArrows();
323
392
  },
324
393
 
325
- setEndDate: function(endDate){
394
+ setEndDate: function (endDate) {
326
395
  this.endDate = endDate || Infinity;
327
396
  if (this.endDate !== Infinity) {
328
- this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language);
397
+ this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language, this.formatType);
329
398
  }
330
399
  this.update();
331
400
  this.updateNavArrows();
332
401
  },
333
402
 
334
- setDaysOfWeekDisabled: function(daysOfWeekDisabled){
403
+ setDaysOfWeekDisabled: function (daysOfWeekDisabled) {
335
404
  this.daysOfWeekDisabled = daysOfWeekDisabled || [];
336
405
  if (!$.isArray(this.daysOfWeekDisabled)) {
337
406
  this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/);
@@ -343,41 +412,61 @@
343
412
  this.updateNavArrows();
344
413
  },
345
414
 
346
- place: function(){
347
- if(this.isInline) return;
348
- var zIndex = parseInt(this.element.parents().filter(function() {
349
- return $(this).css('z-index') != 'auto';
350
- }).first().css('z-index'))+10;
351
- var offset, left;
415
+ place: function () {
416
+ if (this.isInline) return;
417
+
418
+ var index_highest = 0;
419
+ $('div').each(function () {
420
+ var index_current = parseInt($(this).css("zIndex"), 10);
421
+ if (index_current > index_highest) {
422
+ index_highest = index_current;
423
+ }
424
+ });
425
+ var zIndex = index_highest + 10;
426
+
427
+ var offset, top, left;
352
428
  if (this.component) {
353
429
  offset = this.component.offset();
354
430
  left = offset.left;
355
- if (this.pickerPosition == 'bottom-left') {
431
+ if (this.pickerPosition == 'bottom-left' || this.pickerPosition == 'top-left') {
356
432
  left += this.component.outerWidth() - this.picker.outerWidth();
357
433
  }
358
434
  } else {
359
435
  offset = this.element.offset();
360
436
  left = offset.left;
361
437
  }
438
+ if (this.pickerPosition == 'top-left' || this.pickerPosition == 'top-right') {
439
+ top = offset.top - this.picker.outerHeight();
440
+ } else {
441
+ top = offset.top + this.height;
442
+ }
362
443
  this.picker.css({
363
- top: offset.top + this.height,
364
- left: left,
444
+ top: top,
445
+ left: left,
365
446
  zIndex: zIndex
366
447
  });
367
448
  },
368
449
 
369
- update: function(){
450
+ update: function () {
370
451
  var date, fromArgs = false;
371
- if(arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) {
452
+ if (arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) {
372
453
  date = arguments[0];
373
454
  fromArgs = true;
374
455
  } else {
375
- date = this.isInput ? this.element.prop('value') : this.element.data('date') || this.element.find('input').prop('value');
456
+ date = this.element.data('date') || (this.isInput ? this.element.val() : this.element.find('input').val()) || this.initialDate;
457
+ if (typeof date == 'string' || date instanceof String) {
458
+ date = date.replace(/^\s+|\s+$/g,'');
459
+ }
460
+ }
461
+
462
+ if (!date) {
463
+ date = new Date();
464
+ fromArgs = false;
376
465
  }
377
-
378
- this.date = DPGlobal.parseDate(date, this.format, this.language);
379
466
 
380
- if(fromArgs) this.setValue();
467
+ this.date = DPGlobal.parseDate(date, this.format, this.language, this.formatType);
468
+
469
+ if (fromArgs) this.setValue();
381
470
 
382
471
  if (this.date < this.startDate) {
383
472
  this.viewDate = new Date(this.startDate);
@@ -389,30 +478,29 @@
389
478
  this.fill();
390
479
  },
391
480
 
392
- fillDow: function(){
481
+ fillDow: function () {
393
482
  var dowCnt = this.weekStart,
394
- html = '<tr>';
483
+ html = '<tr>';
395
484
  while (dowCnt < this.weekStart + 7) {
396
- html += '<th class="dow">'+dates[this.language].daysMin[(dowCnt++)%7]+'</th>';
485
+ html += '<th class="dow">' + dates[this.language].daysMin[(dowCnt++) % 7] + '</th>';
397
486
  }
398
487
  html += '</tr>';
399
488
  this.picker.find('.datetimepicker-days thead').append(html);
400
489
  },
401
490
 
402
- fillMonths: function(){
491
+ fillMonths: function () {
403
492
  var html = '',
404
- i = 0;
493
+ i = 0;
405
494
  while (i < 12) {
406
- html += '<span class="month">'+dates[this.language].monthsShort[i++]+'</span>';
495
+ html += '<span class="month">' + dates[this.language].monthsShort[i++] + '</span>';
407
496
  }
408
497
  this.picker.find('.datetimepicker-months td').html(html);
409
498
  },
410
499
 
411
- fill: function() {
500
+ fill: function () {
412
501
  if (this.date == null || this.viewDate == null) {
413
502
  return;
414
503
  }
415
-
416
504
  var d = new Date(this.viewDate),
417
505
  year = d.getUTCFullYear(),
418
506
  month = d.getUTCMonth(),
@@ -426,24 +514,39 @@
426
514
  currentDate = (new UTCDate(this.date.getUTCFullYear(), this.date.getUTCMonth(), this.date.getUTCDate())).valueOf(),
427
515
  today = new Date();
428
516
  this.picker.find('.datetimepicker-days thead th:eq(1)')
429
- .text(dates[this.language].months[month]+' '+year);
430
- this.picker.find('.datetimepicker-hours thead th:eq(1)')
431
- .text(dayMonth+' '+dates[this.language].months[month]+' '+year);
432
- this.picker.find('.datetimepicker-minutes thead th:eq(1)')
433
- .text(dayMonth+' '+dates[this.language].months[month]+' '+year);
517
+ .text(dates[this.language].months[month] + ' ' + year);
518
+ if (this.formatViewType == "time") {
519
+ var hourConverted = hours % 12 ? hours % 12 : 12;
520
+ var hoursDisplay = (hourConverted < 10 ? '0' : '') + hourConverted;
521
+ var minutesDisplay = (minutes < 10 ? '0' : '') + minutes;
522
+ var meridianDisplay = dates[this.language].meridiem[hours < 12 ? 0 : 1];
523
+ this.picker.find('.datetimepicker-hours thead th:eq(1)')
524
+ .text(hoursDisplay + ':' + minutesDisplay + ' ' + meridianDisplay.toUpperCase());
525
+ this.picker.find('.datetimepicker-minutes thead th:eq(1)')
526
+ .text(hoursDisplay + ':' + minutesDisplay + ' ' + meridianDisplay.toUpperCase());
527
+ } else {
528
+ this.picker.find('.datetimepicker-hours thead th:eq(1)')
529
+ .text(dayMonth + ' ' + dates[this.language].months[month] + ' ' + year);
530
+ this.picker.find('.datetimepicker-minutes thead th:eq(1)')
531
+ .text(dayMonth + ' ' + dates[this.language].months[month] + ' ' + year);
532
+ }
434
533
  this.picker.find('tfoot th.today')
435
- .text(dates[this.language].today)
436
- .toggle(this.todayBtn !== false);
534
+ .text(dates[this.language].today)
535
+ .toggle(this.todayBtn !== false);
437
536
  this.updateNavArrows();
438
537
  this.fillMonths();
439
- var prevMonth = UTCDate(year, month, 0,0,0,0,0);
440
- prevMonth.setUTCDate(prevMonth.getDate() - (prevMonth.getUTCDay() - this.weekStart + 7)%7);
538
+ /*var prevMonth = UTCDate(year, month, 0,0,0,0,0);
539
+ prevMonth.setUTCDate(prevMonth.getDate() - (prevMonth.getUTCDay() - this.weekStart + 7)%7);*/
540
+ var prevMonth = UTCDate(year, month - 1, 28, 0, 0, 0, 0),
541
+ day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
542
+ prevMonth.setUTCDate(day);
543
+ prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7) % 7);
441
544
  var nextMonth = new Date(prevMonth);
442
545
  nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
443
546
  nextMonth = nextMonth.valueOf();
444
547
  var html = [];
445
548
  var clsName;
446
- while(prevMonth.valueOf() < nextMonth) {
549
+ while (prevMonth.valueOf() < nextMonth) {
447
550
  if (prevMonth.getUTCDay() == this.weekStart) {
448
551
  html.push('<tr>');
449
552
  }
@@ -463,51 +566,89 @@
463
566
  if (prevMonth.valueOf() == currentDate) {
464
567
  clsName += ' active';
465
568
  }
466
- if ((prevMonth.valueOf() + 86400000) < this.startDate || prevMonth.valueOf() > this.endDate ||
569
+ if ((prevMonth.valueOf() + 86400000) <= this.startDate || prevMonth.valueOf() > this.endDate ||
467
570
  $.inArray(prevMonth.getUTCDay(), this.daysOfWeekDisabled) !== -1) {
468
571
  clsName += ' disabled';
469
572
  }
470
- html.push('<td class="day'+clsName+'">'+prevMonth.getUTCDate() + '</td>');
573
+ html.push('<td class="day' + clsName + '">' + prevMonth.getUTCDate() + '</td>');
471
574
  if (prevMonth.getUTCDay() == this.weekEnd) {
472
575
  html.push('</tr>');
473
576
  }
474
- prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
577
+ prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);
475
578
  }
476
579
  this.picker.find('.datetimepicker-days tbody').empty().append(html.join(''));
477
580
 
478
581
  html = [];
479
- for (var i=0;i<24;i++) {
582
+ var txt = '', meridian = '', meridianOld = '';
583
+ for (var i = 0; i < 24; i++) {
480
584
  var actual = UTCDate(year, month, dayMonth, i);
481
585
  clsName = '';
482
586
  // We want the previous hour for the startDate
483
- if ((actual.valueOf() + 3600000) < this.startDate || actual.valueOf() > this.endDate) {
587
+ if ((actual.valueOf() + 3600000) <= this.startDate || actual.valueOf() > this.endDate) {
484
588
  clsName += ' disabled';
485
589
  } else if (hours == i) {
486
590
  clsName += ' active';
487
591
  }
488
- html.push('<span class="hour'+clsName+'">'+i+':00</span>');
592
+ if (this.showMeridian && dates[this.language].meridiem.length == 2) {
593
+ meridian = (i < 12 ? dates[this.language].meridiem[0] : dates[this.language].meridiem[1]);
594
+ if (meridian != meridianOld) {
595
+ if (meridianOld != '') {
596
+ html.push('</fieldset>');
597
+ }
598
+ html.push('<fieldset class="hour"><legend>' + meridian.toUpperCase() + '</legend>');
599
+ }
600
+ meridianOld = meridian;
601
+ txt = (i % 12 ? i % 12 : 12);
602
+ html.push('<span class="hour' + clsName + ' hour_' + (i < 12 ? 'am' : 'pm') + '">' + txt + '</span>');
603
+ if (i == 23) {
604
+ html.push('</fieldset>');
605
+ }
606
+ } else {
607
+ txt = i + ':00';
608
+ html.push('<span class="hour' + clsName + '">' + txt + '</span>');
609
+ }
489
610
  }
490
611
  this.picker.find('.datetimepicker-hours td').html(html.join(''));
491
612
 
492
613
  html = [];
493
- for(var i=0;i<60;i+=this.minuteStep) {
494
- var actual = UTCDate(year, month, dayMonth, hours, i);
614
+ txt = '', meridian = '', meridianOld = '';
615
+ for (var i = 0; i < 60; i += this.minuteStep) {
616
+ var actual = UTCDate(year, month, dayMonth, hours, i, 0);
495
617
  clsName = '';
496
618
  if (actual.valueOf() < this.startDate || actual.valueOf() > this.endDate) {
497
619
  clsName += ' disabled';
498
- } else if (Math.floor(minutes/this.minuteStep) == Math.floor(i/this.minuteStep)) {
620
+ } else if (Math.floor(minutes / this.minuteStep) == Math.floor(i / this.minuteStep)) {
499
621
  clsName += ' active';
500
622
  }
501
- html.push('<span class="minute'+clsName+'">'+hours+':'+(i<10?'0'+i:i)+'</span>');
623
+ if (this.showMeridian && dates[this.language].meridiem.length == 2) {
624
+ meridian = (hours < 12 ? dates[this.language].meridiem[0] : dates[this.language].meridiem[1]);
625
+ if (meridian != meridianOld) {
626
+ if (meridianOld != '') {
627
+ html.push('</fieldset>');
628
+ }
629
+ html.push('<fieldset class="minute"><legend>' + meridian.toUpperCase() + '</legend>');
630
+ }
631
+ meridianOld = meridian;
632
+ txt = (hours % 12 ? hours % 12 : 12);
633
+ //html.push('<span class="minute'+clsName+' minute_'+(hours<12?'am':'pm')+'">'+txt+'</span>');
634
+ html.push('<span class="minute' + clsName + '">' + txt + ':' + (i < 10 ? '0' + i : i) + '</span>');
635
+ if (i == 59) {
636
+ html.push('</fieldset>');
637
+ }
638
+ } else {
639
+ txt = i + ':00';
640
+ //html.push('<span class="hour'+clsName+'">'+txt+'</span>');
641
+ html.push('<span class="minute' + clsName + '">' + hours + ':' + (i < 10 ? '0' + i : i) + '</span>');
642
+ }
502
643
  }
503
644
  this.picker.find('.datetimepicker-minutes td').html(html.join(''));
504
645
 
505
646
  var currentYear = this.date.getUTCFullYear();
506
647
  var months = this.picker.find('.datetimepicker-months')
507
- .find('th:eq(1)')
508
- .text(year)
509
- .end()
510
- .find('span').removeClass('active');
648
+ .find('th:eq(1)')
649
+ .text(year)
650
+ .end()
651
+ .find('span').removeClass('active');
511
652
  if (currentYear == year) {
512
653
  months.eq(this.date.getUTCMonth()).addClass('active');
513
654
  }
@@ -518,25 +659,26 @@
518
659
  months.slice(0, startMonth).addClass('disabled');
519
660
  }
520
661
  if (year == endYear) {
521
- months.slice(endMonth+1).addClass('disabled');
662
+ months.slice(endMonth + 1).addClass('disabled');
522
663
  }
523
664
 
524
665
  html = '';
525
- year = parseInt(year/10, 10) * 10;
666
+ year = parseInt(year / 10, 10) * 10;
526
667
  var yearCont = this.picker.find('.datetimepicker-years')
527
- .find('th:eq(1)')
528
- .text(year + '-' + (year + 9))
529
- .end()
530
- .find('td');
668
+ .find('th:eq(1)')
669
+ .text(year + '-' + (year + 9))
670
+ .end()
671
+ .find('td');
531
672
  year -= 1;
532
673
  for (var i = -1; i < 11; i++) {
533
- html += '<span class="year'+(i == -1 || i == 10 ? ' old' : '')+(currentYear == year ? ' active' : '')+(year < startYear || year > endYear ? ' disabled' : '')+'">'+year+'</span>';
674
+ html += '<span class="year' + (i == -1 || i == 10 ? ' old' : '') + (currentYear == year ? ' active' : '') + (year < startYear || year > endYear ? ' disabled' : '') + '">' + year + '</span>';
534
675
  year += 1;
535
676
  }
536
677
  yearCont.html(html);
678
+ this.place();
537
679
  },
538
680
 
539
- updateNavArrows: function() {
681
+ updateNavArrows: function () {
540
682
  var d = new Date(this.viewDate),
541
683
  year = d.getUTCFullYear(),
542
684
  month = d.getUTCMonth(),
@@ -544,48 +686,48 @@
544
686
  hour = d.getUTCHours();
545
687
  switch (this.viewMode) {
546
688
  case 0:
547
- if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()
548
- && month <= this.startDate.getUTCMonth()
549
- && day <= this.startDate.getUTCDate()
550
- && hour <= this.startDate.getUTCHours()) {
689
+ if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()
690
+ && month <= this.startDate.getUTCMonth()
691
+ && day <= this.startDate.getUTCDate()
692
+ && hour <= this.startDate.getUTCHours()) {
551
693
  this.picker.find('.prev').css({visibility: 'hidden'});
552
694
  } else {
553
695
  this.picker.find('.prev').css({visibility: 'visible'});
554
696
  }
555
- if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()
556
- && month >= this.endDate.getUTCMonth()
557
- && day >= this.endDate.getUTCDate()
558
- && hour >= this.endDate.getUTCHours()) {
697
+ if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()
698
+ && month >= this.endDate.getUTCMonth()
699
+ && day >= this.endDate.getUTCDate()
700
+ && hour >= this.endDate.getUTCHours()) {
559
701
  this.picker.find('.next').css({visibility: 'hidden'});
560
702
  } else {
561
703
  this.picker.find('.next').css({visibility: 'visible'});
562
704
  }
563
705
  break;
564
706
  case 1:
565
- if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()
566
- && month <= this.startDate.getUTCMonth()
567
- && day <= this.startDate.getUTCDate()) {
707
+ if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()
708
+ && month <= this.startDate.getUTCMonth()
709
+ && day <= this.startDate.getUTCDate()) {
568
710
  this.picker.find('.prev').css({visibility: 'hidden'});
569
711
  } else {
570
712
  this.picker.find('.prev').css({visibility: 'visible'});
571
713
  }
572
- if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()
573
- && month >= this.endDate.getUTCMonth()
574
- && day >= this.endDate.getUTCDate()) {
714
+ if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()
715
+ && month >= this.endDate.getUTCMonth()
716
+ && day >= this.endDate.getUTCDate()) {
575
717
  this.picker.find('.next').css({visibility: 'hidden'});
576
718
  } else {
577
719
  this.picker.find('.next').css({visibility: 'visible'});
578
720
  }
579
721
  break;
580
722
  case 2:
581
- if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()
582
- && month <= this.startDate.getUTCMonth()) {
723
+ if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()
724
+ && month <= this.startDate.getUTCMonth()) {
583
725
  this.picker.find('.prev').css({visibility: 'hidden'});
584
726
  } else {
585
727
  this.picker.find('.prev').css({visibility: 'visible'});
586
728
  }
587
- if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()
588
- && month >= this.endDate.getUTCMonth()) {
729
+ if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()
730
+ && month >= this.endDate.getUTCMonth()) {
589
731
  this.picker.find('.next').css({visibility: 'hidden'});
590
732
  } else {
591
733
  this.picker.find('.next').css({visibility: 'visible'});
@@ -607,35 +749,61 @@
607
749
  }
608
750
  },
609
751
 
610
- click: function(e) {
611
- e.stopPropagation();
752
+ mousewheel: function (e) {
753
+
612
754
  e.preventDefault();
613
-
614
- if ($(e.target).hasClass('datetimepicker-close')){
615
- this.hide();
755
+ e.stopPropagation();
756
+
757
+ if (this.wheelPause) {
758
+ return;
759
+ }
760
+
761
+ this.wheelPause = true;
762
+
763
+ var originalEvent = e.originalEvent;
764
+
765
+ var delta = originalEvent.wheelDelta;
766
+
767
+ var mode = delta > 0 ? 1 : (delta === 0) ? 0 : -1;
768
+
769
+ if (this.wheelViewModeNavigationInverseDirection) {
770
+ mode = -mode;
616
771
  }
617
-
618
- var target = $(e.target).closest('span, td, th');
772
+
773
+ this.showMode(mode);
774
+
775
+ setTimeout($.proxy(function () {
776
+
777
+ this.wheelPause = false
778
+
779
+ }, this), this.wheelViewModeNavigationDelay);
780
+
781
+ },
782
+
783
+ click: function (e) {
784
+ e.stopPropagation();
785
+ e.preventDefault();
786
+ var target = $(e.target).closest('span, td, th, legend');
619
787
  if (target.length == 1) {
620
788
  if (target.is('.disabled')) {
621
789
  this.element.trigger({
622
- type: 'outOfRange',
623
- date: this.viewDate,
790
+ type: 'outOfRange',
791
+ date: this.viewDate,
624
792
  startDate: this.startDate,
625
- endDate: this.endDate
793
+ endDate: this.endDate
626
794
  });
627
795
  return;
628
796
  }
629
- switch(target[0].nodeName.toLowerCase()) {
797
+ switch (target[0].nodeName.toLowerCase()) {
630
798
  case 'th':
631
- switch(target[0].className) {
799
+ switch (target[0].className) {
632
800
  case 'switch':
633
801
  this.showMode(1);
634
802
  break;
635
803
  case 'prev':
636
804
  case 'next':
637
805
  var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1);
638
- switch(this.viewMode){
806
+ switch (this.viewMode) {
639
807
  case 0:
640
808
  this.viewDate = this.moveHour(this.viewDate, dir);
641
809
  break;
@@ -654,48 +822,81 @@
654
822
  break;
655
823
  case 'today':
656
824
  var date = new Date();
657
- date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
825
+ date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0);
826
+
827
+ // Respect startDate and endDate.
828
+ if (date < this.startDate) date = this.startDate;
829
+ else if (date > this.endDate) date = this.endDate;
658
830
 
659
831
  this.viewMode = this.startViewMode;
660
832
  this.showMode(0);
661
833
  this._setDate(date);
834
+ this.fill();
835
+ if (this.autoclose) {
836
+ this.hide();
837
+ }
662
838
  break;
663
839
  }
664
840
  break;
665
841
  case 'span':
666
842
  if (!target.is('.disabled')) {
843
+ var year = this.viewDate.getUTCFullYear(),
844
+ month = this.viewDate.getUTCMonth(),
845
+ day = this.viewDate.getUTCDate(),
846
+ hours = this.viewDate.getUTCHours(),
847
+ minutes = this.viewDate.getUTCMinutes(),
848
+ seconds = this.viewDate.getUTCSeconds();
849
+
667
850
  if (target.is('.month')) {
668
851
  this.viewDate.setUTCDate(1);
669
- var month = target.parent().find('span').index(target);
852
+ month = target.parent().find('span').index(target);
853
+ day = this.viewDate.getUTCDate();
670
854
  this.viewDate.setUTCMonth(month);
671
855
  this.element.trigger({
672
856
  type: 'changeMonth',
673
857
  date: this.viewDate
674
858
  });
859
+ if (this.viewSelect >= 3) {
860
+ this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
861
+ }
675
862
  } else if (target.is('.year')) {
676
863
  this.viewDate.setUTCDate(1);
677
- var year = parseInt(target.text(), 10) || 0;
864
+ year = parseInt(target.text(), 10) || 0;
678
865
  this.viewDate.setUTCFullYear(year);
679
866
  this.element.trigger({
680
867
  type: 'changeYear',
681
868
  date: this.viewDate
682
869
  });
683
- } else if (target.is('.hour')){
684
- var hours = parseInt(target.text(), 10) || 0;
685
- var year = this.viewDate.getUTCFullYear(),
686
- month = this.viewDate.getUTCMonth(),
687
- day = this.viewDate.getUTCDate(),
688
- minutes = this.viewDate.getUTCMinutes(),
689
- seconds = this.viewDate.getUTCSeconds();
690
- this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
691
- } else if (target.is('.minute')){
692
- var minutes = parseInt(target.text().substr(target.text().indexOf(':')+1), 10) || 0;
693
- var year = this.viewDate.getUTCFullYear(),
694
- month = this.viewDate.getUTCMonth(),
695
- day = this.viewDate.getUTCDate(),
696
- hours = this.viewDate.getUTCHours(),
697
- seconds = this.viewDate.getUTCSeconds();
698
- this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
870
+ if (this.viewSelect >= 4) {
871
+ this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
872
+ }
873
+ } else if (target.is('.hour')) {
874
+ hours = parseInt(target.text(), 10) || 0;
875
+ if (target.hasClass('hour_am') || target.hasClass('hour_pm')) {
876
+ if (hours == 12 && target.hasClass('hour_am')) {
877
+ hours = 0;
878
+ } else if (hours != 12 && target.hasClass('hour_pm')) {
879
+ hours += 12;
880
+ }
881
+ }
882
+ this.viewDate.setUTCHours(hours);
883
+ this.element.trigger({
884
+ type: 'changeHour',
885
+ date: this.viewDate
886
+ });
887
+ if (this.viewSelect >= 1) {
888
+ this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
889
+ }
890
+ } else if (target.is('.minute')) {
891
+ minutes = parseInt(target.text().substr(target.text().indexOf(':') + 1), 10) || 0;
892
+ this.viewDate.setUTCMinutes(minutes);
893
+ this.element.trigger({
894
+ type: 'changeMinute',
895
+ date: this.viewDate
896
+ });
897
+ if (this.viewSelect >= 0) {
898
+ this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
899
+ }
699
900
  }
700
901
  if (this.viewMode != 0) {
701
902
  var oldViewMode = this.viewMode;
@@ -713,7 +914,7 @@
713
914
  }
714
915
  break;
715
916
  case 'td':
716
- if (target.is('.day') && !target.is('.disabled')){
917
+ if (target.is('.day') && !target.is('.disabled')) {
717
918
  var day = parseInt(target.text(), 10) || 1;
718
919
  var year = this.viewDate.getUTCFullYear(),
719
920
  month = this.viewDate.getUTCMonth(),
@@ -735,7 +936,15 @@
735
936
  month += 1;
736
937
  }
737
938
  }
738
- this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
939
+ this.viewDate.setUTCFullYear(year);
940
+ this.viewDate.setUTCMonth(month, day);
941
+ this.element.trigger({
942
+ type: 'changeDay',
943
+ date: this.viewDate
944
+ });
945
+ if (this.viewSelect >= 2) {
946
+ this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));
947
+ }
739
948
  }
740
949
  var oldViewMode = this.viewMode;
741
950
  this.showMode(-1);
@@ -748,21 +957,17 @@
748
957
  }
749
958
  },
750
959
 
751
- _setDate: function(date, which){
960
+ _setDate: function (date, which) {
752
961
  if (!which || which == 'date')
753
962
  this.date = date;
754
- if (!which || which == 'view')
963
+ if (!which || which == 'view')
755
964
  this.viewDate = date;
756
965
  this.fill();
757
- this.element.trigger({
758
- type: 'changeDate',
759
- date: this.date
760
- });
761
966
  this.setValue();
762
967
  var element;
763
968
  if (this.isInput) {
764
969
  element = this.element;
765
- } else if (this.component){
970
+ } else if (this.component) {
766
971
  element = this.element.find('input');
767
972
  }
768
973
  if (element) {
@@ -771,25 +976,37 @@
771
976
  //this.hide();
772
977
  }
773
978
  }
979
+ this.element.trigger({
980
+ type: 'changeDate',
981
+ date: this.date
982
+ });
774
983
  },
775
984
 
776
- moveHour: function(date, dir){
985
+ moveMinute: function (date, dir) {
777
986
  if (!dir) return date;
778
987
  var new_date = new Date(date.valueOf());
779
- dir = dir > 0 ? 1 : -1;
988
+ //dir = dir > 0 ? 1 : -1;
989
+ new_date.setUTCMinutes(new_date.getUTCMinutes() + (dir * this.minuteStep));
990
+ return new_date;
991
+ },
992
+
993
+ moveHour: function (date, dir) {
994
+ if (!dir) return date;
995
+ var new_date = new Date(date.valueOf());
996
+ //dir = dir > 0 ? 1 : -1;
780
997
  new_date.setUTCHours(new_date.getUTCHours() + dir);
781
998
  return new_date;
782
999
  },
783
1000
 
784
- moveDate: function(date, dir){
1001
+ moveDate: function (date, dir) {
785
1002
  if (!dir) return date;
786
1003
  var new_date = new Date(date.valueOf());
787
- dir = dir > 0 ? 1 : -1;
1004
+ //dir = dir > 0 ? 1 : -1;
788
1005
  new_date.setUTCDate(new_date.getUTCDate() + dir);
789
1006
  return new_date;
790
1007
  },
791
1008
 
792
- moveMonth: function(date, dir){
1009
+ moveMonth: function (date, dir) {
793
1010
  if (!dir) return date;
794
1011
  var new_date = new Date(date.valueOf()),
795
1012
  day = new_date.getUTCDate(),
@@ -797,14 +1014,18 @@
797
1014
  mag = Math.abs(dir),
798
1015
  new_month, test;
799
1016
  dir = dir > 0 ? 1 : -1;
800
- if (mag == 1){
1017
+ if (mag == 1) {
801
1018
  test = dir == -1
802
1019
  // If going back one month, make sure month is not current month
803
1020
  // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
804
- ? function(){ return new_date.getUTCMonth() == month; }
1021
+ ? function () {
1022
+ return new_date.getUTCMonth() == month;
1023
+ }
805
1024
  // If going forward one month, make sure month is as expected
806
1025
  // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
807
- : function(){ return new_date.getUTCMonth() != new_month; };
1026
+ : function () {
1027
+ return new_date.getUTCMonth() != new_month;
1028
+ };
808
1029
  new_month = month + dir;
809
1030
  new_date.setUTCMonth(new_month);
810
1031
  // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
@@ -812,33 +1033,35 @@
812
1033
  new_month = (new_month + 12) % 12;
813
1034
  } else {
814
1035
  // For magnitudes >1, move one month at a time...
815
- for (var i=0; i<mag; i++)
1036
+ for (var i = 0; i < mag; i++)
816
1037
  // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
817
1038
  new_date = this.moveMonth(new_date, dir);
818
1039
  // ...then reset the day, keeping it in the new month
819
1040
  new_month = new_date.getUTCMonth();
820
1041
  new_date.setUTCDate(day);
821
- test = function(){ return new_month != new_date.getUTCMonth(); };
1042
+ test = function () {
1043
+ return new_month != new_date.getUTCMonth();
1044
+ };
822
1045
  }
823
1046
  // Common date-resetting loop -- if date is beyond end of month, make it
824
1047
  // end of month
825
- while (test()){
1048
+ while (test()) {
826
1049
  new_date.setUTCDate(--day);
827
1050
  new_date.setUTCMonth(new_month);
828
1051
  }
829
1052
  return new_date;
830
1053
  },
831
1054
 
832
- moveYear: function(date, dir){
833
- return this.moveMonth(date, dir*12);
1055
+ moveYear: function (date, dir) {
1056
+ return this.moveMonth(date, dir * 12);
834
1057
  },
835
1058
 
836
- dateWithinRange: function(date){
1059
+ dateWithinRange: function (date) {
837
1060
  return date >= this.startDate && date <= this.endDate;
838
1061
  },
839
1062
 
840
- keydown: function(e){
841
- if (this.picker.is(':not(:visible)')){
1063
+ keydown: function (e) {
1064
+ if (this.picker.is(':not(:visible)')) {
842
1065
  if (e.keyCode == 27) // allow escape to hide and re-show picker
843
1066
  this.show();
844
1067
  return;
@@ -846,7 +1069,7 @@
846
1069
  var dateChanged = false,
847
1070
  dir, day, month,
848
1071
  newDate, newViewDate;
849
- switch(e.keyCode){
1072
+ switch (e.keyCode) {
850
1073
  case 27: // escape
851
1074
  this.hide();
852
1075
  e.preventDefault();
@@ -855,19 +1078,29 @@
855
1078
  case 39: // right
856
1079
  if (!this.keyboardNavigation) break;
857
1080
  dir = e.keyCode == 37 ? -1 : 1;
858
- if (e.ctrlKey){
1081
+ viewMode = this.viewMode;
1082
+ if (e.ctrlKey) {
1083
+ viewMode += 2;
1084
+ } else if (e.shiftKey) {
1085
+ viewMode += 1;
1086
+ }
1087
+ if (viewMode == 4) {
859
1088
  newDate = this.moveYear(this.date, dir);
860
1089
  newViewDate = this.moveYear(this.viewDate, dir);
861
- } else if (e.shiftKey){
1090
+ } else if (viewMode == 3) {
862
1091
  newDate = this.moveMonth(this.date, dir);
863
1092
  newViewDate = this.moveMonth(this.viewDate, dir);
864
- } else {
865
- newDate = new Date(this.date);
866
- newDate.setUTCDate(this.date.getUTCDate() + dir);
867
- newViewDate = new Date(this.viewDate);
868
- newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir);
1093
+ } else if (viewMode == 2) {
1094
+ newDate = this.moveDate(this.date, dir);
1095
+ newViewDate = this.moveDate(this.viewDate, dir);
1096
+ } else if (viewMode == 1) {
1097
+ newDate = this.moveHour(this.date, dir);
1098
+ newViewDate = this.moveHour(this.viewDate, dir);
1099
+ } else if (viewMode == 0) {
1100
+ newDate = this.moveMinute(this.date, dir);
1101
+ newViewDate = this.moveMinute(this.viewDate, dir);
869
1102
  }
870
- if (this.dateWithinRange(newDate)){
1103
+ if (this.dateWithinRange(newDate)) {
871
1104
  this.date = newDate;
872
1105
  this.viewDate = newViewDate;
873
1106
  this.setValue();
@@ -880,19 +1113,34 @@
880
1113
  case 40: // down
881
1114
  if (!this.keyboardNavigation) break;
882
1115
  dir = e.keyCode == 38 ? -1 : 1;
883
- if (e.ctrlKey){
1116
+ viewMode = this.viewMode;
1117
+ if (e.ctrlKey) {
1118
+ viewMode += 2;
1119
+ } else if (e.shiftKey) {
1120
+ viewMode += 1;
1121
+ }
1122
+ if (viewMode == 4) {
884
1123
  newDate = this.moveYear(this.date, dir);
885
1124
  newViewDate = this.moveYear(this.viewDate, dir);
886
- } else if (e.shiftKey){
1125
+ } else if (viewMode == 3) {
887
1126
  newDate = this.moveMonth(this.date, dir);
888
1127
  newViewDate = this.moveMonth(this.viewDate, dir);
889
- } else {
890
- newDate = new Date(this.date);
891
- newDate.setUTCDate(this.date.getUTCDate() + dir * 7);
892
- newViewDate = new Date(this.viewDate);
893
- newViewDate.setUTCDate(this.viewDate.getUTCDate() + dir * 7);
1128
+ } else if (viewMode == 2) {
1129
+ newDate = this.moveDate(this.date, dir * 7);
1130
+ newViewDate = this.moveDate(this.viewDate, dir * 7);
1131
+ } else if (viewMode == 1) {
1132
+ if (this.showMeridian) {
1133
+ newDate = this.moveHour(this.date, dir * 6);
1134
+ newViewDate = this.moveHour(this.viewDate, dir * 6);
1135
+ } else {
1136
+ newDate = this.moveHour(this.date, dir * 4);
1137
+ newViewDate = this.moveHour(this.viewDate, dir * 4);
1138
+ }
1139
+ } else if (viewMode == 0) {
1140
+ newDate = this.moveMinute(this.date, dir * 4);
1141
+ newViewDate = this.moveMinute(this.viewDate, dir * 4);
894
1142
  }
895
- if (this.dateWithinRange(newDate)){
1143
+ if (this.dateWithinRange(newDate)) {
896
1144
  this.date = newDate;
897
1145
  this.viewDate = newViewDate;
898
1146
  this.setValue();
@@ -902,57 +1150,76 @@
902
1150
  }
903
1151
  break;
904
1152
  case 13: // enter
905
- this.hide();
1153
+ if (this.viewMode != 0) {
1154
+ var oldViewMode = this.viewMode;
1155
+ this.showMode(-1);
1156
+ this.fill();
1157
+ if (oldViewMode == this.viewMode && this.autoclose) {
1158
+ this.hide();
1159
+ }
1160
+ } else {
1161
+ this.fill();
1162
+ if (this.autoclose) {
1163
+ this.hide();
1164
+ }
1165
+ }
906
1166
  e.preventDefault();
907
1167
  break;
908
1168
  case 9: // tab
909
1169
  this.hide();
910
1170
  break;
911
1171
  }
912
- if (dateChanged){
913
- this.element.trigger({
914
- type: 'changeDate',
915
- date: this.date
916
- });
1172
+ if (dateChanged) {
917
1173
  var element;
918
1174
  if (this.isInput) {
919
1175
  element = this.element;
920
- } else if (this.component){
1176
+ } else if (this.component) {
921
1177
  element = this.element.find('input');
922
1178
  }
923
1179
  if (element) {
924
1180
  element.change();
925
1181
  }
1182
+ this.element.trigger({
1183
+ type: 'changeDate',
1184
+ date: this.date
1185
+ });
926
1186
  }
927
1187
  },
928
1188
 
929
- showMode: function(dir) {
1189
+ showMode: function (dir) {
930
1190
  if (dir) {
931
1191
  var newViewMode = Math.max(0, Math.min(DPGlobal.modes.length - 1, this.viewMode + dir));
932
1192
  if (newViewMode >= this.minView && newViewMode <= this.maxView) {
1193
+ this.element.trigger({
1194
+ type: 'changeMode',
1195
+ date: this.viewDate,
1196
+ oldViewMode: this.viewMode,
1197
+ newViewMode: newViewMode
1198
+ });
1199
+
933
1200
  this.viewMode = newViewMode;
934
1201
  }
935
1202
  }
936
1203
  /*
937
- vitalets: fixing bug of very special conditions:
938
- jquery 1.7.1 + webkit + show inline datetimepicker in bootstrap popover.
939
- Method show() does not set display css correctly and datetimepicker is not shown.
940
- Changed to .css('display', 'block') solve the problem.
941
- See https://github.com/vitalets/x-editable/issues/37
942
-
943
- In jquery 1.7.2+ everything works fine.
944
- */
1204
+ vitalets: fixing bug of very special conditions:
1205
+ jquery 1.7.1 + webkit + show inline datetimepicker in bootstrap popover.
1206
+ Method show() does not set display css correctly and datetimepicker is not shown.
1207
+ Changed to .css('display', 'block') solve the problem.
1208
+ See https://github.com/vitalets/x-editable/issues/37
1209
+
1210
+ In jquery 1.7.2+ everything works fine.
1211
+ */
945
1212
  //this.picker.find('>div').hide().filter('.datetimepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
946
- this.picker.find('>div').hide().filter('.datetimepicker-'+DPGlobal.modes[this.viewMode].clsName).css('display', 'block');
1213
+ this.picker.find('>div').hide().filter('.datetimepicker-' + DPGlobal.modes[this.viewMode].clsName).css('display', 'block');
947
1214
  this.updateNavArrows();
948
1215
  },
949
-
950
- reset: function(e) {
1216
+
1217
+ reset: function (e) {
951
1218
  this._setDate(null, 'date');
952
1219
  }
953
1220
  };
954
1221
 
955
- $.fn.fdatetimepicker = function ( option ) {
1222
+ $.fn.fdatetimepicker = function (option) {
956
1223
  var args = Array.apply(null, arguments);
957
1224
  args.shift();
958
1225
  return this.each(function () {
@@ -960,7 +1227,7 @@
960
1227
  data = $this.data('datetimepicker'),
961
1228
  options = typeof option == 'object' && option;
962
1229
  if (!data) {
963
- $this.data('datetimepicker', (data = new Datetimepicker(this, $.extend({}, $.fn.fdatetimepicker.defaults,options))));
1230
+ $this.data('datetimepicker', (data = new Datetimepicker(this, $.extend({}, $.fn.fdatetimepicker.defaults, options))));
964
1231
  }
965
1232
  if (typeof option == 'string' && typeof data[option] == 'function') {
966
1233
  data[option].apply(data, args);
@@ -973,80 +1240,110 @@
973
1240
  $.fn.fdatetimepicker.Constructor = Datetimepicker;
974
1241
  var dates = $.fn.fdatetimepicker.dates = {
975
1242
  en: {
976
- days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
977
- daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
978
- daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
979
- months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
1243
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
1244
+ daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
1245
+ daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
1246
+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
980
1247
  monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
981
- today: "Today"
1248
+ meridiem: ["am", "pm"],
1249
+ suffix: ["st", "nd", "rd", "th"],
1250
+ today: "Today"
982
1251
  }
983
1252
  };
984
1253
 
985
1254
  var DPGlobal = {
986
- modes: [
1255
+ modes: [
987
1256
  {
988
1257
  clsName: 'minutes',
989
- navFnc: 'Hours',
1258
+ navFnc: 'Hours',
990
1259
  navStep: 1
991
1260
  },
992
1261
  {
993
1262
  clsName: 'hours',
994
- navFnc: 'Date',
1263
+ navFnc: 'Date',
995
1264
  navStep: 1
996
1265
  },
997
1266
  {
998
1267
  clsName: 'days',
999
- navFnc: 'Month',
1268
+ navFnc: 'Month',
1000
1269
  navStep: 1
1001
1270
  },
1002
1271
  {
1003
1272
  clsName: 'months',
1004
- navFnc: 'FullYear',
1273
+ navFnc: 'FullYear',
1005
1274
  navStep: 1
1006
1275
  },
1007
1276
  {
1008
1277
  clsName: 'years',
1009
- navFnc: 'FullYear',
1278
+ navFnc: 'FullYear',
1010
1279
  navStep: 10
1011
- }],
1012
- isLeapYear: function (year) {
1280
+ }
1281
+ ],
1282
+ isLeapYear: function (year) {
1013
1283
  return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
1014
1284
  },
1015
- getDaysInMonth: function (year, month) {
1285
+ getDaysInMonth: function (year, month) {
1016
1286
  return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
1017
1287
  },
1018
- validParts: /hh?|ii?|ss?|dd?|mm?|MM?|yy(?:yy)?/g,
1019
- nonpunctuation: /[^ -\/:-@\[-`{-~\t\n\rTZ]+/g,
1020
- parseFormat: function(format){
1288
+ getDefaultFormat: function (type, field) {
1289
+ if (type == "standard") {
1290
+ if (field == 'input')
1291
+ return 'yyyy-mm-dd hh:ii';
1292
+ else
1293
+ return 'yyyy-mm-dd hh:ii:ss';
1294
+ } else if (type == "php") {
1295
+ if (field == 'input')
1296
+ return 'Y-m-d H:i';
1297
+ else
1298
+ return 'Y-m-d H:i:s';
1299
+ } else {
1300
+ throw new Error("Invalid format type.");
1301
+ }
1302
+ },
1303
+ validParts: function (type) {
1304
+ if (type == "standard") {
1305
+ return /hh?|HH?|p|P|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g;
1306
+ } else if (type == "php") {
1307
+ return /[dDjlNwzFmMnStyYaABgGhHis]/g;
1308
+ } else {
1309
+ throw new Error("Invalid format type.");
1310
+ }
1311
+ },
1312
+ nonpunctuation: /[^ -\/:-@\[-`{-~\t\n\rTZ]+/g,
1313
+ parseFormat: function (format, type) {
1021
1314
  // IE treats \0 as a string end in inputs (truncating the value),
1022
1315
  // so it's a bad format delimiter, anyway
1023
- var separators = format.replace(this.validParts, '\0').split('\0'),
1024
- parts = format.match(this.validParts);
1025
- if (!separators || !separators.length || !parts || parts.length == 0){
1316
+ var separators = format.replace(this.validParts(type), '\0').split('\0'),
1317
+ parts = format.match(this.validParts(type));
1318
+ if (!separators || !separators.length || !parts || parts.length == 0) {
1026
1319
  throw new Error("Invalid date format.");
1027
1320
  }
1028
1321
  return {separators: separators, parts: parts};
1029
1322
  },
1030
- parseDate: function(date, format, language) {
1031
- if (date instanceof Date) return new Date(date.valueOf() - date.getTimezoneOffset() * 60000);
1323
+ parseDate: function (date, format, language, type) {
1324
+ if (date instanceof Date) {
1325
+ var dateUTC = new Date(date.valueOf() - date.getTimezoneOffset() * 60000);
1326
+ dateUTC.setMilliseconds(0);
1327
+ return dateUTC;
1328
+ }
1032
1329
  if (/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(date)) {
1033
- format = this.parseFormat('yyyy-mm-dd');
1330
+ format = this.parseFormat('yyyy-mm-dd', type);
1034
1331
  }
1035
1332
  if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(date)) {
1036
- format = this.parseFormat('yyyy-mm-dd hh:ii');
1333
+ format = this.parseFormat('yyyy-mm-dd hh:ii', type);
1037
1334
  }
1038
1335
  if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(date)) {
1039
- format = this.parseFormat('yyyy-mm-dd hh:ii:ss');
1336
+ format = this.parseFormat('yyyy-mm-dd hh:ii:ss', type);
1040
1337
  }
1041
1338
  if (/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(date)) {
1042
1339
  var part_re = /([-+]\d+)([dmwy])/,
1043
1340
  parts = date.match(/([-+]\d+)([dmwy])/g),
1044
1341
  part, dir;
1045
1342
  date = new Date();
1046
- for (var i=0; i<parts.length; i++) {
1343
+ for (var i = 0; i < parts.length; i++) {
1047
1344
  part = part_re.exec(parts[i]);
1048
1345
  dir = parseInt(part[1]);
1049
- switch(part[2]){
1346
+ switch (part[2]) {
1050
1347
  case 'd':
1051
1348
  date.setUTCDate(date.getUTCDate() + dir);
1052
1349
  break;
@@ -1061,44 +1358,72 @@
1061
1358
  break;
1062
1359
  }
1063
1360
  }
1064
- return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
1361
+ return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), 0);
1065
1362
  }
1066
1363
  var parts = date && date.match(this.nonpunctuation) || [],
1067
- date = new Date(),
1364
+ date = new Date(0, 0, 0, 0, 0, 0, 0),
1068
1365
  parsed = {},
1069
- setters_order = ['hh', 'h', 'ii', 'i', 'ss', 's', 'yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
1366
+ setters_order = ['hh', 'h', 'ii', 'i', 'ss', 's', 'yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'D', 'DD', 'd', 'dd', 'H', 'HH', 'p', 'P'],
1070
1367
  setters_map = {
1071
- hh: function(d,v){ return d.setUTCHours(v); },
1072
- h: function(d,v){ return d.setUTCHours(v); },
1073
- ii: function(d,v){ return d.setUTCMinutes(v); },
1074
- i: function(d,v){ return d.setUTCMinutes(v); },
1075
- ss: function(d,v){ return d.setUTCSeconds(v); },
1076
- s: function(d,v){ return d.setUTCSeconds(v); },
1077
- yyyy: function(d,v){ return d.setUTCFullYear(v); },
1078
- yy: function(d,v){ return d.setUTCFullYear(2000+v); },
1079
- m: function(d,v){
1368
+ hh: function (d, v) {
1369
+ return d.setUTCHours(v);
1370
+ },
1371
+ h: function (d, v) {
1372
+ return d.setUTCHours(v);
1373
+ },
1374
+ HH: function (d, v) {
1375
+ return d.setUTCHours(v == 12 ? 0 : v);
1376
+ },
1377
+ H: function (d, v) {
1378
+ return d.setUTCHours(v == 12 ? 0 : v);
1379
+ },
1380
+ ii: function (d, v) {
1381
+ return d.setUTCMinutes(v);
1382
+ },
1383
+ i: function (d, v) {
1384
+ return d.setUTCMinutes(v);
1385
+ },
1386
+ ss: function (d, v) {
1387
+ return d.setUTCSeconds(v);
1388
+ },
1389
+ s: function (d, v) {
1390
+ return d.setUTCSeconds(v);
1391
+ },
1392
+ yyyy: function (d, v) {
1393
+ return d.setUTCFullYear(v);
1394
+ },
1395
+ yy: function (d, v) {
1396
+ return d.setUTCFullYear(2000 + v);
1397
+ },
1398
+ m: function (d, v) {
1080
1399
  v -= 1;
1081
- while (v<0) v += 12;
1400
+ while (v < 0) v += 12;
1082
1401
  v %= 12;
1083
1402
  d.setUTCMonth(v);
1084
1403
  while (d.getUTCMonth() != v)
1085
- d.setUTCDate(d.getUTCDate()-1);
1404
+ d.setUTCDate(d.getUTCDate() - 1);
1086
1405
  return d;
1087
1406
  },
1088
- d: function(d,v){ return d.setUTCDate(v); }
1407
+ d: function (d, v) {
1408
+ return d.setUTCDate(v);
1409
+ },
1410
+ p: function (d, v) {
1411
+ return d.setUTCHours(v == 1 ? d.getUTCHours() + 12 : d.getUTCHours());
1412
+ }
1089
1413
  },
1090
1414
  val, filtered, part;
1091
1415
  setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
1092
1416
  setters_map['dd'] = setters_map['d'];
1093
- date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);//date.getHours(), date.getMinutes(), date.getSeconds());
1417
+ setters_map['P'] = setters_map['p'];
1418
+ date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
1094
1419
  if (parts.length == format.parts.length) {
1095
- for (var i=0, cnt = format.parts.length; i < cnt; i++) {
1420
+ for (var i = 0, cnt = format.parts.length; i < cnt; i++) {
1096
1421
  val = parseInt(parts[i], 10);
1097
1422
  part = format.parts[i];
1098
1423
  if (isNaN(val)) {
1099
- switch(part) {
1424
+ switch (part) {
1100
1425
  case 'MM':
1101
- filtered = $(dates[language].months).filter(function(){
1426
+ filtered = $(dates[language].months).filter(function () {
1102
1427
  var m = this.slice(0, parts[i].length),
1103
1428
  p = parts[i].slice(0, m.length);
1104
1429
  return m == p;
@@ -1106,18 +1431,22 @@
1106
1431
  val = $.inArray(filtered[0], dates[language].months) + 1;
1107
1432
  break;
1108
1433
  case 'M':
1109
- filtered = $(dates[language].monthsShort).filter(function(){
1434
+ filtered = $(dates[language].monthsShort).filter(function () {
1110
1435
  var m = this.slice(0, parts[i].length),
1111
1436
  p = parts[i].slice(0, m.length);
1112
1437
  return m == p;
1113
1438
  });
1114
1439
  val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
1115
1440
  break;
1441
+ case 'p':
1442
+ case 'P':
1443
+ val = $.inArray(parts[i].toLowerCase(), dates[language].meridiem);
1444
+ break;
1116
1445
  }
1117
1446
  }
1118
1447
  parsed[part] = val;
1119
1448
  }
1120
- for (var i=0, s; i<setters_order.length; i++){
1449
+ for (var i = 0, s; i < setters_order.length; i++) {
1121
1450
  s = setters_order[i];
1122
1451
  if (s in parsed && !isNaN(parsed[s]))
1123
1452
  setters_map[s](date, parsed[s])
@@ -1125,36 +1454,97 @@
1125
1454
  }
1126
1455
  return date;
1127
1456
  },
1128
- formatDate: function(date, format, language){
1457
+ formatDate: function (date, format, language, type) {
1129
1458
  if (date == null) {
1130
1459
  return '';
1131
1460
  }
1132
- var val = {
1133
- h: date.getUTCHours(),
1134
- i: date.getUTCMinutes(),
1135
- s: date.getUTCSeconds(),
1136
- d: date.getUTCDate(),
1137
- m: date.getUTCMonth() + 1,
1138
- M: dates[language].monthsShort[date.getUTCMonth()],
1139
- MM: dates[language].months[date.getUTCMonth()],
1140
- yy: date.getUTCFullYear().toString().substring(2),
1141
- yyyy: date.getUTCFullYear()
1142
- };
1143
- val.hh = (val.h < 10 ? '0' : '') + val.h;
1144
- val.ii = (val.i < 10 ? '0' : '') + val.i;
1145
- val.ss = (val.s < 10 ? '0' : '') + val.s;
1146
- val.dd = (val.d < 10 ? '0' : '') + val.d;
1147
- val.mm = (val.m < 10 ? '0' : '') + val.m;
1461
+ var val;
1462
+ if (type == 'standard') {
1463
+ val = {
1464
+ // year
1465
+ yy: date.getUTCFullYear().toString().substring(2),
1466
+ yyyy: date.getUTCFullYear(),
1467
+ // month
1468
+ m: date.getUTCMonth() + 1,
1469
+ M: dates[language].monthsShort[date.getUTCMonth()],
1470
+ MM: dates[language].months[date.getUTCMonth()],
1471
+ // day
1472
+ d: date.getUTCDate(),
1473
+ D: dates[language].daysShort[date.getUTCDay()],
1474
+ DD: dates[language].days[date.getUTCDay()],
1475
+ p: (dates[language].meridiem.length == 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''),
1476
+ // hour
1477
+ h: date.getUTCHours(),
1478
+ // minute
1479
+ i: date.getUTCMinutes(),
1480
+ // second
1481
+ s: date.getUTCSeconds()
1482
+ };
1483
+
1484
+ if (dates[language].meridiem.length == 2) {
1485
+ val.H = (val.h % 12 == 0 ? 12 : val.h % 12);
1486
+ }
1487
+ else {
1488
+ val.H = val.h;
1489
+ }
1490
+ val.HH = (val.H < 10 ? '0' : '') + val.H;
1491
+ val.P = val.p.toUpperCase();
1492
+ val.hh = (val.h < 10 ? '0' : '') + val.h;
1493
+ val.ii = (val.i < 10 ? '0' : '') + val.i;
1494
+ val.ss = (val.s < 10 ? '0' : '') + val.s;
1495
+ val.dd = (val.d < 10 ? '0' : '') + val.d;
1496
+ val.mm = (val.m < 10 ? '0' : '') + val.m;
1497
+ } else if (type == 'php') {
1498
+ // php format
1499
+ val = {
1500
+ // year
1501
+ y: date.getUTCFullYear().toString().substring(2),
1502
+ Y: date.getUTCFullYear(),
1503
+ // month
1504
+ F: dates[language].months[date.getUTCMonth()],
1505
+ M: dates[language].monthsShort[date.getUTCMonth()],
1506
+ n: date.getUTCMonth() + 1,
1507
+ t: DPGlobal.getDaysInMonth(date.getUTCFullYear(), date.getUTCMonth()),
1508
+ // day
1509
+ j: date.getUTCDate(),
1510
+ l: dates[language].days[date.getUTCDay()],
1511
+ D: dates[language].daysShort[date.getUTCDay()],
1512
+ w: date.getUTCDay(), // 0 -> 6
1513
+ N: (date.getUTCDay() == 0 ? 7 : date.getUTCDay()), // 1 -> 7
1514
+ S: (date.getUTCDate() % 10 <= dates[language].suffix.length ? dates[language].suffix[date.getUTCDate() % 10 - 1] : ''),
1515
+ // hour
1516
+ a: (dates[language].meridiem.length == 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''),
1517
+ g: (date.getUTCHours() % 12 == 0 ? 12 : date.getUTCHours() % 12),
1518
+ G: date.getUTCHours(),
1519
+ // minute
1520
+ i: date.getUTCMinutes(),
1521
+ // second
1522
+ s: date.getUTCSeconds()
1523
+ };
1524
+ val.m = (val.n < 10 ? '0' : '') + val.n;
1525
+ val.d = (val.j < 10 ? '0' : '') + val.j;
1526
+ val.A = val.a.toString().toUpperCase();
1527
+ val.h = (val.g < 10 ? '0' : '') + val.g;
1528
+ val.H = (val.G < 10 ? '0' : '') + val.G;
1529
+ val.i = (val.i < 10 ? '0' : '') + val.i;
1530
+ val.s = (val.s < 10 ? '0' : '') + val.s;
1531
+ } else {
1532
+ throw new Error("Invalid format type.");
1533
+ }
1148
1534
  var date = [],
1149
1535
  seps = $.extend([], format.separators);
1150
- for (var i=0, cnt = format.parts.length; i < cnt; i++) {
1151
- if (seps.length)
1152
- date.push(seps.shift())
1536
+ for (var i = 0, cnt = format.parts.length; i < cnt; i++) {
1537
+ if (seps.length) {
1538
+ date.push(seps.shift());
1539
+ }
1153
1540
  date.push(val[format.parts[i]]);
1154
1541
  }
1542
+ if (seps.length) {
1543
+ date.push(seps.shift());
1544
+ }
1155
1545
  return date.join('');
1156
1546
  },
1157
- convertViewMode: function(viewMode){
1547
+ convertViewMode: function (viewMode) {
1158
1548
  switch (viewMode) {
1159
1549
  case 4:
1160
1550
  case 'decade':
@@ -1180,55 +1570,124 @@
1180
1570
 
1181
1571
  return viewMode;
1182
1572
  },
1183
- headTemplate: '<thead>'+
1184
- '<tr>'+
1185
- '<th class="prev"><i class="icon-chevron-left"/></th>'+
1186
- '<th colspan="5" class="switch"></th>'+
1187
- '<th class="next"><i class="icon-chevron-right"/></th>'+
1188
- '</tr>'+
1189
- '</thead>',
1190
- contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
1191
- footTemplate: '<tfoot><tr><th colspan="7" class="today"></th></tr></tfoot>'
1573
+ headTemplate: '<thead>' +
1574
+ '<tr>' +
1575
+ '<th class="prev"><i class="fi-arrow-left"/></th>' +
1576
+ '<th colspan="5" class="switch"></th>' +
1577
+ '<th class="next"><i class="fi-arrow-right"/></th>' +
1578
+ '</tr>' +
1579
+ '</thead>',
1580
+ headTemplateV3: '<thead>' +
1581
+ '<tr>' +
1582
+ '<th class="prev"><i class="icon-arrow-left"></i> </th>' +
1583
+ '<th colspan="5" class="switch"></th>' +
1584
+ '<th class="next"><i class="icon-arrow-right"></i> </th>' +
1585
+ '</tr>' +
1586
+ '</thead>',
1587
+ contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
1588
+ footTemplate: '<tfoot><tr><th colspan="7" class="today"></th></tr></tfoot>'
1192
1589
  };
1193
- DPGlobal.template = '<div class="datetimepicker">'+
1194
- '<div class="datetimepicker-minutes">'+
1195
- '<table class=" table-condensed">'+
1196
- DPGlobal.headTemplate+
1197
- DPGlobal.contTemplate+
1198
- DPGlobal.footTemplate+
1199
- '</table>'+
1200
- '</div>'+
1201
- '<div class="datetimepicker-hours">'+
1202
- '<table class=" table-condensed">'+
1203
- DPGlobal.headTemplate+
1204
- DPGlobal.contTemplate+
1205
- DPGlobal.footTemplate+
1206
- '</table>'+
1207
- '</div>'+
1208
- '<div class="datetimepicker-days">'+
1209
- '<table class=" table-condensed">'+
1210
- DPGlobal.headTemplate+
1211
- '<tbody></tbody>'+
1212
- DPGlobal.footTemplate+
1213
- '</table>'+
1214
- '</div>'+
1215
- '<div class="datetimepicker-months">'+
1216
- '<table class="table-condensed">'+
1217
- DPGlobal.headTemplate+
1218
- DPGlobal.contTemplate+
1219
- DPGlobal.footTemplate+
1220
- '</table>'+
1221
- '</div>'+
1222
- '<div class="datetimepicker-years">'+
1223
- '<table class="table-condensed">'+
1224
- DPGlobal.headTemplate+
1225
- DPGlobal.contTemplate+
1226
- DPGlobal.footTemplate+
1227
- '</table>'+
1228
- '</div>'+
1229
- '<a class="button datetimepicker-close small alert right" style="width:auto;"><i class="icon-remove"></i></a>'+
1230
- '</div>';
1231
-
1590
+ DPGlobal.template = '<div class="datetimepicker">' +
1591
+ '<div class="datetimepicker-minutes">' +
1592
+ '<table class=" table-condensed">' +
1593
+ DPGlobal.headTemplate +
1594
+ DPGlobal.contTemplate +
1595
+ DPGlobal.footTemplate +
1596
+ '</table>' +
1597
+ '</div>' +
1598
+ '<div class="datetimepicker-hours">' +
1599
+ '<table class=" table-condensed">' +
1600
+ DPGlobal.headTemplate +
1601
+ DPGlobal.contTemplate +
1602
+ DPGlobal.footTemplate +
1603
+ '</table>' +
1604
+ '</div>' +
1605
+ '<div class="datetimepicker-days">' +
1606
+ '<table class=" table-condensed">' +
1607
+ DPGlobal.headTemplate +
1608
+ '<tbody></tbody>' +
1609
+ DPGlobal.footTemplate +
1610
+ '</table>' +
1611
+ '</div>' +
1612
+ '<div class="datetimepicker-months">' +
1613
+ '<table class="table-condensed">' +
1614
+ DPGlobal.headTemplate +
1615
+ DPGlobal.contTemplate +
1616
+ DPGlobal.footTemplate +
1617
+ '</table>' +
1618
+ '</div>' +
1619
+ '<div class="datetimepicker-years">' +
1620
+ '<table class="table-condensed">' +
1621
+ DPGlobal.headTemplate +
1622
+ DPGlobal.contTemplate +
1623
+ DPGlobal.footTemplate +
1624
+ '</table>' +
1625
+ '</div>' +
1626
+ '</div>';
1627
+ DPGlobal.templateV3 = '<div class="datetimepicker">' +
1628
+ '<div class="datetimepicker-minutes">' +
1629
+ '<table class=" table-condensed">' +
1630
+ DPGlobal.headTemplateV3 +
1631
+ DPGlobal.contTemplate +
1632
+ DPGlobal.footTemplate +
1633
+ '</table>' +
1634
+ '</div>' +
1635
+ '<div class="datetimepicker-hours">' +
1636
+ '<table class=" table-condensed">' +
1637
+ DPGlobal.headTemplateV3 +
1638
+ DPGlobal.contTemplate +
1639
+ DPGlobal.footTemplate +
1640
+ '</table>' +
1641
+ '</div>' +
1642
+ '<div class="datetimepicker-days">' +
1643
+ '<table class=" table-condensed">' +
1644
+ DPGlobal.headTemplateV3 +
1645
+ '<tbody></tbody>' +
1646
+ DPGlobal.footTemplate +
1647
+ '</table>' +
1648
+ '</div>' +
1649
+ '<div class="datetimepicker-months">' +
1650
+ '<table class="table-condensed">' +
1651
+ DPGlobal.headTemplateV3 +
1652
+ DPGlobal.contTemplate +
1653
+ DPGlobal.footTemplate +
1654
+ '</table>' +
1655
+ '</div>' +
1656
+ '<div class="datetimepicker-years">' +
1657
+ '<table class="table-condensed">' +
1658
+ DPGlobal.headTemplateV3 +
1659
+ DPGlobal.contTemplate +
1660
+ DPGlobal.footTemplate +
1661
+ '</table>' +
1662
+ '</div>' +
1663
+ '</div>';
1232
1664
  $.fn.fdatetimepicker.DPGlobal = DPGlobal;
1233
1665
 
1234
- }( window.jQuery );
1666
+ /* DATETIMEPICKER NO CONFLICT
1667
+ * =================== */
1668
+
1669
+ $.fn.fdatetimepicker.noConflict = function () {
1670
+ $.fn.fdatetimepicker = old;
1671
+ return this;
1672
+ };
1673
+
1674
+ /* DATETIMEPICKER DATA-API
1675
+ * ================== */
1676
+
1677
+ $(document).on(
1678
+ 'focus.datetimepicker.data-api click.datetimepicker.data-api',
1679
+ '[data-provide="datetimepicker"]',
1680
+ function (e) {
1681
+ var $this = $(this);
1682
+ if ($this.data('datetimepicker')) return;
1683
+ e.preventDefault();
1684
+ // component click requires us to explicitly show it
1685
+ $this.fdatetimepicker('show');
1686
+ }
1687
+ );
1688
+ $(function () {
1689
+ $('[data-provide="datetimepicker-inline"]').fdatetimepicker();
1690
+ });
1691
+
1692
+ }(window.jQuery);
1693
+