bootstrap3-datetimepicker-rails 2.1.30 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -13,8 +13,8 @@ actively maintained and works with [Bootstrap3](http://getbootstrap.com).
13
13
 
14
14
  Add these lines to your application's Gemfile:
15
15
  ```
16
- gem 'momentjs-rails', '~> '2.5.0'
17
- gem 'bootstrap3-datetimepicker-rails', '~> 2.1.30'
16
+ gem 'momentjs-rails', '~> 2.5.0'
17
+ gem 'bootstrap3-datetimepicker-rails', '~> 3.0.0'
18
18
  ```
19
19
 
20
20
  And then execute:
@@ -39,7 +39,7 @@ Add the following to your Javascript manifest file (`application.js`):
39
39
  If you want to include a localization, also add:
40
40
  ```js
41
41
  //= require moment/<locale>
42
- //= require locales/bootstrap-datetimepicker.<locale>
42
+ //= require locales/bootstrap-datetimepicker.<locale>.js
43
43
  ```
44
44
 
45
45
  Add the following to your stylesheet file:
@@ -1,5 +1,5 @@
1
1
  module Bootstrap3Datetimepicker
2
2
  module Rails
3
- VERSION = '2.1.30'
3
+ VERSION = '3.0.0'
4
4
  end
5
5
  end
@@ -1,41 +1,42 @@
1
- /**
2
- * version 2.1.30
3
- * @license
4
- * =========================================================
5
- * bootstrap-datetimepicker.js
6
- * http://www.eyecon.ro/bootstrap-datepicker
7
- * =========================================================
8
- * Copyright 2012 Stefan Petre
9
- *
10
- * Contributions:
11
- * - updated for Bootstrap v3 by Jonathan Peterson (@Eonasdan) and (almost)
12
- * completely rewritten to use Momentjs
13
- * - based on tarruda's bootstrap-datepicker
14
- *
15
- * Licensed under the Apache License, Version 2.0 (the "License");
16
- * you may not use this file except in compliance with the License.
17
- * You may obtain a copy of the License at
18
- *
19
- * http://www.apache.org/licenses/LICENSE-2.0
20
- *
21
- * Unless required by applicable law or agreed to in writing, software
22
- * distributed under the License is distributed on an "AS IS" BASIS,
23
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
- * See the License for the specific language governing permissions and
25
- * limitations under the License.
26
- * =========================================================
27
- */
1
+ /*
2
+ Version 3.0.0
3
+ =========================================================
4
+ bootstrap-datetimepicker.js
5
+ https://github.com/Eonasdan/bootstrap-datetimepicker
6
+ =========================================================
7
+ The MIT License (MIT)
8
+
9
+ Copyright (c) 2014 Jonathan Peterson
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in
19
+ all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
+ THE SOFTWARE.
28
+ */
28
29
  ; (function (factory) {
29
30
  if (typeof define === 'function' && define.amd) {
30
- // AMD is used - Register as an anonymous module.
31
+ // AMD is used - Register as an anonymous module.
31
32
  define(['jquery', 'moment'], factory);
32
33
  } else {
33
34
  // AMD is not used - Attempt to fetch dependencies from scope.
34
- if(!jQuery){
35
+ if (!jQuery) {
35
36
  throw 'bootstrap-datetimepicker requires jQuery to be loaded first';
36
- }else if(!moment) {
37
+ } else if (!moment) {
37
38
  throw 'bootstrap-datetimepicker requires moment.js to be loaded first';
38
- }else{
39
+ } else {
39
40
  factory(jQuery, moment);
40
41
  }
41
42
  }
@@ -58,17 +59,21 @@
58
59
  pickTime: true,
59
60
  useMinutes: true,
60
61
  useSeconds: false,
62
+ useCurrent: true,
61
63
  minuteStepping: 1,
62
- startDate: new pMoment({ y: 1970 }),
63
- endDate: new pMoment().add(50, "y"),
64
+ minDate: new pMoment({ y: 1900 }),
65
+ maxDate: new pMoment().add(100, "y"),
66
+ showToday: true,
64
67
  collapse: true,
65
- language: pMoment.lang(),
68
+ language: "en",
66
69
  defaultDate: "",
67
- disabledDates: [],
70
+ disabledDates: false,
68
71
  enabledDates: false,
69
72
  icons: {},
70
73
  useStrict: false,
71
- direction: "auto"
74
+ direction: "auto",
75
+ sideBySide: false,
76
+ daysOfWeekDisabled: false
72
77
  },
73
78
 
74
79
  icons = {
@@ -101,7 +106,7 @@
101
106
  picker.component = false;
102
107
 
103
108
  if (picker.element.hasClass('input-group')) {
104
- if (picker.element.find('.datepickerbutton').size() == 0) {//in case there is more then one 'input-group-addon` #48
109
+ if (picker.element.find('.datepickerbutton').size() == 0) {//in case there is more then one 'input-group-addon' Issue #48
105
110
  picker.component = picker.element.find("[class^='input-group-']");
106
111
  }
107
112
  else {
@@ -113,24 +118,19 @@
113
118
  longDateFormat = pMoment()._lang._longDateFormat;
114
119
 
115
120
  if (!picker.format) {
116
- if (picker.isInput) picker.format = picker.element.data('format');
117
- else picker.format = picker.element.find('input').data('format');
118
- if (!picker.format) {
119
- picker.format = (picker.options.pickDate ? longDateFormat.L : '');
120
- if (picker.options.pickDate && picker.options.pickTime) picker.format += ' ';
121
- picker.format += (picker.options.pickTime ? longDateFormat.LT : '');
122
- if (picker.options.useSeconds) {
123
- if (~longDateFormat.LT.indexOf(' A')) {
124
- picker.format = picker.format.split(" A")[0] + ":ss A";
125
- }
126
- else {
127
- picker.format += ':ss';
128
- }
121
+ picker.format = (picker.options.pickDate ? longDateFormat.L : '');
122
+ if (picker.options.pickDate && picker.options.pickTime) picker.format += ' ';
123
+ picker.format += (picker.options.pickTime ? longDateFormat.LT : '');
124
+ if (picker.options.useSeconds) {
125
+ if (~longDateFormat.LT.indexOf(' A')) {
126
+ picker.format = picker.format.split(" A")[0] + ":ss A";
127
+ }
128
+ else {
129
+ picker.format += ':ss';
129
130
  }
130
131
  }
131
132
  }
132
-
133
- picker.options.use24hours = picker.format.toLowerCase().indexOf("a") < 1;
133
+ picker.use24hours = picker.format.toLowerCase().indexOf("a") < 1;
134
134
 
135
135
  if (picker.component) icon = picker.component.find('span');
136
136
 
@@ -144,8 +144,13 @@
144
144
  }
145
145
  }
146
146
 
147
- picker.widget = $(getTemplate(picker.options.pickDate, picker.options.pickTime, picker.options.collapse)).appendTo('body');
148
- picker.minViewMode = picker.options.minViewMode || picker.element.data('date-minviewmode') || 0;
147
+ picker.widget = $(getTemplate()).appendTo('body');
148
+
149
+ if (picker.options.useSeconds && !picker.use24hours) {
150
+ picker.widget.width(300);
151
+ }
152
+
153
+ picker.minViewMode = picker.options.minViewMode || 0;
149
154
  if (typeof picker.minViewMode === 'string') {
150
155
  switch (picker.minViewMode) {
151
156
  case 'months':
@@ -159,7 +164,7 @@
159
164
  break;
160
165
  }
161
166
  }
162
- picker.viewMode = picker.options.viewMode || picker.element.data('date-viewmode') || 0;
167
+ picker.viewMode = picker.options.viewMode || 0;
163
168
  if (typeof picker.viewMode === 'string') {
164
169
  switch (picker.viewMode) {
165
170
  case 'months':
@@ -174,51 +179,64 @@
174
179
  }
175
180
  }
176
181
 
177
- for (i = 0; i < picker.options.disabledDates.length; i++) {
178
- dDate = picker.options.disabledDates[i];
179
- dDate = pMoment(dDate);
180
- //if this is not a valid date then set it to the startdate -1 day so it's disabled.
181
- if (!dDate.isValid()) dDate = pMoment(picker.options.startDate).subtract(1, "day");
182
- picker.options.disabledDates[i] = dDate.format("L");
183
- }
182
+ picker.options.disabledDates = indexGivenDates(picker.options.disabledDates);
183
+ picker.options.enabledDates = indexGivenDates(picker.options.enabledDates);
184
184
 
185
- for (i = 0; i < picker.options.enabledDates.length; i++) {
186
- dDate = picker.options.enabledDates[i];
187
- dDate = pMoment(dDate);
188
- //if this is not a valid date then set it to the startdate -1 day so it's disabled.
189
- if (!dDate.isValid()) dDate = pMoment(picker.options.startDate).subtract(1, "day");
190
- picker.options.enabledDates[i] = dDate.format("L");
191
- }
192
185
  picker.startViewMode = picker.viewMode;
193
- picker.setStartDate(picker.options.startDate || picker.element.data('date-startdate'));
194
- picker.setEndDate(picker.options.endDate || picker.element.data('date-enddate'));
186
+ picker.setMinDate(picker.options.minDate);
187
+ picker.setMaxDate(picker.options.maxDate);
195
188
  fillDow();
196
189
  fillMonths();
197
190
  fillHours();
198
191
  fillMinutes();
199
- fillSeconds();
192
+ fillSeconds();
200
193
  update();
201
194
  showMode();
202
195
  attachDatePickerEvents();
203
- if (picker.options.defaultDate !== "") picker.setValue(picker.options.defaultDate);
196
+ if (picker.options.defaultDate !== "" && getPickerInput().val() == "") picker.setValue(picker.options.defaultDate);
197
+ if (picker.options.minuteStepping !== 1) {
198
+ var rMinutes = picker.date.minutes();
199
+ var rInterval = picker.options.minuteStepping;
200
+ picker.date.minutes((Math.round(rMinutes / rInterval) * rInterval) % 60)
201
+ .seconds(0);
202
+ }
203
+ },
204
+
205
+ getPickerInput = function () {
206
+ if (picker.isInput) {
207
+ return picker.element;
208
+ } else {
209
+ return dateStr = picker.element.find('input');
210
+ }
204
211
  },
205
212
 
206
213
  dataToOptions = function () {
207
- var eData = picker.element.data();
208
- if (eData.pickdate !== undefined) picker.options.pickDate = eData.pickdate;
209
- if (eData.picktime !== undefined) picker.options.pickTime = eData.picktime;
210
- if (eData.useminutes !== undefined) picker.options.useMinutes = eData.useminutes;
211
- if (eData.useseconds !== undefined) picker.options.useSeconds = eData.useseconds;
212
- if (eData.minutestepping !== undefined) picker.options.minuteStepping = eData.minutestepping;
213
- if (eData.startdate !== undefined) picker.options.startDate = eData.startdate;
214
- if (eData.enddate !== undefined) picker.options.endDate = eData.enddate;
215
- if (eData.collapse !== undefined) picker.options.collapse = eData.collapse;
216
- if (eData.language !== undefined) picker.options.language = eData.language;
217
- if (eData.defaultdate !== undefined) picker.options.defaultDate = eData.defaultdate;
218
- if (eData.disableddates !== undefined) picker.options.disabledDates = eData.disableddates;
219
- if (eData.enableddates !== undefined) picker.options.enabledDates = eData.enableddates;
220
- if (eData.icons !== undefined) picker.options.icons = eData.icons;
221
- if (eData.usestrict !== undefined) picker.options.useStrict = eData.usestrict;
214
+ var eData
215
+ if (picker.element.is('input')) {
216
+ eData = picker.element.data();
217
+ }
218
+ else {
219
+ eData = picker.element.data();
220
+ }
221
+ if (eData.dateFormat !== undefined) picker.options.format = eData.dateFormat;
222
+ if (eData.datePickdate !== undefined) picker.options.pickDate = eData.datePickdate;
223
+ if (eData.datePicktime !== undefined) picker.options.pickTime = eData.datePicktime;
224
+ if (eData.dateUseminutes !== undefined) picker.options.useMinutes = eData.dateUseminutes;
225
+ if (eData.dateUseseconds !== undefined) picker.options.useSeconds = eData.dateUseseconds;
226
+ if (eData.dateUsecurrent !== undefined) picker.options.useCurrent = eData.dateUsecurrent;
227
+ if (eData.dateMinutestepping !== undefined) picker.options.minuteStepping = eData.dateMinutestepping;
228
+ if (eData.dateMindate !== undefined) picker.options.minDate = eData.dateMindate;
229
+ if (eData.dateMaxdate !== undefined) picker.options.maxDate = eData.dateMaxdate;
230
+ if (eData.dateShowtoday !== undefined) picker.options.showToday = eData.dateShowtoday;
231
+ if (eData.dateCollapse !== undefined) picker.options.collapse = eData.dateCollapse;
232
+ if (eData.dateLanguage !== undefined) picker.options.language = eData.dateLanguage;
233
+ if (eData.dateDefaultdate !== undefined) picker.options.defaultDate = eData.dateDefaultdate;
234
+ if (eData.dateDisableddates !== undefined) picker.options.disabledDates = eData.dateDisableddates;
235
+ if (eData.dateEnableddates !== undefined) picker.options.enabledDates = eData.dateEnableddates;
236
+ if (eData.dateIcons !== undefined) picker.options.icons = eData.dateIcons;
237
+ if (eData.dateUsestrict !== undefined) picker.options.useStrict = eData.dateUsestrict;
238
+ if (eData.dateDirection !== undefined) picker.options.direction = eData.dateDirection;
239
+ if (eData.dateSidebyside !== undefined) picker.options.sideBySide = eData.dateSidebyside;
222
240
  },
223
241
 
224
242
  place = function () {
@@ -226,14 +244,26 @@
226
244
  offset = picker.component ? picker.component.offset() : picker.element.offset(), $window = $(window);
227
245
  picker.width = picker.component ? picker.component.outerWidth() : picker.element.outerWidth();
228
246
  offset.top = offset.top + picker.element.outerHeight();
229
-
230
- // if (picker.options.direction === 'up' || picker.options.direction === 'auto' && offset.top + picker.widget.height() > $window.height()) {
231
- // offset.top -= picker.widget.height() + picker.element.outerHeight();
232
- // picker.widget.addClass('up');
233
- // } else if (picker.options.direction === 'down' || picker.options.direction === 'auto' && offset.top + picker.widget.height() <= $window.height()) {
234
- // offset.top += picker.element.outerHeight();
235
- // picker.widget.addClass('down');
236
- // }
247
+
248
+ var placePosition;
249
+ if (picker.options.direction === 'up') {
250
+ placePosition = 'top'
251
+ } else if (picker.options.direction === 'bottom') {
252
+ placePosition = 'bottom'
253
+ } else if (picker.options.direction === 'auto') {
254
+ if (offset.top + picker.widget.height() > $window.height() + $window.scrollTop() && picker.widget.height() + picker.element.outerHeight() < offset.top) {
255
+ placePosition = 'top';
256
+ } else {
257
+ placePosition = 'bottom';
258
+ }
259
+ };
260
+ if (placePosition === 'top') {
261
+ offset.top -= picker.widget.height() + picker.element.outerHeight() + 15;
262
+ picker.widget.addClass('top').removeClass('bottom');
263
+ } else {
264
+ offset.top += 1;
265
+ picker.widget.addClass('bottom').removeClass('top');
266
+ }
237
267
 
238
268
  if (picker.options.width !== undefined) {
239
269
  picker.widget.width(picker.options.width);
@@ -268,8 +298,9 @@
268
298
  },
269
299
 
270
300
  notifyChange = function (oldDate, eventType) {
301
+ if (pMoment(picker.date).isSame(pMoment(oldDate))) return;
271
302
  picker.element.trigger({
272
- type: 'change.dp',
303
+ type: 'dp.change',
273
304
  date: pMoment(picker.date),
274
305
  oldDate: pMoment(oldDate)
275
306
  });
@@ -280,7 +311,7 @@
280
311
 
281
312
  notifyError = function (date) {
282
313
  picker.element.trigger({
283
- type: 'error.dp',
314
+ type: 'dp.error',
284
315
  date: pMoment(date)
285
316
  });
286
317
  },
@@ -289,11 +320,7 @@
289
320
  pMoment.lang(picker.options.language);
290
321
  var dateStr = newDate;
291
322
  if (!dateStr) {
292
- if (picker.isInput) {
293
- dateStr = picker.element.val();
294
- } else {
295
- dateStr = picker.element.find('input').val();
296
- }
323
+ dateStr = getPickerInput().val()
297
324
  if (dateStr) picker.date = pMoment(dateStr, picker.format, picker.options.useStrict);
298
325
  if (!picker.date) picker.date = pMoment();
299
326
  }
@@ -306,7 +333,7 @@
306
333
  pMoment.lang(picker.options.language);
307
334
  var html = $('<tr>'), weekdaysMin = pMoment.weekdaysMin(), i;
308
335
  if (pMoment()._lang._week.dow == 0) { // starts on Sunday
309
- for(i = 0; i < 7; i++) {
336
+ for (i = 0; i < 7; i++) {
310
337
  html.append('<th class="dow">' + weekdaysMin[i] + '</th>');
311
338
  }
312
339
  } else {
@@ -334,10 +361,10 @@
334
361
  pMoment.lang(picker.options.language);
335
362
  var year = picker.viewDate.year(),
336
363
  month = picker.viewDate.month(),
337
- startYear = picker.options.startDate.year(),
338
- startMonth = picker.options.startDate.month(),
339
- endYear = picker.options.endDate.year(),
340
- endMonth = picker.options.endDate.month(),
364
+ startYear = picker.options.minDate.year(),
365
+ startMonth = picker.options.minDate.month(),
366
+ endYear = picker.options.maxDate.year(),
367
+ endMonth = picker.options.maxDate.month(),
341
368
  prevMonth, nextMonth, html = [], row, clsName, i, days, yearCont, currentYear, months = pMoment.months();
342
369
 
343
370
  picker.widget.find('.datepicker-days').find('.disabled').removeClass('disabled');
@@ -375,14 +402,27 @@
375
402
  if (isInDisableDates(prevMonth) || !isInEnableDates(prevMonth)) {
376
403
  clsName += ' disabled';
377
404
  }
405
+ if (picker.options.showToday === true) {
406
+ if (prevMonth.isSame(pMoment(), 'day')) {
407
+ clsName += ' today';
408
+ }
409
+ }
410
+ if (picker.options.daysOfWeekDisabled) {
411
+ for (i in picker.options.daysOfWeekDisabled) {
412
+ if (prevMonth.day() == picker.options.daysOfWeekDisabled[i]) {
413
+ clsName += ' disabled';
414
+ break;
415
+ }
416
+ }
417
+ }
378
418
  row.append('<td class="day' + clsName + '">' + prevMonth.date() + '</td>');
379
419
  prevMonth.add(1, "d");
380
420
  }
381
421
  picker.widget.find('.datepicker-days tbody').empty().append(html);
382
- currentYear = pMoment().year(), months = picker.widget.find('.datepicker-months')
422
+ currentYear = picker.date.year(), months = picker.widget.find('.datepicker-months')
383
423
  .find('th:eq(1)').text(year).end().find('span').removeClass('active');
384
424
  if (currentYear === year) {
385
- months.eq(pMoment().month()).addClass('active');
425
+ months.eq(picker.date.month()).addClass('active');
386
426
  }
387
427
  if (currentYear - 1 < startYear) {
388
428
  picker.widget.find('.datepicker-months th:eq(0)').addClass('disabled');
@@ -421,7 +461,7 @@
421
461
  pMoment.lang(picker.options.language);
422
462
  var table = picker.widget.find('.timepicker .timepicker-hours table'), html = '', current, i, j;
423
463
  table.parent().hide();
424
- if (picker.options.use24hours) {
464
+ if (picker.use24hours) {
425
465
  current = 0;
426
466
  for (i = 0; i < 6; i += 1) {
427
467
  html += '<tr>';
@@ -447,13 +487,18 @@
447
487
  },
448
488
 
449
489
  fillMinutes = function () {
450
- var table = picker.widget.find('.timepicker .timepicker-minutes table'), html = '', current = 0, i, j;
490
+ var table = picker.widget.find('.timepicker .timepicker-minutes table'), html = '', current = 0, i, j, step = picker.options.minuteStepping;
451
491
  table.parent().hide();
452
- for (i = 0; i < 5; i++) {
492
+ if (step = 1) step = 5;
493
+ for (i = 0; i < Math.ceil(60 / step / 4) ; i++) {
453
494
  html += '<tr>';
454
495
  for (j = 0; j < 4; j += 1) {
455
- html += '<td class="minute">' + padLeft(current.toString()) + '</td>';
456
- current += 3;
496
+ if (current < 60) {
497
+ html += '<td class="minute">' + padLeft(current.toString()) + '</td>';
498
+ current += step;
499
+ } else {
500
+ html += '<td></td>';
501
+ }
457
502
  }
458
503
  html += '</tr>';
459
504
  }
@@ -463,11 +508,11 @@
463
508
  fillSeconds = function () {
464
509
  var table = picker.widget.find('.timepicker .timepicker-seconds table'), html = '', current = 0, i, j;
465
510
  table.parent().hide();
466
- for (i = 0; i < 5; i++) {
511
+ for (i = 0; i < 3; i++) {
467
512
  html += '<tr>';
468
513
  for (j = 0; j < 4; j += 1) {
469
- html += '<td class="second">' + padLeft(current.toString()) + '</td>';
470
- current += 3;
514
+ html += '<td class="second">' + padLeft(current.toString()) + '</td>';
515
+ current += 5;
471
516
  }
472
517
  html += '</tr>';
473
518
  }
@@ -479,7 +524,7 @@
479
524
  var timeComponents = picker.widget.find('.timepicker span[data-time-component]'),
480
525
  hour = picker.date.hours(),
481
526
  period = 'AM';
482
- if (!picker.options.use24hours) {
527
+ if (!picker.use24hours) {
483
528
  if (hour >= 12) period = 'PM';
484
529
  if (hour === 0) hour = 12;
485
530
  else if (hour != 12) hour = hour % 12;
@@ -520,15 +565,17 @@
520
565
  year = parseInt(target.text(), 10) || 0;
521
566
  picker.viewDate.year(year);
522
567
  }
523
- if (picker.viewMode !== 0) {
568
+ if (picker.viewMode === picker.minViewMode) {
524
569
  picker.date = pMoment({
525
570
  y: picker.viewDate.year(),
526
571
  M: picker.viewDate.month(),
527
572
  d: picker.viewDate.date(),
528
573
  h: picker.date.hours(),
529
- m: picker.date.minutes()
574
+ m: picker.date.minutes(),
575
+ s: picker.date.seconds()
530
576
  });
531
577
  notifyChange(oldDate, e.type);
578
+ set();
532
579
  }
533
580
  showMode(-1);
534
581
  fillDate();
@@ -558,7 +605,8 @@
558
605
  M: month,
559
606
  d: day,
560
607
  h: picker.date.hours(),
561
- m: picker.date.minutes()
608
+ m: picker.date.minutes(),
609
+ s: picker.date.seconds()
562
610
  }
563
611
  );
564
612
  picker.viewDate = pMoment({
@@ -627,7 +675,9 @@
627
675
  },
628
676
 
629
677
  selectHour: function (e) {
630
- picker.date.hours(parseInt($(e.target).text(), 10));
678
+ var period = picker.widget.find('.timepicker [data-action=togglePeriod]').text(), hour = parseInt($(e.target).text(), 10);
679
+ if (period == "PM") hour += 12
680
+ picker.date.hours(hour);
631
681
  actions.showPicker.call(picker);
632
682
  },
633
683
 
@@ -668,8 +718,6 @@
668
718
  }
669
719
  else {
670
720
  picker.viewDate = oldDate;
671
- input.val(pMoment(oldDate).format(picker.format));
672
- //picker.setValue(""); // unset the date when the input is erased
673
721
  notifyChange(oldDate, e.type);
674
722
  notifyError(newDate);
675
723
  picker.unset = true;
@@ -680,7 +728,7 @@
680
728
  if (dir) {
681
729
  picker.viewMode = Math.max(picker.minViewMode, Math.min(2, picker.viewMode + dir));
682
730
  }
683
-
731
+ var f = dpGlobal.modes[picker.viewMode].clsName;
684
732
  picker.widget.find('.datepicker > div').hide().filter('.datepicker-' + dpGlobal.modes[picker.viewMode].clsName).show();
685
733
  },
686
734
 
@@ -699,7 +747,7 @@
699
747
 
700
748
  if (expanded && expanded.length) {
701
749
  collapseData = expanded.data('collapse');
702
- if (collapseData && collapseData.transitioning) return;
750
+ if (collapseData && collapseData.date - transitioning) return;
703
751
  expanded.collapse('hide');
704
752
  closed.collapse('show');
705
753
  $this.find('span').toggleClass(picker.options.icons.time + ' ' + picker.options.icons.date);
@@ -785,15 +833,8 @@
785
833
  pMoment.lang(picker.options.language);
786
834
  var formatted = '', input;
787
835
  if (!picker.unset) formatted = pMoment(picker.date).format(picker.format);
788
- if (!picker.isInput) {
789
- if (picker.component) {
790
- input = picker.element.find('input');
791
- input.val(formatted);
792
- }
793
- picker.element.data('date', formatted);
794
- } else {
795
- picker.element.val(formatted);
796
- }
836
+ getPickerInput().val(formatted);
837
+ picker.element.data('date', formatted);
797
838
  if (!picker.options.pickTime) picker.hide();
798
839
  },
799
840
 
@@ -819,56 +860,73 @@
819
860
  else {
820
861
  picker.date.subtract(amount, unit);
821
862
  }
822
- picker.unset = false;
823
- },
824
-
825
- isInDisableDates = function (date) {
826
- pMoment.lang(picker.options.language);
827
- if (date.isAfter(picker.options.endDate) || date.isBefore(picker.options.startDate)) return true;
828
- var disabled = picker.options.disabledDates, i;
829
- for (i in disabled) {
830
- if (disabled[i] == pMoment(date).format("L")) {
831
- return true;
832
- }
833
- }
834
- return false;
863
+ picker.unset = false;
835
864
  },
836
865
 
866
+ isInDisableDates = function (date) {
867
+ pMoment.lang(picker.options.language);
868
+ if (date.isAfter(picker.options.maxDate) || date.isBefore(picker.options.minDate)) return true;
869
+ if (picker.options.disabledDates === false) {
870
+ return false;
871
+ }
872
+ return picker.options.disabledDates[pMoment(date).format("YYYY-MM-DD")] === true;
873
+ },
837
874
  isInEnableDates = function (date) {
838
875
  pMoment.lang(picker.options.language);
839
- var enabled = picker.options.enabledDates, i;
840
- if (enabled.length) {
841
- for (i in enabled) {
842
- if (enabled[i] == pMoment(date).format("L")) {
843
- return true;
844
- }
876
+ if (picker.options.enabledDates === false) {
877
+ return true;
878
+ }
879
+ return picker.options.enabledDates[pMoment(date).format("YYYY-MM-DD")] === true;
880
+ },
881
+
882
+ indexGivenDates = function (givenDatesArray) {
883
+ // Store given enabledDates and disabledDates as keys.
884
+ // This way we can check their existence in O(1) time instead of looping through whole array.
885
+ // (for example: picker.options.enabledDates['2014-02-27'] === true)
886
+ var givenDatesIndexed = {};
887
+ var givenDatesCount = 0;
888
+ for (i = 0; i < givenDatesArray.length; i++) {
889
+ dDate = pMoment(givenDatesArray[i]);
890
+ if (dDate.isValid()) {
891
+ givenDatesIndexed[dDate.format("YYYY-MM-DD")] = true;
892
+ givenDatesCount++;
845
893
  }
846
- return false;
847
894
  }
848
- return enabled === false ? true : false;
895
+ if (givenDatesCount > 0) {
896
+ return givenDatesIndexed;
897
+ }
898
+ return false;
849
899
  },
900
+
850
901
  padLeft = function (string) {
851
902
  string = string.toString();
852
903
  if (string.length >= 2) return string;
853
904
  else return '0' + string;
854
905
  },
855
906
 
856
- getTemplate = function (pickDate, pickTime, collapse) {
857
- if (pickDate && pickTime) {
858
- return (
859
- '<div class="bootstrap-datetimepicker-widget dropdown-menu" style="z-index:9999 !important;">' +
860
- '<ul class="list-unstyled">' +
861
- '<li' + (collapse ? ' class="collapse in"' : '') + '>' +
862
- '<div class="datepicker">' + dpGlobal.template + '</div>' +
863
- '</li>' +
864
- '<li class="picker-switch accordion-toggle"><a class="btn" style="width:100%"><span class="' + picker.options.icons.time + '"></span></a></li>' +
865
- '<li' + (collapse ? ' class="collapse"' : '') + '>' +
866
- '<div class="timepicker">' + tpGlobal.getTemplate() + '</div>' +
867
- '</li>' +
868
- '</ul>' +
869
- '</div>'
870
- );
871
- } else if (pickTime) {
907
+ getTemplate = function () {
908
+ if (picker.options.pickDate && picker.options.pickTime) {
909
+ var ret = '';
910
+ ret = '<div class="bootstrap-datetimepicker-widget' + (picker.options.sideBySide ? ' timepicker-sbs' : '') + ' dropdown-menu" style="z-index:9999 !important;">';
911
+ if (picker.options.sideBySide) {
912
+ ret += '<div class="row">' +
913
+ '<div class="col-sm-6 datepicker">' + dpGlobal.template + '</div>' +
914
+ '<div class="col-sm-6 timepicker">' + tpGlobal.getTemplate() + '</div>' +
915
+ '</div>';
916
+ } else {
917
+ ret += '<ul class="list-unstyled">' +
918
+ '<li' + (picker.options.collapse ? ' class="collapse in"' : '') + '>' +
919
+ '<div class="datepicker">' + dpGlobal.template + '</div>' +
920
+ '</li>' +
921
+ '<li class="picker-switch accordion-toggle"><a class="btn" style="width:100%"><span class="' + picker.options.icons.time + '"></span></a></li>' +
922
+ '<li' + (picker.options.collapse ? ' class="collapse"' : '') + '>' +
923
+ '<div class="timepicker">' + tpGlobal.getTemplate() + '</div>' +
924
+ '</li>' +
925
+ '</ul>';
926
+ }
927
+ ret += '</div>';
928
+ return ret;
929
+ } else if (picker.options.pickTime) {
872
930
  return (
873
931
  '<div class="bootstrap-datetimepicker-widget dropdown-menu">' +
874
932
  '<div class="timepicker">' + tpGlobal.getTemplate() + '</div>' +
@@ -911,9 +969,9 @@
911
969
  },
912
970
 
913
971
  tpGlobal = {
914
- hourTemplate: '<span data-action="showHours" data-time-component="hours" class="timepicker-hour"></span>',
972
+ hourTemplate: '<span data-action="showHours" data-time-component="hours" class="timepicker-hour"></span>',
915
973
  minuteTemplate: '<span data-action="showMinutes" data-time-component="minutes" class="timepicker-minute"></span>',
916
- secondTemplate: '<span data-action="showSeconds" data-time-component="seconds" class="timepicker-second"></span>'
974
+ secondTemplate: '<span data-action="showSeconds" data-time-component="seconds" class="timepicker-second"></span>'
917
975
  };
918
976
 
919
977
  dpGlobal.template =
@@ -937,7 +995,7 @@
937
995
  '<td>' + (picker.options.useMinutes ? '<a href="#" class="btn" data-action="incrementMinutes"><span class="' + picker.options.icons.up + '"></span></a>' : '') + '</td>' +
938
996
  (picker.options.useSeconds ?
939
997
  '<td class="separator"></td><td><a href="#" class="btn" data-action="incrementSeconds"><span class="' + picker.options.icons.up + '"></span></a></td>' : '') +
940
- (picker.options.use24hours ? '' : '<td class="separator"></td>') +
998
+ (picker.use24hours ? '' : '<td class="separator"></td>') +
941
999
  '</tr>' +
942
1000
  '<tr>' +
943
1001
  '<td>' + tpGlobal.hourTemplate + '</td> ' +
@@ -945,7 +1003,7 @@
945
1003
  '<td>' + (picker.options.useMinutes ? tpGlobal.minuteTemplate : '<span class="timepicker-minute">00</span>') + '</td> ' +
946
1004
  (picker.options.useSeconds ?
947
1005
  '<td class="separator">:</td><td>' + tpGlobal.secondTemplate + '</td>' : '') +
948
- (picker.options.use24hours ? '' : '<td class="separator"></td>' +
1006
+ (picker.use24hours ? '' : '<td class="separator"></td>' +
949
1007
  '<td><button type="button" class="btn btn-primary" data-action="togglePeriod"></button></td>') +
950
1008
  '</tr>' +
951
1009
  '<tr>' +
@@ -954,7 +1012,7 @@
954
1012
  '<td>' + (picker.options.useMinutes ? '<a href="#" class="btn" data-action="decrementMinutes"><span class="' + picker.options.icons.down + '"></span></a>' : '') + '</td>' +
955
1013
  (picker.options.useSeconds ?
956
1014
  '<td class="separator"></td><td><a href="#" class="btn" data-action="decrementSeconds"><span class="' + picker.options.icons.down + '"></span></a></td>' : '') +
957
- (picker.options.use24hours ? '' : '<td class="separator"></td>') +
1015
+ (picker.use24hours ? '' : '<td class="separator"></td>') +
958
1016
  '</tr>' +
959
1017
  '</table>' +
960
1018
  '</div>' +
@@ -979,11 +1037,16 @@
979
1037
  };
980
1038
 
981
1039
  picker.show = function (e) {
1040
+ if (picker.options.useCurrent === true) {
1041
+ if (getPickerInput().val() == '') {
1042
+ picker.setValue(pMoment().format(picker.format))
1043
+ };
1044
+ }
982
1045
  picker.widget.show();
983
1046
  picker.height = picker.component ? picker.component.outerHeight() : picker.element.outerHeight();
984
1047
  place();
985
1048
  picker.element.trigger({
986
- type: 'show.dp',
1049
+ type: 'dp.show',
987
1050
  date: pMoment(picker.date)
988
1051
  });
989
1052
  attachDatePickerGlobalEvents();
@@ -994,7 +1057,7 @@
994
1057
 
995
1058
  picker.disable = function () {
996
1059
  var input = picker.element.find('input');
997
- if(input.prop('disabled')) return;
1060
+ if (input.prop('disabled')) return;
998
1061
 
999
1062
  input.prop('disabled', true);
1000
1063
  detachDatePickerEvents();
@@ -1002,7 +1065,7 @@
1002
1065
 
1003
1066
  picker.enable = function () {
1004
1067
  var input = picker.element.find('input');
1005
- if(!input.prop('disabled')) return;
1068
+ if (!input.prop('disabled')) return;
1006
1069
 
1007
1070
  input.prop('disabled', false);
1008
1071
  attachDatePickerEvents();
@@ -1015,14 +1078,14 @@
1015
1078
  var collapse = picker.widget.find('.collapse'), i, collapseData;
1016
1079
  for (i = 0; i < collapse.length; i++) {
1017
1080
  collapseData = collapse.eq(i).data('collapse');
1018
- if (collapseData && collapseData.transitioning)
1081
+ if (collapseData && collapseData.date - transitioning)
1019
1082
  return;
1020
1083
  }
1021
1084
  picker.widget.hide();
1022
1085
  picker.viewMode = picker.startViewMode;
1023
1086
  showMode();
1024
1087
  picker.element.trigger({
1025
- type: 'hide.dp',
1088
+ type: 'dp.hide',
1026
1089
  date: pMoment(picker.date)
1027
1090
  });
1028
1091
  detachDatePickerGlobalEvents();
@@ -1032,6 +1095,7 @@
1032
1095
  pMoment.lang(picker.options.language);
1033
1096
  if (!newDate) {
1034
1097
  picker.unset = true;
1098
+ set();
1035
1099
  } else {
1036
1100
  picker.unset = false;
1037
1101
  }
@@ -1054,26 +1118,33 @@
1054
1118
  },
1055
1119
 
1056
1120
  picker.setDate = function (date) {
1057
- date = pMoment(date);
1058
- if (!date) picker.setValue(null);
1059
- else picker.setValue(date);
1121
+ var oldDate = pMoment(picker.date);
1122
+ if (!date) {
1123
+ picker.setValue(null);
1124
+ } else {
1125
+ picker.setValue(date);
1126
+ }
1127
+ notifyChange(oldDate, "function");
1060
1128
  },
1061
1129
 
1130
+ picker.setDisabledDates = function (dates) {
1131
+ picker.options.disabledDates = indexGivenDates(dates);
1132
+ if (picker.viewDate) update();
1133
+ },
1062
1134
  picker.setEnabledDates = function (dates) {
1063
- if (!dates) picker.options.enabledDates = false;
1064
- else picker.options.enabledDates = dates;
1135
+ picker.options.enabledDates = indexGivenDates(dates);
1065
1136
  if (picker.viewDate) update();
1066
1137
  },
1067
1138
 
1068
- picker.setEndDate = function (date) {
1139
+ picker.setMaxDate = function (date) {
1069
1140
  if (date == undefined) return;
1070
- picker.options.endDate = pMoment(date);
1141
+ picker.options.maxDate = pMoment(date);
1071
1142
  if (picker.viewDate) update();
1072
1143
  },
1073
1144
 
1074
- picker.setStartDate = function (date) {
1145
+ picker.setMinDate = function (date) {
1075
1146
  if (date == undefined) return;
1076
- picker.options.startDate = pMoment(date);
1147
+ picker.options.minDate = pMoment(date);
1077
1148
  if (picker.viewDate) update();
1078
1149
  };
1079
1150
 
@@ -1086,4 +1157,4 @@
1086
1157
  if (!data) $this.data('DateTimePicker', new DateTimePicker(this, options));
1087
1158
  });
1088
1159
  };
1089
- }));
1160
+ }));