1/* ========================================================= 2 * bootstrap-datetimepicker.js 3 * ========================================================= 4 * Copyright 2012 Stefan Petre 5 * 6 * Improvements by Andrew Rowls 7 * Improvements by Sébastien Malot 8 * Improvements by Yun Lai 9 * Improvements by Kenneth Henderick 10 * Improvements by CuGBabyBeaR 11 * Improvements by Christian Vaas <[email protected]> 12 * 13 * Project URL : http://www.malot.fr/bootstrap-datetimepicker 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 28(function(factory){ 29 if (typeof define === 'function' && define.amd) 30 define(['jquery'], factory); 31 else if (typeof exports === 'object') 32 factory(require('jquery')); 33 else 34 factory(jQuery); 35 36}(function($, undefined){ 37 38 // Add ECMA262-5 Array methods if not supported natively (IE8) 39 if (!('indexOf' in Array.prototype)) { 40 Array.prototype.indexOf = function (find, i) { 41 if (i === undefined) i = 0; 42 if (i < 0) i += this.length; 43 if (i < 0) i = 0; 44 for (var n = this.length; i < n; i++) { 45 if (i in this && this[i] === find) { 46 return i; 47 } 48 } 49 return -1; 50 } 51 } 52 53 // Add timezone abbreviation support for ie6+, Chrome, Firefox 54 function timeZoneAbbreviation() { 55 var abbreviation, date, formattedStr, i, len, matchedStrings, ref, str; 56 date = (new Date()).toString(); 57 formattedStr = ((ref = date.split('(')[1]) != null ? ref.slice(0, -1) : 0) || date.split(' '); 58 if (formattedStr instanceof Array) { 59 matchedStrings = []; 60 for (var i = 0, len = formattedStr.length; i < len; i++) { 61 str = formattedStr[i]; 62 if ((abbreviation = (ref = str.match(/\b[A-Z]+\b/)) !== null) ? ref[0] : 0) { 63 matchedStrings.push(abbreviation); 64 } 65 } 66 formattedStr = matchedStrings.pop(); 67 } 68 return formattedStr; 69 } 70 71 function UTCDate() { 72 return new Date(Date.UTC.apply(Date, arguments)); 73 } 74 75 // Picker object 76 var Datetimepicker = function (element, options) { 77 var that = this; 78 79 this.element = $(element); 80 81 // add container for single page application 82 // when page switch the datetimepicker div will be removed also. 83 this.container = options.container || 'body'; 84 85 this.language = options.language || this.element.data('date-language') || 'en'; 86 this.language = this.language in dates ? this.language : this.language.split('-')[0]; // fr-CA fallback to fr 87 this.language = this.language in dates ? this.language : 'en'; 88 this.isRTL = dates[this.language].rtl || false; 89 this.formatType = options.formatType || this.element.data('format-type') || 'standard'; 90 this.format = DPGlobal.parseFormat(options.format || this.element.data('date-format') || dates[this.language].format || DPGlobal.getDefaultFormat(this.formatType, 'input'), this.formatType); 91 this.isInline = false; 92 this.isVisible = false; 93 this.isInput = this.element.is('input'); 94 this.fontAwesome = options.fontAwesome || this.element.data('font-awesome') || false; 95 96 this.bootcssVer = options.bootcssVer || (this.isInput ? (this.element.is('.form-control') ? 3 : 2) : ( this.bootcssVer = this.element.is('.input-group') ? 3 : 2 )); 97 98 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-remove, .input-group-addon .glyphicon-calendar, .input-group-addon .fa-calendar, .input-group-addon .fa-clock-o').parent() : this.element.find('.add-on .icon-th, .add-on .icon-time, .add-on .icon-calendar, .add-on .fa-calendar, .add-on .fa-clock-o').parent()) : false;
99 this.componentReset = this.element.is('.date') ? ( this.bootcssVer === 3 ? this.element.find('.input-group-addon .glyphicon-remove, .input-group-addon .fa-times').parent():this.element.find('.add-on .icon-remove, .add-on .fa-times').parent()) : false; 100 this.hasInput = this.component && this.element.find('input').length; 101 if (this.component && this.component.length === 0) { 102 this.component = false; 103 } 104 this.linkField = options.linkField || this.element.data('link-field') || false; 105 this.linkFormat = DPGlobal.parseFormat(options.linkFormat || this.element.data('link-format') || DPGlobal.getDefaultFormat(this.formatType, 'link'), this.formatType); 106 this.minuteStep = options.minuteStep || this.element.data('minute-step') || 5; 107 this.pickerPosition = options.pickerPosition || this.element.data('picker-position') || 'bottom-right'; 108 this.showMeridian = options.showMeridian || this.element.data('show-meridian') || false; 109 this.initialDate = options.initialDate || new Date(); 110 this.zIndex = options.zIndex || this.element.data('z-index') || undefined; 111 this.title = typeof options.title === 'undefined' ? false : options.title; 112 this.timezone = options.timezone || timeZoneAbbreviation(); 113 114 this.icons = { 115 leftArrow: this.fontAwesome ? 'fa-arrow-left' : (this.bootcssVer === 3 ? 'glyphicon-arrow-left' : 'icon-arrow-left'), 116 rightArrow: this.fontAwesome ? 'fa-arrow-right' : (this.bootcssVer === 3 ? 'glyphicon-arrow-right' : 'icon-arrow-right') 117 } 118 this.icontype = this.fontAwesome ? 'fa' : 'glyphicon'; 119 120 this._attachEvents(); 121 122 this.clickedOutside = function (e) { 123 // Clicked outside the datetimepicker, hide it 124 if ($(e.target).closest('.datetimepicker').length === 0) { 125 that.hide(); 126 } 127 } 128 129 this.formatViewType = 'datetime'; 130 if ('formatViewType' in options) { 131 this.formatViewType = options.formatViewType; 132 } else if ('formatViewType' in this.element.data()) { 133 this.formatViewType = this.element.data('formatViewType'); 134 } 135 136 this.minView = 0; 137 if ('minView' in options) { 138 this.minView = options.minView; 139 } else if ('minView' in this.element.data()) { 140 this.minView = this.element.data('min-view'); 141 } 142 this.minView = DPGlobal.convertViewMode(this.minView); 143 144 this.maxView = DPGlobal.modes.length - 1; 145 if ('maxView' in options) { 146 this.maxView = options.maxView; 147 } else if ('maxView' in this.element.data()) { 148 this.maxView = this.element.data('max-view'); 149 } 150 this.maxView = DPGlobal.convertViewMode(this.maxView); 151 152 this.wheelViewModeNavigation = false; 153 if ('wheelViewModeNavigation' in options) { 154 this.wheelViewModeNavigation = options.wheelViewModeNavigation; 155 } else if ('wheelViewModeNavigation' in this.element.data()) { 156 this.wheelViewModeNavigation = this.element.data('view-mode-wheel-navigation'); 157 } 158 159 this.wheelViewModeNavigationInverseDirection = false; 160 161 if ('wheelViewModeNavigationInverseDirection' in options) { 162 this.wheelViewModeNavigationInverseDirection = options.wheelViewModeNavigationInverseDirection; 163 } else if ('wheelViewModeNavigationInverseDirection' in this.element.data()) { 164 this.wheelViewModeNavigationInverseDirection = this.element.data('view-mode-wheel-navigation-inverse-dir'); 165 } 166 167 this.wheelViewModeNavigationDelay = 100; 168 if ('wheelViewModeNavigationDelay' in options) { 169 this.wheelViewModeNavigationDelay = options.wheelViewModeNavigationDelay; 170 } else if ('wheelViewModeNavigationDelay' in this.element.data()) { 171 this.wheelViewModeNavigationDelay = this.element.data('view-mode-wheel-navigation-delay'); 172 } 173 174 this.startViewMode = 2; 175 if ('startView' in options) { 176 this.startViewMode = options.startView; 177 } else if ('startView' in this.element.data()) { 178 this.startViewMode = this.element.data('start-view'); 179 } 180 this.startViewMode = DPGlobal.convertViewMode(this.startViewMode); 181 this.viewMode = this.startViewMode; 182 183 this.viewSelect = this.minView; 184 if ('viewSelect' in options) { 185 this.viewSelect = options.viewSelect; 186 } else if ('viewSelect' in this.element.data()) { 187 this.viewSelect = this.element.data('view-select'); 188 } 189 this.viewSelect = DPGlobal.convertViewMode(this.viewSelect); 190 191 this.forceParse = true; 192 if ('forceParse' in options) { 193 this.forceParse = options.forceParse; 194 } else if ('dateForceParse' in this.element.data()) { 195 this.forceParse = this.element.data('date-force-parse'); 196 } 197 var template = this.bootcssVer === 3 ? DPGlobal.templateV3 : DPGlobal.template; 198 while (template.indexOf('{iconType}') !== -1) { 199 template = template.replace('{iconType}', this.icontype); 200 } 201 while (template.indexOf('{leftArrow}') !== -1) { 202 template = template.replace('{leftArrow}', this.icons.leftArrow); 203 } 204 while (template.indexOf('{rightArrow}') !== -1) { 205 template = template.replace('{rightArrow}', this.icons.rightArrow); 206 } 207 this.picker = $(template) 208 .appendTo(this.isInline ? this.element : this.container) // 'body') 209 .on({ 210 click: $.proxy(this.click, this), 211 mousedown: $.proxy(this.mousedown, this) 212 }); 213 214 if (this.wheelViewModeNavigation) { 215 if ($.fn.mousewheel) { 216 this.picker.on({mousewheel: $.proxy(this.mousewheel, this)}); 217 } else { 218 console.log('Mouse Wheel event is not supported. Please include the jQuery Mouse Wheel plugin before enabling this option'); 219 } 220 } 221 222 if (this.isInline) { 223 this.picker.addClass('datetimepicker-inline'); 224 } else { 225 this.picker.addClass('datetimepicker-dropdown-' + this.pickerPosition + ' dropdown-menu'); 226 } 227 if (this.isRTL) { 228 this.picker.addClass('datetimepicker-rtl'); 229 var selector = this.bootcssVer === 3 ? '.prev span, .next span' : '.prev i, .next i'; 230 this.picker.find(selector).toggleClass(this.icons.leftArrow + ' ' + this.icons.rightArrow); 231 } 232 233 $(document).on('mousedown touchend', this.clickedOutside); 234 235 this.autoclose = false;
236 if ('autoclose' in options) { 237 this.autoclose = options.autoclose; 238 } else if ('dateAutoclose' in this.element.data()) { 239 this.autoclose = this.element.data('date-autoclose'); 240 } 241 242 this.keyboardNavigation = true; 243 if ('keyboardNavigation' in options) { 244 this.keyboardNavigation = options.keyboardNavigation; 245 } else if ('dateKeyboardNavigation' in this.element.data()) { 246 this.keyboardNavigation = this.element.data('date-keyboard-navigation'); 247 } 248 249 this.todayBtn = (options.todayBtn || this.element.data('date-today-btn') || false); 250 this.clearBtn = (options.clearBtn || this.element.data('date-clear-btn') || false); 251 this.todayHighlight = (options.todayHighlight || this.element.data('date-today-highlight') || false); 252 253 this.weekStart = 0; 254 if (typeof options.weekStart !== 'undefined') { 255 this.weekStart = options.weekStart; 256 } else if (typeof this.element.data('date-weekstart') !== 'undefined') { 257 this.weekStart = this.element.data('date-weekstart'); 258 } else if (typeof dates[this.language].weekStart !== 'undefined') { 259 this.weekStart = dates[this.language].weekStart; 260 } 261 this.weekStart = this.weekStart % 7; 262 this.weekEnd = ((this.weekStart + 6) % 7); 263 this.onRenderDay = function (date) { 264 var render = (options.onRenderDay || function () { return []; })(date); 265 if (typeof render === 'string') { 266 render = [render]; 267 } 268 var res = ['day']; 269 return res.concat((render ? render : [])); 270 }; 271 this.onRenderHour = function (date) { 272 var render = (options.onRenderHour || function () { return []; })(date); 273 var res = ['hour']; 274 if (typeof render === 'string') { 275 render = [render]; 276 } 277 return res.concat((render ? render : [])); 278 }; 279 this.onRenderMinute = function (date) { 280 var render = (options.onRenderMinute || function () { return []; })(date); 281 var res = ['minute']; 282 if (typeof render === 'string') { 283 render = [render]; 284 } 285 if (date < this.startDate || date > this.endDate) { 286 res.push('disabled'); 287 } else if (Math.floor(this.date.getUTCMinutes() / this.minuteStep) === Math.floor(date.getUTCMinutes() / this.minuteStep)) { 288 res.push('active'); 289 } 290 return res.concat((render ? render : [])); 291 }; 292 this.onRenderYear = function (date) { 293 var render = (options.onRenderYear || function () { return []; })(date); 294 var res = ['year']; 295 if (typeof render === 'string') { 296 render = [render]; 297 } 298 if (this.date.getUTCFullYear() === date.getUTCFullYear()) { 299 res.push('active'); 300 } 301 var currentYear = date.getUTCFullYear(); 302 var endYear = this.endDate.getUTCFullYear(); 303 if (date < this.startDate || currentYear > endYear) { 304 res.push('disabled'); 305 } 306 return res.concat((render ? render : [])); 307 } 308 this.onRenderMonth = function (date) { 309 var render = (options.onRenderMonth || function () { return []; })(date); 310 var res = ['month']; 311 if (typeof render === 'string') { 312 render = [render]; 313 } 314 return res.concat((render ? render : [])); 315 } 316 this.startDate = new Date(-8639968443048000); 317 this.endDate = new Date(8639968443048000); 318 this.datesDisabled = []; 319 this.daysOfWeekDisabled = []; 320 this.setStartDate(options.startDate || this.element.data('date-startdate')); 321 this.setEndDate(options.endDate || this.element.data('date-enddate')); 322 this.setDatesDisabled(options.datesDisabled || this.element.data('date-dates-disabled')); 323 this.setDaysOfWeekDisabled(options.daysOfWeekDisabled || this.element.data('date-days-of-week-disabled')); 324 this.setMinutesDisabled(options.minutesDisabled || this.element.data('date-minute-disabled')); 325 this.setHoursDisabled(options.hoursDisabled || this.element.data('date-hour-disabled')); 326 this.fillDow(); 327 this.fillMonths(); 328 this.update(); 329 this.showMode(); 330 331 if (this.isInline) { 332 this.show(); 333 } 334 }; 335 336 Datetimepicker.prototype = { 337 constructor: Datetimepicker, 338 339 _events: [], 340 _attachEvents: function () { 341 this._detachEvents(); 342 if (this.isInput) { // single input 343 this._events = [ 344 [this.element, { 345 focus: $.proxy(this.show, this), 346 keyup: $.proxy(this.update, this), 347 keydown: $.proxy(this.keydown, this) 348 }] 349 ]; 350 } 351 else if (this.component && this.hasInput) { // component: input + button 352 this._events = [ 353 // For components that are not readonly, allow keyboard nav 354 [this.element.find('input'), { 355 focus: $.proxy(this.show, this), 356 keyup: $.proxy(this.update, this), 357 keydown: $.proxy(this.keydown, this) 358 }], 359 [this.component, { 360 click: $.proxy(this.show, this) 361 }] 362 ]; 363 if (this.componentReset) { 364 this._events.push([ 365 this.componentReset, 366 {click: $.proxy(this.reset, this)} 367 ]); 368 } 369 } 370 else if (this.element.is('div')) { // inline datetimepicker 371 this.isInline = true; 372 } 373 else { 374 this._events = [ 375 [this.element, { 376 click: $.proxy(this.show, this) 377 }] 378 ]; 379 } 380 for (var i = 0, el, ev; i < this._events.length; i++) { 381 el = this._events[i][0]; 382 ev = this._events[i][1]; 383 el.on(ev); 384 } 385 }, 386 387 _detachEvents: function () { 388 for (var i = 0, el, ev; i < this._events.length; i++) { 389 el = this._events[i][0]; 390 ev = this._events[i][1]; 391 el.off(ev); 392 } 393 this._events = []; 394 }, 395 396 show: function (e) { 397 this.picker.show(); 398 this.height = this.component ? this.component.outerHeight() : this.element.outerHeight(); 399 if (this.forceParse) { 400 this.update(); 401 } 402 this.place(); 403 $(window).on('resize', $.proxy(this.place, this)); 404 if (e) { 405 e.stopPropagation(); 406 e.preventDefault(); 407 } 408 this.isVisible = true; 409 this.element.trigger({ 410 type: 'show', 411 date: this.date 412 }); 413 }, 414 415 hide: function () { 416 if (!this.isVisible) return; 417 if (this.isInline) return; 418 this.picker.hide(); 419 $(window).off('resize', this.place); 420 this.viewMode = this.startViewMode; 421 this.showMode(); 422 if (!this.isInput) { 423 $(document).off('mousedown', this.hide); 424 } 425 426 if ( 427 this.forceParse && 428 ( 429 this.isInput && this.element.val() || 430 this.hasInput && this.element.find('input').val() 431 ) 432 ) 433 this.setValue(); 434 this.isVisible = false;
435 this.element.trigger({ 436 type: 'hide', 437 date: this.date 438 }); 439 }, 440 441 remove: function () { 442 this._detachEvents(); 443 $(document).off('mousedown', this.clickedOutside); 444 this.picker.remove(); 445 delete this.picker; 446 delete this.element.data().datetimepicker; 447 }, 448 449 getDate: function () { 450 var d = this.getUTCDate(); 451 if (d === null || typeof d === 'undefined') { 452 return null; 453 } 454 return new Date(d.getTime() + (d.getTimezoneOffset() * 60000)); 455 }, 456 457 getUTCDate: function () { 458 return this.date; 459 }, 460 461 getInitialDate: function () { 462 return this.initialDate 463 }, 464 465 setInitialDate: function (initialDate) { 466 this.initialDate = initialDate; 467 }, 468 469 setDate: function (d) { 470 this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset() * 60000))); 471 }, 472 473 setUTCDate: function (d) { 474 if (d >= this.startDate && d <= this.endDate) { 475 this.date = d; 476 this.setValue(); 477 this.viewDate = this.date; 478 this.fill(); 479 } else { 480 this.element.trigger({ 481 type: 'outOfRange', 482 date: d, 483 startDate: this.startDate, 484 endDate: this.endDate 485 }); 486 } 487 }, 488 489 setFormat: function (format) { 490 this.format = DPGlobal.parseFormat(format, this.formatType); 491 var element; 492 if (this.isInput) { 493 element = this.element; 494 } else if (this.component) { 495 element = this.element.find('input'); 496 } 497 if (element && element.val()) { 498 this.setValue(); 499 } 500 }, 501 502 setValue: function () { 503 var formatted = this.getFormattedDate(); 504 if (!this.isInput) { 505 if (this.component) { 506 this.element.find('input').val(formatted); 507 } 508 this.element.data('date', formatted); 509 } else { 510 this.element.val(formatted); 511 } 512 if (this.linkField) { 513 $('#' + this.linkField).val(this.getFormattedDate(this.linkFormat)); 514 } 515 }, 516 517 getFormattedDate: function (format) { 518 format = format || this.format; 519 return DPGlobal.formatDate(this.date, format, this.language, this.formatType, this.timezone); 520 }, 521 522 setStartDate: function (startDate) { 523 this.startDate = startDate || this.startDate; 524 if (this.startDate.valueOf() !== 8639968443048000) { 525 this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language, this.formatType, this.timezone); 526 } 527 this.update(); 528 this.updateNavArrows(); 529 }, 530 531 setEndDate: function (endDate) { 532 this.endDate = endDate || this.endDate; 533 if (this.endDate.valueOf() !== 8639968443048000) { 534 this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language, this.formatType, this.timezone); 535 } 536 this.update(); 537 this.updateNavArrows(); 538 }, 539 540 setDatesDisabled: function (datesDisabled) { 541 this.datesDisabled = datesDisabled || []; 542 if (!$.isArray(this.datesDisabled)) { 543 this.datesDisabled = this.datesDisabled.split(/,\s*/); 544 } 545 var mThis = this; 546 this.datesDisabled = $.map(this.datesDisabled, function (d) { 547 return DPGlobal.parseDate(d, mThis.format, mThis.language, mThis.formatType, mThis.timezone).toDateString(); 548 }); 549 this.update(); 550 this.updateNavArrows(); 551 }, 552 553 setTitle: function (selector, value) { 554 return this.picker.find(selector) 555 .find('th:eq(1)') 556 .text(this.title === false ? value : this.title); 557 }, 558 559 setDaysOfWeekDisabled: function (daysOfWeekDisabled) { 560 this.daysOfWeekDisabled = daysOfWeekDisabled || []; 561 if (!$.isArray(this.daysOfWeekDisabled)) { 562 this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/); 563 } 564 this.daysOfWeekDisabled = $.map(this.daysOfWeekDisabled, function (d) { 565 return parseInt(d, 10); 566 }); 567 this.update(); 568 this.updateNavArrows(); 569 }, 570 571 setMinutesDisabled: function (minutesDisabled) { 572 this.minutesDisabled = minutesDisabled || []; 573 if (!$.isArray(this.minutesDisabled)) { 574 this.minutesDisabled = this.minutesDisabled.split(/,\s*/); 575 } 576 this.minutesDisabled = $.map(this.minutesDisabled, function (d) { 577 return parseInt(d, 10); 578 }); 579 this.update(); 580 this.updateNavArrows(); 581 }, 582 583 setHoursDisabled: function (hoursDisabled) { 584 this.hoursDisabled = hoursDisabled || []; 585 if (!$.isArray(this.hoursDisabled)) { 586 this.hoursDisabled = this.hoursDisabled.split(/,\s*/); 587 } 588 this.hoursDisabled = $.map(this.hoursDisabled, function (d) { 589 return parseInt(d, 10); 590 }); 591 this.update(); 592 this.updateNavArrows(); 593 }, 594 595 place: function () { 596 if (this.isInline) return; 597 598 if (!this.zIndex) { 599 var index_highest = 0; 600 $('div').each(function () { 601 var index_current = parseInt($(this).css('zIndex'), 10); 602 if (index_current > index_highest) { 603 index_highest = index_current; 604 } 605 }); 606 this.zIndex = index_highest + 10; 607 } 608 609 var offset, top, left, containerOffset; 610 if (this.container instanceof $) { 611 containerOffset = this.container.offset(); 612 } else { 613 containerOffset = $(this.container).offset(); 614 } 615 616 if (this.component) { 617 offset = this.component.offset(); 618 left = offset.left; 619 if (this.pickerPosition === 'bottom-left' || this.pickerPosition === 'top-left') { 620 left += this.component.outerWidth() - this.picker.outerWidth(); 621 } 622 } else { 623 offset = this.element.offset(); 624 left = offset.left; 625 if (this.pickerPosition === 'bottom-left' || this.pickerPosition === 'top-left') { 626 left += this.element.outerWidth() - this.picker.outerWidth(); 627 } 628 } 629 630 var bodyWidth = document.body.clientWidth || window.innerWidth; 631 if (left + 220 > bodyWidth) { 632 left = bodyWidth - 220; 633 } 634 635 if (this.pickerPosition === 'top-left' || this.pickerPosition === 'top-right') { 636 top = offset.top - this.picker.outerHeight(); 637 } else { 638 top = offset.top + this.height; 639 } 640 641 top = top - containerOffset.top; 642 left = left - containerOffset.left; 643 644 this.picker.css({ 645 top: top, 646 left: left, 647 zIndex: this.zIndex 648 }); 649 }, 650 651 hour_minute: "^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]", 652 653 update: function () { 654 var date, fromArgs = false;
655 if (arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) { 656 date = arguments[0]; 657 fromArgs = true; 658 } else { 659 date = (this.isInput ? this.element.val() : this.element.find('input').val()) || this.element.data('date') || this.initialDate; 660 if (typeof date === 'string') { 661 date = date.replace(/^\s+|\s+$/g,''); 662 } 663 } 664 665 if (!date) { 666 date = new Date(); 667 fromArgs = false; 668 } 669 670 if (typeof date === "string") { 671 if (new RegExp(this.hour_minute).test(date) || new RegExp(this.hour_minute + ":[0-5][0-9]").test(date)) { 672 date = this.getDate() 673 } 674 } 675 676 this.date = DPGlobal.parseDate(date, this.format, this.language, this.formatType, this.timezone); 677 678 if (fromArgs) this.setValue(); 679 680 if (this.date < this.startDate) { 681 this.viewDate = new Date(this.startDate); 682 } else if (this.date > this.endDate) { 683 this.viewDate = new Date(this.endDate); 684 } else { 685 this.viewDate = new Date(this.date); 686 } 687 this.fill(); 688 }, 689 690 fillDow: function () { 691 var dowCnt = this.weekStart, 692 html = '<tr>'; 693 while (dowCnt < this.weekStart + 7) { 694 html += '<th class="dow">' + dates[this.language].daysMin[(dowCnt++) % 7] + '</th>'; 695 } 696 html += '</tr>'; 697 this.picker.find('.datetimepicker-days thead').append(html); 698 }, 699 700 fillMonths: function () { 701 var html = ''; 702 var d = new Date(this.viewDate); 703 for (var i = 0; i < 12; i++) { 704 d.setUTCMonth(i); 705 var classes = this.onRenderMonth(d); 706 html += '<span class="' + classes.join(' ') + '">' + dates[this.language].monthsShort[i] + '</span>'; 707 } 708 this.picker.find('.datetimepicker-months td').html(html); 709 }, 710 711 fill: function () { 712 if (!this.date || !this.viewDate) { 713 return; 714 } 715 var d = new Date(this.viewDate), 716 year = d.getUTCFullYear(), 717 month = d.getUTCMonth(), 718 dayMonth = d.getUTCDate(), 719 hours = d.getUTCHours(), 720 startYear = this.startDate.getUTCFullYear(), 721 startMonth = this.startDate.getUTCMonth(), 722 endYear = this.endDate.getUTCFullYear(), 723 endMonth = this.endDate.getUTCMonth() + 1, 724 currentDate = (new UTCDate(this.date.getUTCFullYear(), this.date.getUTCMonth(), this.date.getUTCDate())).valueOf(), 725 today = new Date(); 726 this.setTitle('.datetimepicker-days', dates[this.language].months[month] + ' ' + year) 727 if (this.formatViewType === 'time') { 728 var formatted = this.getFormattedDate(); 729 this.setTitle('.datetimepicker-hours', formatted); 730 this.setTitle('.datetimepicker-minutes', formatted); 731 } else { 732 this.setTitle('.datetimepicker-hours', dayMonth + ' ' + dates[this.language].months[month] + ' ' + year); 733 this.setTitle('.datetimepicker-minutes', dayMonth + ' ' + dates[this.language].months[month] + ' ' + year); 734 } 735 this.picker.find('tfoot th.today') 736 .text(dates[this.language].today || dates['en'].today) 737 .toggle(this.todayBtn !== false); 738 this.picker.find('tfoot th.clear') 739 .text(dates[this.language].clear || dates['en'].clear) 740 .toggle(this.clearBtn !== false); 741 this.updateNavArrows(); 742 this.fillMonths(); 743 var prevMonth = UTCDate(year, month - 1, 28, 0, 0, 0, 0), 744 day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth()); 745 prevMonth.setUTCDate(day); 746 prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7) % 7); 747 var nextMonth = new Date(prevMonth); 748 nextMonth.setUTCDate(nextMonth.getUTCDate() + 42); 749 nextMonth = nextMonth.valueOf(); 750 var html = []; 751 var classes; 752 while (prevMonth.valueOf() < nextMonth) { 753 if (prevMonth.getUTCDay() === this.weekStart) { 754 html.push('<tr>'); 755 } 756 classes = this.onRenderDay(prevMonth); 757 if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() === year && prevMonth.getUTCMonth() < month)) { 758 classes.push('old'); 759 } else if (prevMonth.getUTCFullYear() > year || (prevMonth.getUTCFullYear() === year && prevMonth.getUTCMonth() > month)) { 760 classes.push('new'); 761 } 762 // Compare internal UTC date with local today, not UTC today 763 if (this.todayHighlight && 764 prevMonth.getUTCFullYear() === today.getFullYear() && 765 prevMonth.getUTCMonth() === today.getMonth() && 766 prevMonth.getUTCDate() === today.getDate()) { 767 classes.push('today'); 768 } 769 if (prevMonth.valueOf() === currentDate) { 770 classes.push('active'); 771 } 772 if ((prevMonth.valueOf() + 86400000) <= this.startDate || prevMonth.valueOf() > this.endDate || 773 $.inArray(prevMonth.getUTCDay(), this.daysOfWeekDisabled) !== -1 || 774 $.inArray(prevMonth.toDateString(), this.datesDisabled) !== -1) { 775 classes.push('disabled'); 776 } 777 html.push('<td class="' + classes.join(' ') + '">' + prevMonth.getUTCDate() + '</td>'); 778 if (prevMonth.getUTCDay() === this.weekEnd) { 779 html.push('</tr>'); 780 } 781 prevMonth.setUTCDate(prevMonth.getUTCDate() + 1); 782 } 783 this.picker.find('.datetimepicker-days tbody').empty().append(html.join('')); 784 785 html = []; 786 var txt = '', meridian = '', meridianOld = ''; 787 var hoursDisabled = this.hoursDisabled || []; 788 d = new Date(this.viewDate) 789 for (var i = 0; i < 24; i++) { 790 d.setUTCHours(i); 791 classes = this.onRenderHour(d); 792 if (hoursDisabled.indexOf(i) !== -1) { 793 classes.push('disabled'); 794 } 795 var actual = UTCDate(year, month, dayMonth, i); 796 // We want the previous hour for the startDate 797 if ((actual.valueOf() + 3600000) <= this.startDate || actual.valueOf() > this.endDate) { 798 classes.push('disabled'); 799 } else if (hours === i) { 800 classes.push('active'); 801 } 802 if (this.showMeridian && dates[this.language].meridiem.length === 2) { 803 meridian = (i < 12 ? dates[this.language].meridiem[0] : dates[this.language].meridiem[1]); 804 if (meridian !== meridianOld) { 805 if (meridianOld !== '') { 806 html.push('</fieldset>'); 807 } 808 html.push('<fieldset class="hour"><legend>' + meridian.toUpperCase() + '</legend>'); 809 } 810 meridianOld = meridian; 811 txt = (i % 12 ? i % 12 : 12); 812 if (i < 12) { 813 classes.push('hour_am'); 814 } else { 815 classes.push('hour_pm'); 816 } 817 html.push('<span class="' + classes.join(' ') + '">' + txt + '</span>'); 818 if (i === 23) { 819 html.push('</fieldset>'); 820 } 821 } else { 822 txt = i + ':00'; 823 html.push('<span class="' + classes.join(' ') + '">' + txt + '</span>'); 824 } 825 } 826 this.picker.find('.datetimepicker-hours td').html(html.join('')); 827 828 html = []; 829 txt = ''; 830 meridian = ''; 831 meridianOld = ''; 832 var minutesDisabled = this.minutesDisabled || []; 833 d = new Date(this.viewDate); 834 for (var i = 0; i < 60; i += this.minuteStep) { 835 if (minutesDisabled.indexOf(i) !== -1) continue; 836 d.setUTCMinutes(i); 837 d.setUTCSeconds(0); 838 classes = this.onRenderMinute(d); 839 if (this.showMeridian && dates[this.language].meridiem.length === 2) { 840 meridian = (hours < 12 ? dates[this.language].meridiem[0] : dates[this.language].meridiem[1]); 841 if (meridian !== meridianOld) { 842 if (meridianOld !== '') { 843 html.push('</fieldset>'); 844 } 845 html.push('<fieldset class="minute"><legend>' + meridian.toUpperCase() + '</legend>'); 846 } 847 meridianOld = meridian; 848 txt = (hours % 12 ? hours % 12 : 12); 849 html.push('<span class="' + classes.join(' ') + '">' + txt + ':' + (i < 10 ? '0' + i : i) + '</span>'); 850 if (i === 59) { 851 html.push('</fieldset>'); 852 } 853 } else { 854 txt = i + ':00'; 855 html.push('<span class="' + classes.join(' ') + '">' + hours + ':' + (i < 10 ? '0' + i : i) + '</span>'); 856 } 857 } 858 this.picker.find('.datetimepicker-minutes td').html(html.join('')); 859 860 var currentYear = this.date.getUTCFullYear(); 861 var months = this.setTitle('.datetimepicker-months', year) 862 .end() 863 .find('.month').removeClass('active'); 864 if (currentYear === year) { 865 // getUTCMonths() returns 0 based, and we need to select the next one 866 // To cater bootstrap 2 we don't need to select the next one 867 months.eq(this.date.getUTCMonth()).addClass('active'); 868 } 869 if (year < startYear || year > endYear) { 870 months.addClass('disabled'); 871 } 872 if (year === startYear) { 873 months.slice(0, startMonth).addClass('disabled'); 874 } 875 if (year === endYear) { 876 months.slice(endMonth).addClass('disabled'); 877 } 878 879 html = ''; 880 year = parseInt(year / 10, 10) * 10; 881 var yearCont = this.setTitle('.datetimepicker-years', year + '-' + (year + 9)) 882 .end() 883 .find('td'); 884 year -= 1; 885 d = new Date(this.viewDate);
886 for (var i = -1; i < 11; i++) { 887 d.setUTCFullYear(year); 888 classes = this.onRenderYear(d); 889 if (i === -1 || i === 10) { 890 classes.push(old); 891 } 892 html += '<span class="' + classes.join(' ') + '">' + year + '</span>'; 893 year += 1; 894 } 895 yearCont.html(html); 896 this.place(); 897 }, 898 899 updateNavArrows: function () { 900 var d = new Date(this.viewDate), 901 year = d.getUTCFullYear(), 902 month = d.getUTCMonth(), 903 day = d.getUTCDate(), 904 hour = d.getUTCHours(); 905 switch (this.viewMode) { 906 case 0: 907 if (year <= this.startDate.getUTCFullYear() 908 && month <= this.startDate.getUTCMonth() 909 && day <= this.startDate.getUTCDate() 910 && hour <= this.startDate.getUTCHours()) { 911 this.picker.find('.prev').css({visibility: 'hidden'}); 912 } else { 913 this.picker.find('.prev').css({visibility: 'visible'}); 914 } 915 if (year >= this.endDate.getUTCFullYear() 916 && month >= this.endDate.getUTCMonth() 917 && day >= this.endDate.getUTCDate() 918 && hour >= this.endDate.getUTCHours()) { 919 this.picker.find('.next').css({visibility: 'hidden'}); 920 } else { 921 this.picker.find('.next').css({visibility: 'visible'}); 922 } 923 break; 924 case 1: 925 if (year <= this.startDate.getUTCFullYear() 926 && month <= this.startDate.getUTCMonth() 927 && day <= this.startDate.getUTCDate()) { 928 this.picker.find('.prev').css({visibility: 'hidden'}); 929 } else { 930 this.picker.find('.prev').css({visibility: 'visible'}); 931 } 932 if (year >= this.endDate.getUTCFullYear() 933 && month >= this.endDate.getUTCMonth() 934 && day >= this.endDate.getUTCDate()) { 935 this.picker.find('.next').css({visibility: 'hidden'}); 936 } else { 937 this.picker.find('.next').css({visibility: 'visible'}); 938 } 939 break; 940 case 2: 941 if (year <= this.startDate.getUTCFullYear() 942 && month <= this.startDate.getUTCMonth()) { 943 this.picker.find('.prev').css({visibility: 'hidden'}); 944 } else { 945 this.picker.find('.prev').css({visibility: 'visible'}); 946 } 947 if (year >= this.endDate.getUTCFullYear() 948 && month >= this.endDate.getUTCMonth()) { 949 this.picker.find('.next').css({visibility: 'hidden'}); 950 } else { 951 this.picker.find('.next').css({visibility: 'visible'}); 952 } 953 break; 954 case 3: 955 case 4: 956 if (year <= this.startDate.getUTCFullYear()) { 957 this.picker.find('.prev').css({visibility: 'hidden'}); 958 } else { 959 this.picker.find('.prev').css({visibility: 'visible'}); 960 } 961 if (year >= this.endDate.getUTCFullYear()) { 962 this.picker.find('.next').css({visibility: 'hidden'}); 963 } else { 964 this.picker.find('.next').css({visibility: 'visible'}); 965 } 966 break; 967 } 968 }, 969 970 mousewheel: function (e) { 971 972 e.preventDefault(); 973 e.stopPropagation(); 974 975 if (this.wheelPause) { 976 return; 977 } 978 979 this.wheelPause = true; 980 981 var originalEvent = e.originalEvent; 982 983 var delta = originalEvent.wheelDelta; 984 985 var mode = delta > 0 ? 1 : (delta === 0) ? 0 : -1; 986 987 if (this.wheelViewModeNavigationInverseDirection) { 988 mode = -mode; 989 } 990 991 this.showMode(mode); 992 993 setTimeout($.proxy(function () { 994 995 this.wheelPause = false 996 997 }, this), this.wheelViewModeNavigationDelay); 998 999 }, 1000 1001 click: function (e) { 1002 e.stopPropagation(); 1003 e.preventDefault(); 1004 var target = $(e.target).closest('span, td, th, legend'); 1005 if (target.is('.' + this.icontype)) { 1006 target = $(target).parent().closest('span, td, th, legend'); 1007 } 1008 if (target.length === 1) { 1009 if (target.is('.disabled')) { 1010 this.element.trigger({ 1011 type: 'outOfRange', 1012 date: this.viewDate, 1013 startDate: this.startDate, 1014 endDate: this.endDate 1015 }); 1016 return; 1017 } 1018 switch (target[0].nodeName.toLowerCase()) { 1019 case 'th': 1020 switch (target[0].className) { 1021 case 'switch': 1022 this.showMode(1); 1023 break; 1024 case 'prev': 1025 case 'next': 1026 var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1); 1027 switch (this.viewMode) { 1028 case 0: 1029 this.viewDate = this.moveHour(this.viewDate, dir); 1030 break; 1031 case 1: 1032 this.viewDate = this.moveDate(this.viewDate, dir); 1033 break; 1034 case 2: 1035 this.viewDate = this.moveMonth(this.viewDate, dir); 1036 break; 1037 case 3: 1038 case 4: 1039 this.viewDate = this.moveYear(this.viewDate, dir); 1040 break; 1041 } 1042 this.fill(); 1043 this.element.trigger({ 1044 type: target[0].className + ':' + this.convertViewModeText(this.viewMode), 1045 date: this.viewDate, 1046 startDate: this.startDate, 1047 endDate: this.endDate 1048 }); 1049 break; 1050 case 'clear': 1051 this.reset(); 1052 if (this.autoclose) { 1053 this.hide(); 1054 } 1055 break; 1056 case 'today': 1057 var date = new Date(); 1058 date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0); 1059 1060 // Respect startDate and endDate. 1061 if (date < this.startDate) date = this.startDate; 1062 else if (date > this.endDate) date = this.endDate; 1063 1064 this.viewMode = this.startViewMode; 1065 this.showMode(0); 1066 this._setDate(date); 1067 this.fill(); 1068 if (this.autoclose) { 1069 this.hide(); 1070 } 1071 break; 1072 } 1073 break; 1074 case 'span': 1075 if (!target.is('.disabled')) { 1076 var year = this.viewDate.getUTCFullYear(),
1077 month = this.viewDate.getUTCMonth(), 1078 day = this.viewDate.getUTCDate(), 1079 hours = this.viewDate.getUTCHours(), 1080 minutes = this.viewDate.getUTCMinutes(), 1081 seconds = this.viewDate.getUTCSeconds(); 1082 1083 if (target.is('.month')) { 1084 this.viewDate.setUTCDate(1); 1085 month = target.parent().find('span').index(target); 1086 day = this.viewDate.getUTCDate(); 1087 this.viewDate.setUTCMonth(month); 1088 this.element.trigger({ 1089 type: 'changeMonth', 1090 date: this.viewDate 1091 }); 1092 if (this.viewSelect >= 3) { 1093 this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0)); 1094 } 1095 } else if (target.is('.year')) { 1096 this.viewDate.setUTCDate(1); 1097 year = parseInt(target.text(), 10) || 0; 1098 this.viewDate.setUTCFullYear(year); 1099 this.element.trigger({ 1100 type: 'changeYear', 1101 date: this.viewDate 1102 }); 1103 if (this.viewSelect >= 4) { 1104 this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0)); 1105 } 1106 } else if (target.is('.hour')) { 1107 hours = parseInt(target.text(), 10) || 0; 1108 if (target.hasClass('hour_am') || target.hasClass('hour_pm')) { 1109 if (hours === 12 && target.hasClass('hour_am')) { 1110 hours = 0; 1111 } else if (hours !== 12 && target.hasClass('hour_pm')) { 1112 hours += 12; 1113 } 1114 } 1115 this.viewDate.setUTCHours(hours); 1116 this.element.trigger({ 1117 type: 'changeHour', 1118 date: this.viewDate 1119 }); 1120 if (this.viewSelect >= 1) { 1121 this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0)); 1122 } 1123 } else if (target.is('.minute')) { 1124 minutes = parseInt(target.text().substr(target.text().indexOf(':') + 1), 10) || 0; 1125 this.viewDate.setUTCMinutes(minutes); 1126 this.element.trigger({ 1127 type: 'changeMinute', 1128 date: this.viewDate 1129 }); 1130 if (this.viewSelect >= 0) { 1131 this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0)); 1132 } 1133 } 1134 if (this.viewMode !== 0) { 1135 var oldViewMode = this.viewMode; 1136 this.showMode(-1); 1137 this.fill(); 1138 if (oldViewMode === this.viewMode && this.autoclose) { 1139 this.hide(); 1140 } 1141 } else { 1142 this.fill(); 1143 if (this.autoclose) { 1144 this.hide(); 1145 } 1146 } 1147 } 1148 break; 1149 case 'td': 1150 if (target.is('.day') && !target.is('.disabled')) { 1151 var day = parseInt(target.text(), 10) || 1; 1152 var year = this.viewDate.getUTCFullYear(), 1153 month = this.viewDate.getUTCMonth(), 1154 hours = this.viewDate.getUTCHours(), 1155 minutes = this.viewDate.getUTCMinutes(), 1156 seconds = this.viewDate.getUTCSeconds(); 1157 if (target.is('.old')) { 1158 if (month === 0) { 1159 month = 11; 1160 year -= 1; 1161 } else { 1162 month -= 1; 1163 } 1164 } else if (target.is('.new')) { 1165 if (month === 11) { 1166 month = 0; 1167 year += 1; 1168 } else { 1169 month += 1; 1170 } 1171 } 1172 this.viewDate.setUTCFullYear(year); 1173 this.viewDate.setUTCMonth(month, day); 1174 this.element.trigger({ 1175 type: 'changeDay', 1176 date: this.viewDate 1177 }); 1178 if (this.viewSelect >= 2) { 1179 this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0)); 1180 } 1181 } 1182 var oldViewMode = this.viewMode; 1183 this.showMode(-1); 1184 this.fill(); 1185 if (oldViewMode === this.viewMode && this.autoclose) { 1186 this.hide(); 1187 } 1188 break; 1189 } 1190 } 1191 }, 1192 1193 _setDate: function (date, which) { 1194 if (!which || which === 'date') 1195 this.date = date; 1196 if (!which || which === 'view') 1197 this.viewDate = date; 1198 this.fill(); 1199 this.setValue(); 1200 var element; 1201 if (this.isInput) { 1202 element = this.element; 1203 } else if (this.component) { 1204 element = this.element.find('input'); 1205 } 1206 if (element) { 1207 element.change(); 1208 } 1209 this.element.trigger({ 1210 type: 'changeDate', 1211 date: this.getDate() 1212 }); 1213 if(date === null) 1214 this.date = this.viewDate; 1215 }, 1216 1217 moveMinute: function (date, dir) { 1218 if (!dir) return date; 1219 var new_date = new Date(date.valueOf()); 1220 //dir = dir > 0 ? 1 : -1; 1221 new_date.setUTCMinutes(new_date.getUTCMinutes() + (dir * this.minuteStep)); 1222 return new_date; 1223 }, 1224 1225 moveHour: function (date, dir) { 1226 if (!dir) return date; 1227 var new_date = new Date(date.valueOf()); 1228 //dir = dir > 0 ? 1 : -1; 1229 new_date.setUTCHours(new_date.getUTCHours() + dir); 1230 return new_date; 1231 }, 1232 1233 moveDate: function (date, dir) { 1234 if (!dir) return date; 1235 var new_date = new Date(date.valueOf()); 1236 //dir = dir > 0 ? 1 : -1; 1237 new_date.setUTCDate(new_date.getUTCDate() + dir); 1238 return new_date; 1239 }, 1240 1241 moveMonth: function (date, dir) { 1242 if (!dir) return date; 1243 var new_date = new Date(date.valueOf()), 1244 day = new_date.getUTCDate(),
1245 month = new_date.getUTCMonth(), 1246 mag = Math.abs(dir), 1247 new_month, test; 1248 dir = dir > 0 ? 1 : -1; 1249 if (mag === 1) { 1250 test = dir === -1 1251 // If going back one month, make sure month is not current month 1252 // (eg, Mar 31 -> Feb 31 === Feb 28, not Mar 02) 1253 ? function () { 1254 return new_date.getUTCMonth() === month; 1255 } 1256 // If going forward one month, make sure month is as expected 1257 // (eg, Jan 31 -> Feb 31 === Feb 28, not Mar 02) 1258 : function () { 1259 return new_date.getUTCMonth() !== new_month; 1260 }; 1261 new_month = month + dir; 1262 new_date.setUTCMonth(new_month); 1263 // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11 1264 if (new_month < 0 || new_month > 11) 1265 new_month = (new_month + 12) % 12; 1266 } else { 1267 // For magnitudes >1, move one month at a time... 1268 for (var i = 0; i < mag; i++) 1269 // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)... 1270 new_date = this.moveMonth(new_date, dir); 1271 // ...then reset the day, keeping it in the new month 1272 new_month = new_date.getUTCMonth(); 1273 new_date.setUTCDate(day); 1274 test = function () { 1275 return new_month !== new_date.getUTCMonth(); 1276 }; 1277 } 1278 // Common date-resetting loop -- if date is beyond end of month, make it 1279 // end of month 1280 while (test()) { 1281 new_date.setUTCDate(--day); 1282 new_date.setUTCMonth(new_month); 1283 } 1284 return new_date; 1285 }, 1286 1287 moveYear: function (date, dir) { 1288 return this.moveMonth(date, dir * 12); 1289 }, 1290 1291 dateWithinRange: function (date) { 1292 return date >= this.startDate && date <= this.endDate; 1293 }, 1294 1295 keydown: function (e) { 1296 if (this.picker.is(':not(:visible)')) { 1297 if (e.keyCode === 27) // allow escape to hide and re-show picker 1298 this.show(); 1299 return; 1300 } 1301 var dateChanged = false, 1302 dir, newDate, newViewDate; 1303 switch (e.keyCode) { 1304 case 27: // escape 1305 this.hide(); 1306 e.preventDefault(); 1307 break; 1308 case 37: // left 1309 case 39: // right 1310 if (!this.keyboardNavigation) break; 1311 dir = e.keyCode === 37 ? -1 : 1; 1312 var viewMode = this.viewMode; 1313 if (e.ctrlKey) { 1314 viewMode += 2; 1315 } else if (e.shiftKey) { 1316 viewMode += 1; 1317 } 1318 if (viewMode === 4) { 1319 newDate = this.moveYear(this.date, dir); 1320 newViewDate = this.moveYear(this.viewDate, dir); 1321 } else if (viewMode === 3) { 1322 newDate = this.moveMonth(this.date, dir); 1323 newViewDate = this.moveMonth(this.viewDate, dir); 1324 } else if (viewMode === 2) { 1325 newDate = this.moveDate(this.date, dir); 1326 newViewDate = this.moveDate(this.viewDate, dir); 1327 } else if (viewMode === 1) { 1328 newDate = this.moveHour(this.date, dir); 1329 newViewDate = this.moveHour(this.viewDate, dir); 1330 } else if (viewMode === 0) { 1331 newDate = this.moveMinute(this.date, dir); 1332 newViewDate = this.moveMinute(this.viewDate, dir); 1333 } 1334 if (this.dateWithinRange(newDate)) { 1335 this.date = newDate; 1336 this.viewDate = newViewDate; 1337 this.setValue(); 1338 this.update(); 1339 e.preventDefault(); 1340 dateChanged = true; 1341 } 1342 break; 1343 case 38: // up 1344 case 40: // down 1345 if (!this.keyboardNavigation) break; 1346 dir = e.keyCode === 38 ? -1 : 1; 1347 viewMode = this.viewMode; 1348 if (e.ctrlKey) { 1349 viewMode += 2; 1350 } else if (e.shiftKey) { 1351 viewMode += 1; 1352 } 1353 if (viewMode === 4) { 1354 newDate = this.moveYear(this.date, dir); 1355 newViewDate = this.moveYear(this.viewDate, dir); 1356 } else if (viewMode === 3) { 1357 newDate = this.moveMonth(this.date, dir); 1358 newViewDate = this.moveMonth(this.viewDate, dir); 1359 } else if (viewMode === 2) { 1360 newDate = this.moveDate(this.date, dir * 7); 1361 newViewDate = this.moveDate(this.viewDate, dir * 7); 1362 } else if (viewMode === 1) { 1363 if (this.showMeridian) { 1364 newDate = this.moveHour(this.date, dir * 6); 1365 newViewDate = this.moveHour(this.viewDate, dir * 6); 1366 } else { 1367 newDate = this.moveHour(this.date, dir * 4); 1368 newViewDate = this.moveHour(this.viewDate, dir * 4); 1369 } 1370 } else if (viewMode === 0) { 1371 newDate = this.moveMinute(this.date, dir * 4); 1372 newViewDate = this.moveMinute(this.viewDate, dir * 4); 1373 } 1374 if (this.dateWithinRange(newDate)) { 1375 this.date = newDate; 1376 this.viewDate = newViewDate; 1377 this.setValue(); 1378 this.update(); 1379 e.preventDefault(); 1380 dateChanged = true; 1381 } 1382 break; 1383 case 13: // enter 1384 if (this.viewMode !== 0) { 1385 var oldViewMode = this.viewMode; 1386 this.showMode(-1); 1387 this.fill(); 1388 if (oldViewMode === this.viewMode && this.autoclose) { 1389 this.hide(); 1390 } 1391 } else { 1392 this.fill(); 1393 if (this.autoclose) { 1394 this.hide(); 1395 } 1396 } 1397 e.preventDefault(); 1398 break; 1399 case 9: // tab 1400 this.hide(); 1401 break; 1402 } 1403 if (dateChanged) { 1404 var element; 1405 if (this.isInput) { 1406 element = this.element; 1407 } else if (this.component) { 1408 element = this.element.find('input'); 1409 } 1410 if (element) { 1411 element.change(); 1412 } 1413 this.element.trigger({ 1414 type: 'changeDate', 1415 date: this.getDate() 1416 }); 1417 } 1418 }, 1419 1420 showMode: function (dir) { 1421 if (dir) { 1422 var newViewMode = Math.max(0, Math.min(DPGlobal.modes.length - 1, this.viewMode + dir)); 1423 if (newViewMode >= this.minView && newViewMode <= this.maxView) { 1424 this.element.trigger({ 1425 type: 'changeMode', 1426 date: this.viewDate, 1427 oldViewMode: this.viewMode, 1428 newViewMode: newViewMode 1429 }); 1430 1431 this.viewMode = newViewMode; 1432 } 1433 } 1434 /* 1435 vitalets: fixing bug of very special conditions: 1436 jquery 1.7.1 + webkit + show inline datetimepicker in bootstrap popover. 1437 Method show() does not set display css correctly and datetimepicker is not shown. 1438 Changed to .css('display', 'block') solve the problem. 1439 See https://github.com/vitalets/x-editable/issues/37 1440 1441 In jquery 1.7.2+ everything works fine. 1442 */ 1443 //this.picker.find('>div').hide().filter('.datetimepicker-'+DPGlobal.modes[this.viewMode].clsName).show(); 1444 this.picker.find('>div').hide().filter('.datetimepicker-' + DPGlobal.modes[this.viewMode].clsName).css('display', 'block'); 1445 this.updateNavArrows(); 1446 }, 1447 1448 reset: function () { 1449 this._setDate(null, 'date'); 1450 }, 1451 1452 convertViewModeText: function (viewMode) { 1453 switch (viewMode) { 1454 case 4: 1455 return 'decade'; 1456 case 3: 1457 return 'year'; 1458 case 2: 1459 return 'month'; 1460 case 1: 1461 return 'day'; 1462 case 0: 1463 return 'hour'; 1464 } 1465 } 1466 }; 1467 1468 var old = $.fn.datetimepicker; 1469 $.fn.datetimepicker = function (option) { 1470 var args = Array.apply(null, arguments); 1471 args.shift(); 1472 var internal_return; 1473 this.each(function () { 1474 var $this = $(this), 1475 data = $this.data('datetimepicker'), 1476 options = typeof option === 'object' && option; 1477 if (!data) { 1478 $this.data('datetimepicker', (data = new Datetimepicker(this, $.extend({}, $.fn.datetimepicker.defaults, options)))); 1479 } 1480 if (typeof option === 'string' && typeof data[option] === 'function') { 1481 internal_return = data[option].apply(data, args); 1482 if (internal_return !== undefined) { 1483 return false;
1484 } 1485 } 1486 }); 1487 if (internal_return !== undefined) 1488 return internal_return; 1489 else 1490 return this; 1491 }; 1492 1493 $.fn.datetimepicker.defaults = { 1494 }; 1495 $.fn.datetimepicker.Constructor = Datetimepicker; 1496 var dates = $.fn.datetimepicker.dates = { 1497 en: { 1498 days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], 1499 daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], 1500 daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'], 1501 months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], 1502 monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 1503 meridiem: ['am', 'pm'], 1504 suffix: ['st', 'nd', 'rd', 'th'], 1505 today: 'Today', 1506 clear: 'Clear' 1507 } 1508 }; 1509 1510 var DPGlobal = { 1511 modes: [ 1512 { 1513 clsName: 'minutes', 1514 navFnc: 'Hours', 1515 navStep: 1 1516 }, 1517 { 1518 clsName: 'hours', 1519 navFnc: 'Date', 1520 navStep: 1 1521 }, 1522 { 1523 clsName: 'days', 1524 navFnc: 'Month', 1525 navStep: 1 1526 }, 1527 { 1528 clsName: 'months', 1529 navFnc: 'FullYear', 1530 navStep: 1 1531 }, 1532 { 1533 clsName: 'years', 1534 navFnc: 'FullYear', 1535 navStep: 10 1536 } 1537 ], 1538 isLeapYear: function (year) { 1539 return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) 1540 }, 1541 getDaysInMonth: function (year, month) { 1542 return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month] 1543 }, 1544 getDefaultFormat: function (type, field) { 1545 if (type === 'standard') { 1546 if (field === 'input') 1547 return 'yyyy-mm-dd hh:ii'; 1548 else 1549 return 'yyyy-mm-dd hh:ii:ss'; 1550 } else if (type === 'php') { 1551 if (field === 'input') 1552 return 'Y-m-d H:i'; 1553 else 1554 return 'Y-m-d H:i:s'; 1555 } else { 1556 throw new Error('Invalid format type.'); 1557 } 1558 }, 1559 validParts: function (type) { 1560 if (type === 'standard') { 1561 return /t|hh?|HH?|p|P|z|Z|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g; 1562 } else if (type === 'php') { 1563 return /[dDjlNwzFmMnStyYaABgGhHis]/g; 1564 } else { 1565 throw new Error('Invalid format type.'); 1566 } 1567 }, 1568 nonpunctuation: /[^ -\/:-@\[-`{-~\t\n\rTZ]+/g, 1569 parseFormat: function (format, type) { 1570 // IE treats \0 as a string end in inputs (truncating the value), 1571 // so it's a bad format delimiter, anyway 1572 var separators = format.replace(this.validParts(type), '\0').split('\0'), 1573 parts = format.match(this.validParts(type)); 1574 if (!separators || !separators.length || !parts || parts.length === 0) { 1575 throw new Error('Invalid date format.'); 1576 } 1577 return {separators: separators, parts: parts}; 1578 }, 1579 parseDate: function (date, format, language, type, timezone) { 1580 if (date instanceof Date) { 1581 var dateUTC = new Date(date.valueOf() - date.getTimezoneOffset() * 60000); 1582 dateUTC.setMilliseconds(0); 1583 return dateUTC; 1584 } 1585 if (/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(date)) { 1586 format = this.parseFormat('yyyy-mm-dd', type); 1587 } 1588 if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}$/.test(date)) { 1589 format = this.parseFormat('yyyy-mm-dd hh:ii', type); 1590 } 1591 if (/^\d{4}\-\d{1,2}\-\d{1,2}[T ]\d{1,2}\:\d{1,2}\:\d{1,2}[Z]{0,1}$/.test(date)) { 1592 format = this.parseFormat('yyyy-mm-dd hh:ii:ss', type); 1593 } 1594 if (/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(date)) { 1595 var part_re = /([-+]\d+)([dmwy])/, 1596 parts = date.match(/([-+]\d+)([dmwy])/g), 1597 part, dir; 1598 date = new Date(); 1599 for (var i = 0; i < parts.length; i++) { 1600 part = part_re.exec(parts[i]); 1601 dir = parseInt(part[1]); 1602 switch (part[2]) { 1603 case 'd': 1604 date.setUTCDate(date.getUTCDate() + dir); 1605 break; 1606 case 'm': 1607 date = Datetimepicker.prototype.moveMonth.call(Datetimepicker.prototype, date, dir); 1608 break; 1609 case 'w': 1610 date.setUTCDate(date.getUTCDate() + dir * 7); 1611 break; 1612 case 'y': 1613 date = Datetimepicker.prototype.moveYear.call(Datetimepicker.prototype, date, dir); 1614 break; 1615 } 1616 } 1617 return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), 0); 1618 } 1619 var parts = date && date.toString().match(this.nonpunctuation) || [], 1620 date = new Date(0, 0, 0, 0, 0, 0, 0), 1621 parsed = {}, 1622 setters_order = ['hh', 'h', 'ii', 'i', 'ss', 's', 'yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'D', 'DD', 'd', 'dd', 'H', 'HH', 'p', 'P', 'z', 'Z'], 1623 setters_map = { 1624 hh: function (d, v) { 1625 return d.setUTCHours(v); 1626 }, 1627 h: function (d, v) { 1628 return d.setUTCHours(v); 1629 }, 1630 HH: function (d, v) { 1631 return d.setUTCHours(v === 12 ? 0 : v); 1632 }, 1633 H: function (d, v) { 1634 return d.setUTCHours(v === 12 ? 0 : v); 1635 }, 1636 ii: function (d, v) { 1637 return d.setUTCMinutes(v); 1638 }, 1639 i: function (d, v) { 1640 return d.setUTCMinutes(v); 1641 }, 1642 ss: function (d, v) { 1643 return d.setUTCSeconds(v); 1644 }, 1645 s: function (d, v) { 1646 return d.setUTCSeconds(v); 1647 }, 1648 yyyy: function (d, v) { 1649 return d.setUTCFullYear(v); 1650 }, 1651 yy: function (d, v) { 1652 return d.setUTCFullYear(2000 + v); 1653 }, 1654 m: function (d, v) { 1655 v -= 1; 1656 while (v < 0) v += 12; 1657 v %= 12; 1658 d.setUTCMonth(v); 1659 while (d.getUTCMonth() !== v) 1660 if (isNaN(d.getUTCMonth())) 1661 return d; 1662 else 1663 d.setUTCDate(d.getUTCDate() - 1); 1664 return d; 1665 }, 1666 d: function (d, v) { 1667 return d.setUTCDate(v); 1668 }, 1669 p: function (d, v) { 1670 return d.setUTCHours(v === 1 ? d.getUTCHours() + 12 : d.getUTCHours()); 1671 }, 1672 z: function () { 1673 return timezone 1674 } 1675 }, 1676 val, filtered, part; 1677 setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m']; 1678 setters_map['dd'] = setters_map['d']; 1679 setters_map['P'] = setters_map['p']; 1680 setters_map['Z'] = setters_map['z']; 1681 date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()); 1682 if (parts.length === format.parts.length) { 1683 for (var i = 0, cnt = format.parts.length; i < cnt; i++) { 1684 val = parseInt(parts[i], 10); 1685 part = format.parts[i]; 1686 if (isNaN(val)) { 1687 switch (part) { 1688 case 'MM': 1689 filtered = $(dates[language].months).filter(function () { 1690 var m = this.slice(0, parts[i].length), 1691 p = parts[i].slice(0, m.length); 1692 return m === p; 1693 }); 1694 val = $.inArray(filtered[0], dates[language].months) + 1; 1695 break; 1696 case 'M': 1697 filtered = $(dates[language].monthsShort).filter(function () { 1698 var m = this.slice(0, parts[i].length), 1699 p = parts[i].slice(0, m.length); 1700 return m.toLowerCase() === p.toLowerCase(); 1701 }); 1702 val = $.inArray(filtered[0], dates[language].monthsShort) + 1; 1703 break; 1704 case 'p': 1705 case 'P': 1706 val = $.inArray(parts[i].toLowerCase(), dates[language].meridiem); 1707 break; 1708 case 'z': 1709 case 'Z': 1710 timezone; 1711 break; 1712 1713 } 1714 } 1715 parsed[part] = val; 1716 } 1717 for (var i = 0, s; i < setters_order.length; i++) { 1718 s = setters_order[i]; 1719 if (s in parsed && !isNaN(parsed[s])) 1720 setters_map[s](date, parsed[s]) 1721 } 1722 } 1723 return date; 1724 }, 1725 formatDate: function (date, format, language, type, timezone) { 1726 if (date === null) { 1727 return ''; 1728 } 1729 var val; 1730 if (type === 'standard') { 1731 val = { 1732 t: date.getTime(), 1733 // year 1734 yy: date.getUTCFullYear().toString().substring(2), 1735 yyyy: date.getUTCFullYear(), 1736 // month 1737 m: date.getUTCMonth() + 1, 1738 M: dates[language].monthsShort[date.getUTCMonth()], 1739 MM: dates[language].months[date.getUTCMonth()], 1740 // day 1741 d: date.getUTCDate(), 1742 D: dates[language].daysShort[date.getUTCDay()], 1743 DD: dates[language].days[date.getUTCDay()], 1744 p: (dates[language].meridiem.length === 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''), 1745 // hour 1746 h: date.getUTCHours(), 1747 // minute 1748 i: date.getUTCMinutes(), 1749 // second 1750 s: date.getUTCSeconds(), 1751 // timezone 1752 z: timezone 1753 }; 1754 1755 if (dates[language].meridiem.length === 2) { 1756 val.H = (val.h % 12 === 0 ? 12 : val.h % 12); 1757 } 1758 else { 1759 val.H = val.h; 1760 } 1761 val.HH = (val.H < 10 ? '0' : '') + val.H; 1762 val.P = val.p.toUpperCase(); 1763 val.Z = val.z; 1764 val.hh = (val.h < 10 ? '0' : '') + val.h; 1765 val.ii = (val.i < 10 ? '0' : '') + val.i; 1766 val.ss = (val.s < 10 ? '0' : '') + val.s; 1767 val.dd = (val.d < 10 ? '0' : '') + val.d; 1768 val.mm = (val.m < 10 ? '0' : '') + val.m; 1769 } else if (type === 'php') { 1770 // php format 1771 val = { 1772 // year 1773 y: date.getUTCFullYear().toString().substring(2), 1774 Y: date.getUTCFullYear(), 1775 // month 1776 F: dates[language].months[date.getUTCMonth()], 1777 M: dates[language].monthsShort[date.getUTCMonth()], 1778 n: date.getUTCMonth() + 1, 1779 t: DPGlobal.getDaysInMonth(date.getUTCFullYear(), date.getUTCMonth()), 1780 // day 1781 j: date.getUTCDate(), 1782 l: dates[language].days[date.getUTCDay()], 1783 D: dates[language].daysShort[date.getUTCDay()], 1784 w: date.getUTCDay(), // 0 -> 6 1785 N: (date.getUTCDay() === 0 ? 7 : date.getUTCDay()), // 1 -> 7 1786 S: (date.getUTCDate() % 10 <= dates[language].suffix.length ? dates[language].suffix[date.getUTCDate() % 10 - 1] : ''), 1787 // hour 1788 a: (dates[language].meridiem.length === 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''), 1789 g: (date.getUTCHours() % 12 === 0 ? 12 : date.getUTCHours() % 12), 1790 G: date.getUTCHours(), 1791 // minute 1792 i: date.getUTCMinutes(), 1793 // second 1794 s: date.getUTCSeconds() 1795 }; 1796 val.m = (val.n < 10 ? '0' : '') + val.n; 1797 val.d = (val.j < 10 ? '0' : '') + val.j; 1798 val.A = val.a.toString().toUpperCase(); 1799 val.h = (val.g < 10 ? '0' : '') + val.g; 1800 val.H = (val.G < 10 ? '0' : '') + val.G; 1801 val.i = (val.i < 10 ? '0' : '') + val.i; 1802 val.s = (val.s < 10 ? '0' : '') + val.s; 1803 } else { 1804 throw new Error('Invalid format type.'); 1805 } 1806 var date = [], 1807 seps = $.extend([], format.separators); 1808 for (var i = 0, cnt = format.parts.length; i < cnt; i++) { 1809 if (seps.length) { 1810 date.push(seps.shift()); 1811 } 1812 date.push(val[format.parts[i]]); 1813 } 1814 if (seps.length) { 1815 date.push(seps.shift()); 1816 } 1817 return date.join(''); 1818 }, 1819 convertViewMode: function (viewMode) { 1820 switch (viewMode) { 1821 case 4: 1822 case 'decade': 1823 viewMode = 4; 1824 break; 1825 case 3: 1826 case 'year': 1827 viewMode = 3; 1828 break; 1829 case 2: 1830 case 'month': 1831 viewMode = 2; 1832 break; 1833 case 1: 1834 case 'day': 1835 viewMode = 1; 1836 break; 1837 case 0: 1838 case 'hour': 1839 viewMode = 0; 1840 break; 1841 } 1842 1843 return viewMode; 1844 }, 1845 headTemplate: '<thead>' + 1846 '<tr>' + 1847 '<th class="prev"><i class="{iconType} {leftArrow}"/></th>' + 1848 '<th colspan="5" class="switch"></th>' + 1849 '<th class="next"><i class="{iconType} {rightArrow}"/></th>' + 1850 '</tr>' + 1851 '</thead>', 1852 headTemplateV3: '<thead>' + 1853 '<tr>' + 1854 '<th class="prev"><span class="{iconType} {leftArrow}"></span> </th>' + 1855 '<th colspan="5" class="switch"></th>' + 1856 '<th class="next"><span class="{iconType} {rightArrow}"></span> </th>' + 1857 '</tr>' + 1858 '</thead>', 1859 contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>', 1860 footTemplate: '<tfoot>' + 1861 '<tr><th colspan="7" class="today"></th></tr>' + 1862 '<tr><th colspan="7" class="clear"></th></tr>' + 1863 '</tfoot>' 1864 }; 1865 DPGlobal.template = '<div class="datetimepicker">' + 1866 '<div class="datetimepicker-minutes">' + 1867 '<table class=" table-condensed">' + 1868 DPGlobal.headTemplate + 1869 DPGlobal.contTemplate + 1870 DPGlobal.footTemplate + 1871 '</table>' + 1872 '</div>' + 1873 '<div class="datetimepicker-hours">' + 1874 '<table class=" table-condensed">' + 1875 DPGlobal.headTemplate + 1876 DPGlobal.contTemplate + 1877 DPGlobal.footTemplate + 1878 '</table>' + 1879 '</div>' + 1880 '<div class="datetimepicker-days">' + 1881 '<table class=" table-condensed">' + 1882 DPGlobal.headTemplate + 1883 '<tbody></tbody>' + 1884 DPGlobal.footTemplate + 1885 '</table>' + 1886 '</div>' + 1887 '<div class="datetimepicker-months">' + 1888 '<table class="table-condensed">' + 1889 DPGlobal.headTemplate + 1890 DPGlobal.contTemplate + 1891 DPGlobal.footTemplate + 1892 '</table>' + 1893 '</div>' + 1894 '<div class="datetimepicker-years">' + 1895 '<table class="table-condensed">' + 1896 DPGlobal.headTemplate + 1897 DPGlobal.contTemplate + 1898 DPGlobal.footTemplate + 1899 '</table>' + 1900 '</div>' + 1901 '</div>'; 1902 DPGlobal.templateV3 = '<div class="datetimepicker">' + 1903 '<div class="datetimepicker-minutes">' + 1904 '<table class=" table-condensed">' + 1905 DPGlobal.headTemplateV3 + 1906 DPGlobal.contTemplate + 1907 DPGlobal.footTemplate + 1908 '</table>' + 1909 '</div>' + 1910 '<div class="datetimepicker-hours">' + 1911 '<table class=" table-condensed">' + 1912 DPGlobal.headTemplateV3 + 1913 DPGlobal.contTemplate + 1914 DPGlobal.footTemplate + 1915 '</table>' + 1916 '</div>' + 1917 '<div class="datetimepicker-days">' + 1918 '<table class=" table-condensed">' + 1919 DPGlobal.headTemplateV3 + 1920 '<tbody></tbody>' + 1921 DPGlobal.footTemplate + 1922 '</table>' + 1923 '</div>' + 1924 '<div class="datetimepicker-months">' + 1925 '<table class="table-condensed">' + 1926 DPGlobal.headTemplateV3 + 1927 DPGlobal.contTemplate + 1928 DPGlobal.footTemplate + 1929 '</table>' + 1930 '</div>' + 1931 '<div class="datetimepicker-years">' + 1932 '<table class="table-condensed">' + 1933 DPGlobal.headTemplateV3 + 1934 DPGlobal.contTemplate + 1935 DPGlobal.footTemplate + 1936 '</table>' + 1937 '</div>' + 1938 '</div>'; 1939 $.fn.datetimepicker.DPGlobal = DPGlobal; 1940 1941 /* DATETIMEPICKER NO CONFLICT 1942 * =================== */ 1943 1944 $.fn.datetimepicker.noConflict = function () { 1945 $.fn.datetimepicker = old; 1946 return this; 1947 }; 1948 1949 /* DATETIMEPICKER DATA-API 1950 * ================== */ 1951 1952 $(document).on(
1953 'focus.datetimepicker.data-api click.datetimepicker.data-api', 1954 '[data-provide="datetimepicker"]', 1955 function (e) { 1956 var $this = $(this); 1957 if ($this.data('datetimepicker')) return; 1958 e.preventDefault(); 1959 // component click requires us to explicitly show it 1960 $this.datetimepicker('show'); 1961 } 1962 ); 1963 $(function () { 1964 $('[data-provide="datetimepicker-inline"]').datetimepicker(); 1965 }); 1966 1967}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.