foundation-datetimepicker-rails 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+