vendor: 6,003 bytes, lines 1-215
1/* 2 * jQuery timepicker addon 3 * By: Trent Richardson [http://trentrichardson.com] 4 * Version 1.1.0 5 * Last Modified: 11/03/2012 6 * 7 * Copyright 2012 Trent Richardson 8 * You may use this project under MIT or GPL licenses. 9 * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt 10 * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt 11 */ 12 13/*jslint evil: true, white: false, undef: false, nomen: false */ 14 15(function($) { 16 17 /* 18 * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded" 19 */ 20 $.ui.timepicker = $.ui.timepicker || {}; 21 if ($.ui.timepicker.version) { 22 return; 23 } 24 25 /* 26 * Extend jQueryUI, get it started with our version number 27 */ 28 $.extend($.ui, { 29 timepicker: { 30 version: "1.1.0" 31 } 32 }); 33 34 /* 35 * Timepicker manager. 36 * Use the singleton instance of this class, $.timepicker, to interact with the time picker. 37 * Settings for (groups of) time pickers are maintained in an instance object, 38 * allowing multiple different settings on the same page. 39 */ 40 function Timepicker() { 41 this.regional = []; // Available regional settings, indexed by language code 42 this.regional[''] = { // Default regional settings 43 currentText: 'Now', 44 closeText: 'Done', 45 amNames: ['AM', 'A'], 46 pmNames: ['PM', 'P'], 47 timeFormat: 'HH:mm', 48 timeSuffix: '', 49 timeOnlyTitle: 'Choose Time', 50 timeText: 'Time', 51 hourText: 'Hour', 52 minuteText: 'Minute', 53 secondText: 'Second', 54 millisecText: 'Millisecond', 55 timezoneText: 'Time Zone', 56 isRTL: false 57 }; 58 this._defaults = { // Global defaults for all the datetime picker instances 59 showButtonPanel: true, 60 timeOnly: false, 61 showHour: true, 62 showMinute: true, 63 showSecond: false, 64 showMillisec: false, 65 showTimezone: false, 66 showTime: true, 67 stepHour: 1, 68 stepMinute: 1, 69 stepSecond: 1, 70 stepMillisec: 1, 71 hour: 0, 72 minute: 0, 73 second: 0, 74 millisec: 0, 75 timezone: null, 76 useLocalTimezone: false, 77 defaultTimezone: "+0000", 78 hourMin: 0, 79 minuteMin: 0, 80 secondMin: 0, 81 millisecMin: 0, 82 hourMax: 23, 83 minuteMax: 59, 84 secondMax: 59, 85 millisecMax: 999, 86 minDateTime: null, 87 maxDateTime: null, 88 onSelect: null, 89 hourGrid: 0, 90 minuteGrid: 0, 91 secondGrid: 0, 92 millisecGrid: 0, 93 alwaysSetTime: true, 94 separator: ' ', 95 altFieldTimeOnly: true, 96 altTimeFormat: null, 97 altSeparator: null, 98 altTimeSuffix: null, 99 pickerTimeFormat: null, 100 pickerTimeSuffix: null, 101 showTimepicker: true, 102 timezoneIso8601: false, 103 timezoneList: null, 104 addSliderAccess: false, 105 sliderAccessArgs: null, 106 controlType: 'slider', 107 defaultValue: null, 108 parse: 'strict' 109 }; 110 $.extend(this._defaults, this.regional['']); 111 } 112 113 $.extend(Timepicker.prototype, { 114 $input: null, 115 $altInput: null, 116 $timeObj: null, 117 inst: null, 118 hour_slider: null, 119 minute_slider: null, 120 second_slider: null, 121 millisec_slider: null, 122 timezone_select: null, 123 hour: 0, 124 minute: 0, 125 second: 0, 126 millisec: 0, 127 timezone: null, 128 defaultTimezone: "+0000", 129 hourMinOriginal: null, 130 minuteMinOriginal: null, 131 secondMinOriginal: null, 132 millisecMinOriginal: null, 133 hourMaxOriginal: null, 134 minuteMaxOriginal: null, 135 secondMaxOriginal: null, 136 millisecMaxOriginal: null, 137 ampm: '', 138 formattedDate: '', 139 formattedTime: '', 140 formattedDateTime: '', 141 timezoneList: null, 142 units: ['hour','minute','second','millisec'], 143 control: null, 144 145 /* 146 * Override the default settings for all instances of the time picker. 147 * @param settings object - the new settings to use as defaults (anonymous object) 148 * @return the manager object 149 */ 150 setDefaults: function(settings) { 151 extendRemove(this._defaults, settings || {}); 152 return this; 153 }, 154 155 /* 156 * Create a new Timepicker instance 157 */ 158 _newInst: function($input, o) { 159 var tp_inst = new Timepicker(), 160 inlineSettings = {}, 161 fns = {}, 162 overrides, i; 163 164 for (var attrName in this._defaults) { 165 if(this._defaults.hasOwnProperty(attrName)){ 166 var attrValue = $input.attr('time:' + attrName); 167 if (attrValue) { 168 try { 169 inlineSettings[attrName] = eval(attrValue); 170 } catch (err) { 171 inlineSettings[attrName] = attrValue; 172 } 173 } 174 } 175 } 176 overrides = { 177 beforeShow: function (input, dp_inst) { 178 if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) { 179 return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst); 180 } 181 }, 182 onChangeMonthYear: function (year, month, dp_inst) { 183 // Update the time as well : this prevents the time from disappearing from the $input field. 184 tp_inst._updateDateTime(dp_inst); 185 if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) { 186 tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); 187 } 188 }, 189 onClose: function (dateText, dp_inst) { 190 if (tp_inst.timeDefined === true && $input.val() !== '') { 191 tp_inst._updateDateTime(dp_inst); 192 } 193 if ($.isFunction(tp_inst._defaults.evnts.onClose)) { 194 tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst); 195 } 196 } 197 }; 198 for (i in overrides) { 199 if (overrides.hasOwnProperty(i)) { 200 fns[i] = o[i] || null; 201 } 202 } 203 tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, overrides, { 204 evnts:fns, 205 timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); 206 }); 207 tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { 208 return val.toUpperCase(); 209 }); 210 tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { 211 return val.toUpperCase(); 212 }); 213 214 // controlType is string - key to our this._controls 215 if(typeof(tp_inst._defaults.controlType) === 'string'){
216 if($.fn[tp_inst._defaults.controlType] === undefined){ 217 tp_inst._defaults.controlType = 'select'; 218 } 219 tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType]; 220 } 221 // controlType is an object and must implement create, options, value methods 222 else{ 223 tp_inst.control = tp_inst._defaults.controlType; 224 } 225 226 if (tp_inst._defaults.timezoneList === null) { 227 var timezoneList = ['-1200', '-1100', '-1000', '-0930', '-0900', '-0800', '-0700', '-0600', '-0500', '-0430', '-0400', '-0330', '-0300', '-0200', '-0100', '+0000', 228 '+0100', '+0200', '+0300', '+0330', '+0400', '+0430', '+0500', '+0530', '+0545', '+0600', '+0630', '+0700', '+0800', '+0845', '+0900', '+0930', 229 '+1000', '+1030', '+1100', '+1130', '+1200', '+1245', '+1300', '+1400']; 230 231 if (tp_inst._defaults.timezoneIso8601) { 232 timezoneList = $.map(timezoneList, function(val) { 233 return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3)); 234 }); 235 } 236 tp_inst._defaults.timezoneList = timezoneList; 237 } 238 239 tp_inst.timezone = tp_inst._defaults.timezone; 240 tp_inst.hour = tp_inst._defaults.hour; 241 tp_inst.minute = tp_inst._defaults.minute; 242 tp_inst.second = tp_inst._defaults.second; 243 tp_inst.millisec = tp_inst._defaults.millisec; 244 tp_inst.ampm = ''; 245 tp_inst.$input = $input; 246 247 if (o.altField) { 248 tp_inst.$altInput = $(o.altField).css({ 249 cursor: 'pointer' 250 }).focus(function() { 251 $input.trigger("focus"); 252 }); 253 } 254 255 if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) { 256 tp_inst._defaults.minDate = new Date(); 257 } 258 if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) { 259 tp_inst._defaults.maxDate = new Date(); 260 } 261 262 // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. 263 if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) { 264 tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); 265 } 266 if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) { 267 tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); 268 } 269 if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) { 270 tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); 271 } 272 if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) { 273 tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); 274 } 275 tp_inst.$input.bind('focus', function() { 276 tp_inst._onFocus(); 277 }); 278 279 return tp_inst; 280 }, 281 282 /* 283 * add our sliders to the calendar 284 */ 285 _addTimePicker: function(dp_inst) { 286 var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val(); 287 288 this.timeDefined = this._parseTime(currDT); 289 this._limitMinMaxDateTime(dp_inst, false); 290 this._injectTimePicker(); 291 }, 292 293 /* 294 * parse the time string from input value or _setTime 295 */ 296 _parseTime: function(timeString, withDate) { 297 if (!this.inst) { 298 this.inst = $.datepicker._getInst(this.$input[0]); 299 } 300 301 if (withDate || !this._defaults.timeOnly) { 302 var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');
vendor: 14,783 bytes, lines 303-657
303 try { 304 var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults); 305 if (!parseRes.timeObj) { 306 return false; 307 } 308 $.extend(this, parseRes.timeObj); 309 } catch (err) { 310 $.datepicker.log("Error parsing the date/time string: " + err + 311 "\ndate/time string = " + timeString + 312 "\ntimeFormat = " + this._defaults.timeFormat + 313 "\ndateFormat = " + dp_dateFormat); 314 return false; 315 } 316 return true; 317 } else { 318 var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults); 319 if (!timeObj) { 320 return false; 321 } 322 $.extend(this, timeObj); 323 return true; 324 } 325 }, 326 327 /* 328 * generate and inject html for timepicker into ui datepicker 329 */ 330 _injectTimePicker: function() { 331 var $dp = this.inst.dpDiv, 332 o = this.inst.settings, 333 tp_inst = this, 334 litem = '', 335 uitem = '', 336 max = {}, 337 gridSize = {}, 338 size = null; 339 340 // Prevent displaying twice 341 if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) { 342 var noDisplay = ' style="display:none;"', 343 html = '<div class="ui-timepicker-div'+ (o.isRTL? ' ui-timepicker-rtl' : '') +'"><dl>' + '<dt class="ui_tpicker_time_label"' + ((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' + 344 '<dd class="ui_tpicker_time"' + ((o.showTime) ? '' : noDisplay) + '></dd>'; 345 346 // Create the markup 347 for(var i=0,l=this.units.length; i<l; i++){ 348 litem = this.units[i]; 349 uitem = litem.substr(0,1).toUpperCase() + litem.substr(1); 350 // Added by Peter Medeiros: 351 // - Figure out what the hour/minute/second max should be based on the step values. 352 // - Example: if stepMinute is 15, then minMax is 45. 353 max[litem] = parseInt((o[litem+'Max'] - ((o[litem+'Max'] - o[litem+'Min']) % o['step'+uitem])), 10); 354 gridSize[litem] = 0; 355 356 html += '<dt class="ui_tpicker_'+ litem +'_label"' + ((o['show'+uitem]) ? '' : noDisplay) + '>' + o[litem +'Text'] + '</dt>' + 357 '<dd class="ui_tpicker_'+ litem +'"><div class="ui_tpicker_'+ litem +'_slider"' + ((o['show'+uitem]) ? '' : noDisplay) + '></div>'; 358 359 if (o['show'+uitem] && o[litem+'Grid'] > 0) { 360 html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>'; 361 362 if(litem == 'hour'){ 363 for (var h = o[litem+'Min']; h <= max[litem]; h += parseInt(o[litem+'Grid'], 10)) { 364 gridSize[litem]++; 365 var tmph = $.datepicker.formatTime(useAmpm(o.pickerTimeFormat || o.timeFormat)? 'hht':'HH', {hour:h}, o); 366 html += '<td data-for="'+litem+'">' + tmph + '</td>'; 367 } 368 } 369 else{ 370 for (var m = o[litem+'Min']; m <= max[litem]; m += parseInt(o[litem+'Grid'], 10)) { 371 gridSize[litem]++; 372 html += '<td data-for="'+litem+'">' + ((m < 10) ? '0' : '') + m + '</td>'; 373 } 374 } 375 376 html += '</tr></table></div>'; 377 } 378 html += '</dd>'; 379 } 380 381 // Timezone 382 html += '<dt class="ui_tpicker_timezone_label"' + ((o.showTimezone) ? '' : noDisplay) + '>' + o.timezoneText + '</dt>'; 383 html += '<dd class="ui_tpicker_timezone" ' + ((o.showTimezone) ? '' : noDisplay) + '></dd>'; 384 385 // Create the elements from string 386 html += '</dl></div>'; 387 var $tp = $(html); 388 389 // if we only want time picker... 390 if (o.timeOnly === true) { 391 $tp.prepend('<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + '</div>'); 392 $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); 393 } 394 395 // add sliders, adjust grids, add events 396 for(var i=0,l=tp_inst.units.length; i<l; i++){ 397 litem = tp_inst.units[i]; 398 uitem = litem.substr(0,1).toUpperCase() + litem.substr(1); 399 400 // add the slider 401 tp_inst[litem+'_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_'+litem+'_slider'), litem, tp_inst[litem], o[litem+'Min'], max[litem], o['step'+uitem]); 402 403 // adjust the grid and add click event 404 if (o['show'+uitem] && o[litem+'Grid'] > 0) { 405 size = 100 * gridSize[litem] * o[litem+'Grid'] / (max[litem] - o[litem+'Min']); 406 $tp.find('.ui_tpicker_'+litem+' table').css({ 407 width: size + "%", 408 marginLeft: o.isRTL? '0' : ((size / (-2 * gridSize[litem])) + "%"), 409 marginRight: o.isRTL? ((size / (-2 * gridSize[litem])) + "%") : '0', 410 borderCollapse: 'collapse' 411 }).find("td").click(function(e){ 412 var $t = $(this), 413 h = $t.html(), 414 n = parseInt(h.replace(/[^0-9]/g),10), 415 ap = h.replace(/[^apm]/ig), 416 f = $t.data('for'); // loses scope, so we use data-for 417 418 if(f == 'hour'){ 419 if(ap.indexOf('p') !== -1 && n < 12){ 420 n += 12; 421 } 422 else{ 423 if(ap.indexOf('a') !== -1 && n === 12){ 424 n = 0; 425 } 426 } 427 } 428 429 tp_inst.control.value(tp_inst, tp_inst[f+'_slider'], litem, n); 430 431 tp_inst._onTimeChange(); 432 tp_inst._onSelectHandler(); 433 }) 434 .css({ 435 cursor: 'pointer', 436 width: (100 / gridSize[litem]) + '%', 437 textAlign: 'center', 438 overflow: 'hidden' 439 }); 440 } // end if grid > 0 441 } // end for loop 442 443 // Add timezone options 444 this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find("select"); 445 $.fn.append.apply(this.timezone_select, 446 $.map(o.timezoneList, function(val, idx) { 447 return $("<option />").val(typeof val == "object" ? val.value : val).text(typeof val == "object" ? val.label : val); 448 })); 449 if (typeof(this.timezone) != "undefined" && this.timezone !== null && this.timezone !== "") { 450 var local_date = new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12); 451 var local_timezone = $.timepicker.timeZoneOffsetString(local_date); 452 if (local_timezone == this.timezone) { 453 selectLocalTimeZone(tp_inst); 454 } else { 455 this.timezone_select.val(this.timezone); 456 } 457 } else { 458 if (typeof(this.hour) != "undefined" && this.hour !== null && this.hour !== "") { 459 this.timezone_select.val(o.defaultTimezone); 460 } else { 461 selectLocalTimeZone(tp_inst); 462 } 463 } 464 this.timezone_select.change(function() { 465 tp_inst._defaults.useLocalTimezone = false; 466 tp_inst._onTimeChange(); 467 }); 468 // End timezone options 469 470 // inject timepicker into datepicker 471 var $buttonPanel = $dp.find('.ui-datepicker-buttonpane'); 472 if ($buttonPanel.length) { 473 $buttonPanel.before($tp); 474 } else { 475 $dp.append($tp); 476 } 477 478 this.$timeObj = $tp.find('.ui_tpicker_time'); 479 480 if (this.inst !== null) { 481 var timeDefined = this.timeDefined; 482 this._onTimeChange(); 483 this.timeDefined = timeDefined; 484 } 485 486 // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/ 487 if (this._defaults.addSliderAccess) { 488 var sliderAccessArgs = this._defaults.sliderAccessArgs, 489 rtl = this._defaults.isRTL; 490 sliderAccessArgs.isRTL = rtl; 491 492 setTimeout(function() { // fix for inline mode 493 if ($tp.find('.ui-slider-access').length === 0) { 494 $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs); 495 496 // fix any grids since sliders are shorter 497 var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true); 498 if (sliderAccessWidth) { 499 $tp.find('table:visible').each(function() { 500 var $g = $(this), 501 oldWidth = $g.outerWidth(), 502 oldMarginLeft = $g.css(rtl? 'marginRight':'marginLeft').toString().replace('%', ''), 503 newWidth = oldWidth - sliderAccessWidth, 504 newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%', 505 css = { width: newWidth, marginRight: 0, marginLeft: 0 }; 506 css[rtl? 'marginRight':'marginLeft'] = newMarginLeft; 507 $g.css(css); 508 }); 509 } 510 } 511 }, 10); 512 } 513 // end slideAccess integration 514 515 } 516 }, 517 518 /* 519 * This function tries to limit the ability to go outside the 520 * min/max date range 521 */ 522 _limitMinMaxDateTime: function(dp_inst, adjustSliders) { 523 var o = this._defaults, 524 dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay); 525 526 if (!this._defaults.showTimepicker) { 527 return; 528 } // No time so nothing to check here 529 530 if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) { 531 var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'), 532 minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0); 533 534 if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null) { 535 this.hourMinOriginal = o.hourMin; 536 this.minuteMinOriginal = o.minuteMin; 537 this.secondMinOriginal = o.secondMin; 538 this.millisecMinOriginal = o.millisecMin; 539 } 540 541 if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() == dp_date.getTime()) { 542 this._defaults.hourMin = minDateTime.getHours(); 543 if (this.hour <= this._defaults.hourMin) { 544 this.hour = this._defaults.hourMin; 545 this._defaults.minuteMin = minDateTime.getMinutes(); 546 if (this.minute <= this._defaults.minuteMin) { 547 this.minute = this._defaults.minuteMin; 548 this._defaults.secondMin = minDateTime.getSeconds(); 549 if (this.second <= this._defaults.secondMin) { 550 this.second = this._defaults.secondMin; 551 this._defaults.millisecMin = minDateTime.getMilliseconds(); 552 } else { 553 if (this.millisec < this._defaults.millisecMin) { 554 this.millisec = this._defaults.millisecMin; 555 } 556 this._defaults.millisecMin = this.millisecMinOriginal; 557 } 558 } else { 559 this._defaults.secondMin = this.secondMinOriginal; 560 this._defaults.millisecMin = this.millisecMinOriginal; 561 } 562 } else { 563 this._defaults.minuteMin = this.minuteMinOriginal; 564 this._defaults.secondMin = this.secondMinOriginal; 565 this._defaults.millisecMin = this.millisecMinOriginal; 566 } 567 } else { 568 this._defaults.hourMin = this.hourMinOriginal; 569 this._defaults.minuteMin = this.minuteMinOriginal; 570 this._defaults.secondMin = this.secondMinOriginal; 571 this._defaults.millisecMin = this.millisecMinOriginal; 572 } 573 } 574 575 if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) { 576 var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'), 577 maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0); 578 579 if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null) { 580 this.hourMaxOriginal = o.hourMax; 581 this.minuteMaxOriginal = o.minuteMax; 582 this.secondMaxOriginal = o.secondMax; 583 this.millisecMaxOriginal = o.millisecMax; 584 } 585 586 if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()) { 587 this._defaults.hourMax = maxDateTime.getHours(); 588 if (this.hour >= this._defaults.hourMax) { 589 this.hour = this._defaults.hourMax; 590 this._defaults.minuteMax = maxDateTime.getMinutes(); 591 if (this.minute >= this._defaults.minuteMax) { 592 this.minute = this._defaults.minuteMax; 593 this._defaults.secondMax = maxDateTime.getSeconds(); 594 } else if (this.second >= this._defaults.secondMax) { 595 this.second = this._defaults.secondMax; 596 this._defaults.millisecMax = maxDateTime.getMilliseconds(); 597 } else { 598 if (this.millisec > this._defaults.millisecMax) { 599 this.millisec = this._defaults.millisecMax; 600 } 601 this._defaults.millisecMax = this.millisecMaxOriginal; 602 } 603 } else { 604 this._defaults.minuteMax = this.minuteMaxOriginal; 605 this._defaults.secondMax = this.secondMaxOriginal; 606 this._defaults.millisecMax = this.millisecMaxOriginal; 607 } 608 } else { 609 this._defaults.hourMax = this.hourMaxOriginal; 610 this._defaults.minuteMax = this.minuteMaxOriginal; 611 this._defaults.secondMax = this.secondMaxOriginal; 612 this._defaults.millisecMax = this.millisecMaxOriginal; 613 } 614 } 615 616 if (adjustSliders !== undefined && adjustSliders === true) { 617 var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10), 618 minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10), 619 secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10), 620 millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10); 621 622 if (this.hour_slider) { 623 this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax }); 624 this.control.value(this, this.hour_slider, 'hour', this.hour); 625 } 626 if (this.minute_slider) { 627 this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax }); 628 this.control.value(this, this.minute_slider, 'minute', this.minute); 629 } 630 if (this.second_slider) { 631 this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax }); 632 this.control.value(this, this.second_slider, 'second', this.second); 633 } 634 if (this.millisec_slider) { 635 this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax }); 636 this.control.value(this, this.millisec_slider, 'millisec', this.millisec); 637 } 638 } 639 640 }, 641 642 /* 643 * when a slider moves, set the internal time... 644 * on time change is also called when the time is updated in the text field 645 */ 646 _onTimeChange: function() { 647 var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false, 648 minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false, 649 second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false, 650 millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false, 651 timezone = (this.timezone_select) ? this.timezone_select.val() : false, 652 o = this._defaults, 653 pickerTimeFormat = o.pickerTimeFormat || o.timeFormat, 654 pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix; 655 656 if (typeof(hour) == 'object') { 657 hour = false;
658 } 659 if (typeof(minute) == 'object') { 660 minute = false; 661 } 662 if (typeof(second) == 'object') { 663 second = false; 664 } 665 if (typeof(millisec) == 'object') { 666 millisec = false; 667 } 668 if (typeof(timezone) == 'object') { 669 timezone = false; 670 } 671 672 if (hour !== false) { 673 hour = parseInt(hour, 10); 674 } 675 if (minute !== false) { 676 minute = parseInt(minute, 10); 677 } 678 if (second !== false) { 679 second = parseInt(second, 10); 680 } 681 if (millisec !== false) { 682 millisec = parseInt(millisec, 10); 683 } 684 685 var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0]; 686 687 // If the update was done in the input field, the input field should not be updated. 688 // If the update was done using the sliders, update the input field. 689 var hasChanged = (hour != this.hour || minute != this.minute || second != this.second || millisec != this.millisec 690 || (this.ampm.length > 0 && (hour < 12) != ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) 691 || ((this.timezone === null && timezone != this.defaultTimezone) || (this.timezone !== null && timezone != this.timezone))); 692 693 if (hasChanged) { 694 695 if (hour !== false) { 696 this.hour = hour; 697 } 698 if (minute !== false) { 699 this.minute = minute; 700 } 701 if (second !== false) { 702 this.second = second; 703 } 704 if (millisec !== false) { 705 this.millisec = millisec; 706 } 707 if (timezone !== false) { 708 this.timezone = timezone; 709 } 710 711 if (!this.inst) { 712 this.inst = $.datepicker._getInst(this.$input[0]); 713 } 714 715 this._limitMinMaxDateTime(this.inst, true); 716 } 717 if (useAmpm(o.timeFormat)) { 718 this.ampm = ampm; 719 } 720 721 // Updates the time within the timepicker 722 this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o); 723 if (this.$timeObj) { 724 if(pickerTimeFormat === o.timeFormat){ 725 this.$timeObj.text(this.formattedTime + pickerTimeSuffix); 726 } 727 else{ 728 this.$timeObj.text($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix); 729 } 730 } 731 732 this.timeDefined = true; 733 if (hasChanged) { 734 this._updateDateTime(); 735 } 736 }, 737 738 /* 739 * call custom onSelect. 740 * bind to sliders slidestop, and grid click. 741 */ 742 _onSelectHandler: function() { 743 var onSelect = this._defaults.onSelect || this.inst.settings.onSelect; 744 var inputEl = this.$input ? this.$input[0] : null; 745 if (onSelect && inputEl) { 746 onSelect.apply(inputEl, [this.formattedDateTime, this]); 747 } 748 }, 749 750 /* 751 * update our input with the new date time.. 752 */ 753 _updateDateTime: function(dp_inst) { 754 dp_inst = this.inst || dp_inst; 755 var dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)), 756 dateFmt = $.datepicker._get(dp_inst, 'dateFormat'), 757 formatCfg = $.datepicker._getFormatConfig(dp_inst), 758 timeAvailable = dt !== null && this.timeDefined; 759 this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg); 760 var formattedDateTime = this.formattedDate; 761 762 /* 763 * remove following lines to force every changes in date picker to change the input value 764 * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker. 765 * If the user manually empty the value in the input field, the date picker will never change selected value. 766 */ 767 //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) { 768 // return; 769 //} 770 771 if (this._defaults.timeOnly === true) { 772 formattedDateTime = this.formattedTime; 773 } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) { 774 formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix; 775 } 776 777 this.formattedDateTime = formattedDateTime; 778 779 if (!this._defaults.showTimepicker) { 780 this.$input.val(this.formattedDate); 781 } else if (this.$altInput && this._defaults.altFieldTimeOnly === true) { 782 this.$altInput.val(this.formattedTime); 783 this.$input.val(this.formattedDate); 784 } else if (this.$altInput) { 785 this.$input.val(formattedDateTime); 786 var altFormattedDateTime = '', 787 altSeparator = this._defaults.altSeparator ? this._defaults.altSeparator : this._defaults.separator, 788 altTimeSuffix = this._defaults.altTimeSuffix ? this._defaults.altTimeSuffix : this._defaults.timeSuffix; 789 790 if (this._defaults.altFormat) altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg); 791 else altFormattedDateTime = this.formattedDate; 792 if (altFormattedDateTime) altFormattedDateTime += altSeparator; 793 if (this._defaults.altTimeFormat) altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix; 794 else altFormattedDateTime += this.formattedTime + altTimeSuffix; 795 this.$altInput.val(altFormattedDateTime); 796 } else { 797 this.$input.val(formattedDateTime); 798 } 799 800 this.$input.trigger("change"); 801 }, 802 803 _onFocus: function() { 804 if (!this.$input.val() && this._defaults.defaultValue) { 805 this.$input.val(this._defaults.defaultValue); 806 var inst = $.datepicker._getInst(this.$input.get(0)), 807 tp_inst = $.datepicker._get(inst, 'timepicker'); 808 if (tp_inst) {
809 if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) { 810 try { 811 $.datepicker._updateDatepicker(inst); 812 } catch (err) { 813 $.datepicker.log(err); 814 } 815 } 816 } 817 } 818 }, 819 820 /* 821 * Small abstraction to control types 822 * We can add more, just be sure to follow the pattern: create, options, value 823 */ 824 _controls: { 825 // slider methods 826 slider: { 827 create: function(tp_inst, obj, unit, val, min, max, step){ 828 var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60 829 return obj.prop('slide', null).slider({ 830 orientation: "horizontal", 831 value: rtl? val*-1 : val, 832 min: rtl? max*-1 : min, 833 max: rtl? min*-1 : max, 834 step: step, 835 slide: function(event, ui) { 836 tp_inst.control.value(tp_inst, $(this), unit, rtl? ui.value*-1:ui.value); 837 tp_inst._onTimeChange(); 838 }, 839 stop: function(event, ui) { 840 tp_inst._onSelectHandler(); 841 } 842 }); 843 }, 844 options: function(tp_inst, obj, unit, opts, val){ 845 if(tp_inst._defaults.isRTL){ 846 if(typeof(opts) == 'string'){ 847 if(opts == 'min' || opts == 'max'){ 848 if(val !== undefined) 849 return obj.slider(opts, val*-1); 850 return Math.abs(obj.slider(opts)); 851 } 852 return obj.slider(opts); 853 } 854 var min = opts.min, 855 max = opts.max; 856 opts.min = opts.max = null; 857 if(min !== undefined) 858 opts.max = min * -1; 859 if(max !== undefined) 860 opts.min = max * -1; 861 return obj.slider(opts); 862 } 863 if(typeof(opts) == 'string' && val !== undefined) 864 return obj.slider(opts, val); 865 return obj.slider(opts); 866 }, 867 value: function(tp_inst, obj, unit, val){ 868 if(tp_inst._defaults.isRTL){ 869 if(val !== undefined) 870 return obj.slider('value', val*-1); 871 return Math.abs(obj.slider('value')); 872 } 873 if(val !== undefined) 874 return obj.slider('value', val); 875 return obj.slider('value'); 876 } 877 }, 878 // select methods 879 select: { 880 create: function(tp_inst, obj, unit, val, min, max, step){ 881 var sel = '<select class="ui-timepicker-select" data-unit="'+ unit +'" data-min="'+ min +'" data-max="'+ max +'" data-step="'+ step +'">', 882 ul = tp_inst._defaults.timeFormat.indexOf('t') !== -1? 'toLowerCase':'toUpperCase', 883 m = 0; 884 885 for(var i=min; i<=max; i+=step){ 886 sel += '<option value="'+ i +'"'+ (i==val? ' selected':'') +'>'; 887 if(unit == 'hour' && useAmpm(tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat)) 888 sel += $.datepicker.formatTime("hh TT", {hour:i}, tp_inst._defaults); 889 else if(unit == 'millisec' || i >= 10) sel += i; 890 else sel += '0'+ i.toString(); 891 sel += '</option>'; 892 } 893 sel += '</select>'; 894 895 obj.children('select').remove(); 896 897 $(sel).appendTo(obj).change(function(e){ 898 tp_inst._onTimeChange(); 899 tp_inst._onSelectHandler(); 900 }); 901 902 return obj; 903 }, 904 options: function(tp_inst, obj, unit, opts, val){ 905 var o = {}, 906 $t = obj.children('select'); 907 if(typeof(opts) == 'string'){ 908 if(val === undefined) 909 return $t.data(opts); 910 o[opts] = val; 911 } 912 else o = opts; 913 return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min || $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step')); 914 }, 915 value: function(tp_inst, obj, unit, val){ 916 var $t = obj.children('select'); 917 if(val !== undefined) 918 return $t.val(val); 919 return $t.val(); 920 } 921 } 922 } // end _controls 923 924 }); 925 926 $.fn.extend({ 927 /* 928 * shorthand just to use timepicker.. 929 */ 930 timepicker: function(o) { 931 o = o || {}; 932 var tmp_args = Array.prototype.slice.call(arguments); 933 934 if (typeof o == 'object') { 935 tmp_args[0] = $.extend(o, { 936 timeOnly: true 937 }); 938 } 939 940 return $(this).each(function() { 941 $.fn.datetimepicker.apply($(this), tmp_args); 942 }); 943 }, 944 945 /* 946 * extend timepicker to datepicker 947 */ 948 datetimepicker: function(o) { 949 o = o || {}; 950 var tmp_args = arguments; 951 952 if (typeof(o) == 'string') { 953 if (o == 'getDate') { 954 return $.fn.datepicker.apply($(this[0]), tmp_args); 955 } else { 956 return this.each(function() { 957 var $t = $(this); 958 $t.datepicker.apply($t, tmp_args); 959 }); 960 } 961 } else { 962 return this.each(function() { 963 var $t = $(this); 964 $t.datepicker($.timepicker._newInst($t, o)._defaults); 965 }); 966 } 967 } 968 }); 969 970 /* 971 * Public Utility to parse date and time 972 */ 973 $.datepicker.parseDateTime = function(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) { 974 var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings); 975 if (parseRes.timeObj) { 976 var t = parseRes.timeObj; 977 parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec); 978 } 979 980 return parseRes.date; 981 }; 982 983 /* 984 * Public utility to parse time 985 */ 986 $.datepicker.parseTime = function(timeFormat, timeString, options) { 987 var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}); 988 989 // Strict parse requires the timeString to match the timeFormat exactly 990 var strictParse = function(f, s, o){ 991 992 // pattern for standard and localized AM/PM markers 993 var getPatternAmpm = function(amNames, pmNames) { 994 var markers = []; 995 if (amNames) { 996 $.merge(markers, amNames); 997 } 998 if (pmNames) { 999 $.merge(markers, pmNames); 1000 } 1001 markers = $.map(markers, function(val) { 1002 return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&'); 1003 }); 1004 return '(' + markers.join('|') + ')?'; 1005 }; 1006 1007 // figure out position of time elements.. cause js cant do named captures 1008 var getFormatPositions = function(timeFormat) { 1009 var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|t{1,2}|z|'.*?')/g), 1010 orders = { 1011 h: -1, 1012 m: -1, 1013 s: -1, 1014 l: -1, 1015 t: -1, 1016 z: -1 1017 }; 1018 1019 if (finds) { 1020 for (var i = 0; i < finds.length; i++) { 1021 if (orders[finds[i].toString().charAt(0)] == -1) { 1022 orders[finds[i].toString().charAt(0)] = i + 1; 1023 } 1024 } 1025 } 1026 return orders; 1027 }; 1028 1029 var regstr = '^' + f.toString() 1030 .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[lz]|'.*?')/g, function (match) { 1031 switch (match.charAt(0).toLowerCase()) { 1032 case 'h': return '(\\d?\\d)'; 1033 case 'm': return '(\\d?\\d)'; 1034 case 's': return '(\\d?\\d)'; 1035 case 'l': return '(\\d?\\d?\\d)'; 1036 case 'z': return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?'; 1037 case 't': return getPatternAmpm(o.amNames, o.pmNames); 1038 default: // literal escaped in quotes 1039 return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?'; 1040 } 1041 }) 1042 .replace(/\s/g, '\\s?') + 1043 o.timeSuffix + '$', 1044 order = getFormatPositions(f), 1045 ampm = '', 1046 treg; 1047 1048 treg = s.match(new RegExp(regstr, 'i')); 1049 1050 var resTime = { 1051 hour: 0, 1052 minute: 0, 1053 second: 0, 1054 millisec: 0 1055 }; 1056 1057 if (treg) { 1058 if (order.t !== -1) { 1059 if (treg[order.t] === undefined || treg[order.t].length === 0) { 1060 ampm = ''; 1061 resTime.ampm = ''; 1062 } else { 1063 ampm = $.inArray(treg[order.t].toUpperCase(), o.amNames) !== -1 ? 'AM' : 'PM'; 1064 resTime.ampm = o[ampm == 'AM' ? 'amNames' : 'pmNames'][0]; 1065 } 1066 } 1067 1068 if (order.h !== -1) { 1069 if (ampm == 'AM' && treg[order.h] == '12') { 1070 resTime.hour = 0; // 12am = 0 hour 1071 } else { 1072 if (ampm == 'PM' && treg[order.h] != '12') { 1073 resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12 1074 } else { 1075 resTime.hour = Number(treg[order.h]); 1076 } 1077 } 1078 } 1079 1080 if (order.m !== -1) { 1081 resTime.minute = Number(treg[order.m]); 1082 } 1083 if (order.s !== -1) { 1084 resTime.second = Number(treg[order.s]); 1085 } 1086 if (order.l !== -1) {
1087 resTime.millisec = Number(treg[order.l]); 1088 } 1089 if (order.z !== -1 && treg[order.z] !== undefined) { 1090 var tz = treg[order.z].toUpperCase(); 1091 switch (tz.length) { 1092 case 1: 1093 // Z 1094 tz = o.timezoneIso8601 ? 'Z' : '+0000'; 1095 break; 1096 case 5: 1097 // +hhmm 1098 if (o.timezoneIso8601) { 1099 tz = tz.substring(1) == '0000' ? 'Z' : tz.substring(0, 3) + ':' + tz.substring(3); 1100 } 1101 break; 1102 case 6: 1103 // +hh:mm 1104 if (!o.timezoneIso8601) { 1105 tz = tz == 'Z' || tz.substring(1) == '00:00' ? '+0000' : tz.replace(/:/, ''); 1106 } else { 1107 if (tz.substring(1) == '00:00') { 1108 tz = 'Z'; 1109 } 1110 } 1111 break; 1112 } 1113 resTime.timezone = tz; 1114 } 1115 1116 1117 return resTime; 1118 } 1119 return false; 1120 };// end strictParse 1121 1122 // First try JS Date, if that fails, use strictParse 1123 var looseParse = function(f,s,o){ 1124 try{ 1125 var d = new Date('2012-01-01 '+ s); 1126 return { 1127 hour: d.getHours(), 1128 minutes: d.getMinutes(), 1129 seconds: d.getSeconds(), 1130 millisec: d.getMilliseconds(), 1131 timezone: $.timepicker.timeZoneOffsetString(d) 1132 }; 1133 } 1134 catch(err){ 1135 try{ 1136 return strictParse(f,s,o); 1137 } 1138 catch(err2){ 1139 $.datepicker.log("Unable to parse \ntimeString: "+ s +"\ntimeFormat: "+ f); 1140 } 1141 } 1142 return false; 1143 }; // end looseParse 1144 1145 if(typeof o.parse === "function"){ 1146 return o.parse(timeFormat, timeString, o) 1147 } 1148 if(o.parse === 'loose'){ 1149 return looseParse(timeFormat, timeString, o); 1150 } 1151 return strictParse(timeFormat, timeString, o); 1152 }; 1153 1154 /* 1155 * Public utility to format the time 1156 * format = string format of the time 1157 * time = a {}, not a Date() for timezones 1158 * options = essentially the regional[].. amNames, pmNames, ampm 1159 */ 1160 $.datepicker.formatTime = function(format, time, options) { 1161 options = options || {}; 1162 options = $.extend({}, $.timepicker._defaults, options); 1163 time = $.extend({ 1164 hour: 0, 1165 minute: 0, 1166 second: 0, 1167 millisec: 0, 1168 timezone: '+0000' 1169 }, time); 1170 1171 var tmptime = format, 1172 ampmName = options.amNames[0], 1173 hour = parseInt(time.hour, 10); 1174 1175 if (hour > 11) { 1176 ampmName = options.pmNames[0]; 1177 } 1178 1179 tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[lz]|('.*?'|".*?"))/g, function(match) { 1180 switch (match) { 1181 case 'HH': 1182 return ('0' + hour).slice(-2); 1183 case 'H': 1184 return hour; 1185 case 'hh': 1186 return convert24to12(hour).slice(-2); 1187 case 'h': 1188 return convert24to12(hour); 1189 case 'mm': 1190 return ('0' + time.minute).slice(-2); 1191 case 'm': 1192 return time.minute; 1193 case 'ss': 1194 return ('0' + time.second).slice(-2); 1195 case 's': 1196 return time.second; 1197 case 'l': 1198 return ('00' + time.millisec).slice(-3); 1199 case 'z': 1200 return time.timezone === null? options.defaultTimezone : time.timezone; 1201 case 'T': 1202 return ampmName.charAt(0).toUpperCase(); 1203 case 'TT': 1204 return ampmName.toUpperCase(); 1205 case 't': 1206 return ampmName.charAt(0).toLowerCase(); 1207 case 'tt': 1208 return ampmName.toLowerCase(); 1209 default: 1210 return match.replace(/\'/g, "") || "'"; 1211 } 1212 }); 1213 1214 tmptime = $.trim(tmptime); 1215 return tmptime; 1216 }; 1217 1218 /* 1219 * the bad hack :/ override datepicker so it doesnt close on select 1220 // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378 1221 */ 1222 $.datepicker._base_selectDate = $.datepicker._selectDate; 1223 $.datepicker._selectDate = function(id, dateStr) { 1224 var inst = this._getInst($(id)[0]), 1225 tp_inst = this._get(inst, 'timepicker'); 1226 1227 if (tp_inst) { 1228 tp_inst._limitMinMaxDateTime(inst, true); 1229 inst.inline = inst.stay_open = true; 1230 //This way the onSelect handler called from calendarpicker get the full dateTime 1231 this._base_selectDate(id, dateStr); 1232 inst.inline = inst.stay_open = false; 1233 this._notifyChange(inst); 1234 this._updateDatepicker(inst); 1235 } else { 1236 this._base_selectDate(id, dateStr); 1237 } 1238 }; 1239 1240 /* 1241 * second bad hack :/ override datepicker so it triggers an event when changing the input field 1242 * and does not redraw the datepicker on every selectDate event 1243 */ 1244 $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker; 1245 $.datepicker._updateDatepicker = function(inst) { 1246 1247 // don't popup the datepicker if there is another instance already opened 1248 var input = inst.input[0]; 1249 if ($.datepicker._curInst && $.datepicker._curInst != inst && $.datepicker._datepickerShowing && $.datepicker._lastInput != input) { 1250 return; 1251 } 1252 1253 if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) { 1254 1255 this._base_updateDatepicker(inst); 1256 1257 // Reload the time control when changing something in the input text field. 1258 var tp_inst = this._get(inst, 'timepicker'); 1259 if (tp_inst) { 1260 tp_inst._addTimePicker(inst); 1261
vendor: 12,025 bytes, lines 1262-1623
1262 if (tp_inst._defaults.useLocalTimezone) { //checks daylight saving with the new date. 1263 var date = new Date(inst.selectedYear, inst.selectedMonth, inst.selectedDay, 12); 1264 selectLocalTimeZone(tp_inst, date); 1265 tp_inst._onTimeChange(); 1266 } 1267 } 1268 } 1269 }; 1270 1271 /* 1272 * third bad hack :/ override datepicker so it allows spaces and colon in the input field 1273 */ 1274 $.datepicker._base_doKeyPress = $.datepicker._doKeyPress; 1275 $.datepicker._doKeyPress = function(event) { 1276 var inst = $.datepicker._getInst(event.target), 1277 tp_inst = $.datepicker._get(inst, 'timepicker'); 1278 1279 if (tp_inst) { 1280 if ($.datepicker._get(inst, 'constrainInput')) { 1281 var ampm = useAmpm(tp_inst._defaults.timeFormat), 1282 dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')), 1283 datetimeChars = tp_inst._defaults.timeFormat.toString() 1284 .replace(/[hms]/g, '') 1285 .replace(/TT/g, ampm ? 'APM' : '') 1286 .replace(/Tt/g, ampm ? 'AaPpMm' : '') 1287 .replace(/tT/g, ampm ? 'AaPpMm' : '') 1288 .replace(/T/g, ampm ? 'AP' : '') 1289 .replace(/tt/g, ampm ? 'apm' : '') 1290 .replace(/t/g, ampm ? 'ap' : '') + 1291 " " + tp_inst._defaults.separator + 1292 tp_inst._defaults.timeSuffix + 1293 (tp_inst._defaults.showTimezone ? tp_inst._defaults.timezoneList.join('') : '') + 1294 (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) + 1295 dateChars, 1296 chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode); 1297 return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1); 1298 } 1299 } 1300 1301 return $.datepicker._base_doKeyPress(event); 1302 }; 1303 1304 /* 1305 * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField 1306 */ 1307 $.datepicker._base_updateAlternate = $.datepicker._updateAlternate; 1308 /* Update any alternate field to synchronise with the main field. */ 1309 $.datepicker._updateAlternate = function(inst) { 1310 var tp_inst = this._get(inst, 'timepicker'); 1311 if(tp_inst){ 1312 var altField = tp_inst._defaults.altField; 1313 if (altField) { // update alternate field too 1314 var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat, 1315 date = this._getDate(inst), 1316 formatCfg = $.datepicker._getFormatConfig(inst), 1317 altFormattedDateTime = '', 1318 altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator, 1319 altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix, 1320 altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat; 1321 1322 altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix; 1323 if(!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly){ 1324 if(tp_inst._defaults.altFormat) 1325 altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, (date === null ? new Date() : date), formatCfg) + altSeparator + altFormattedDateTime; 1326 else altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime; 1327 } 1328 $(altField).val(altFormattedDateTime); 1329 } 1330 } 1331 else{ 1332 $.datepicker._base_updateAlternate(inst); 1333 } 1334 }; 1335 1336 /* 1337 * Override key up event to sync manual input changes. 1338 */ 1339 $.datepicker._base_doKeyUp = $.datepicker._doKeyUp; 1340 $.datepicker._doKeyUp = function(event) { 1341 var inst = $.datepicker._getInst(event.target), 1342 tp_inst = $.datepicker._get(inst, 'timepicker'); 1343 1344 if (tp_inst) { 1345 if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) { 1346 try { 1347 $.datepicker._updateDatepicker(inst); 1348 } catch (err) { 1349 $.datepicker.log(err); 1350 } 1351 } 1352 } 1353 1354 return $.datepicker._base_doKeyUp(event); 1355 }; 1356 1357 /* 1358 * override "Today" button to also grab the time. 1359 */ 1360 $.datepicker._base_gotoToday = $.datepicker._gotoToday; 1361 $.datepicker._gotoToday = function(id) { 1362 var inst = this._getInst($(id)[0]), 1363 $dp = inst.dpDiv; 1364 this._base_gotoToday(id); 1365 var tp_inst = this._get(inst, 'timepicker'); 1366 selectLocalTimeZone(tp_inst); 1367 var now = new Date(); 1368 this._setTime(inst, now); 1369 $('.ui-datepicker-today', $dp).click(); 1370 }; 1371 1372 /* 1373 * Disable & enable the Time in the datetimepicker 1374 */ 1375 $.datepicker._disableTimepickerDatepicker = function(target) { 1376 var inst = this._getInst(target); 1377 if (!inst) { 1378 return; 1379 } 1380 1381 var tp_inst = this._get(inst, 'timepicker'); 1382 $(target).datepicker('getDate'); // Init selected[Year|Month|Day] 1383 if (tp_inst) { 1384 tp_inst._defaults.showTimepicker = false; 1385 tp_inst._updateDateTime(inst); 1386 } 1387 }; 1388 1389 $.datepicker._enableTimepickerDatepicker = function(target) { 1390 var inst = this._getInst(target); 1391 if (!inst) { 1392 return; 1393 } 1394 1395 var tp_inst = this._get(inst, 'timepicker'); 1396 $(target).datepicker('getDate'); // Init selected[Year|Month|Day] 1397 if (tp_inst) { 1398 tp_inst._defaults.showTimepicker = true; 1399 tp_inst._addTimePicker(inst); // Could be disabled on page load 1400 tp_inst._updateDateTime(inst); 1401 } 1402 }; 1403 1404 /* 1405 * Create our own set time function 1406 */ 1407 $.datepicker._setTime = function(inst, date) { 1408 var tp_inst = this._get(inst, 'timepicker'); 1409 if (tp_inst) { 1410 var defaults = tp_inst._defaults; 1411 1412 // calling _setTime with no date sets time to defaults 1413 tp_inst.hour = date ? date.getHours() : defaults.hour; 1414 tp_inst.minute = date ? date.getMinutes() : defaults.minute; 1415 tp_inst.second = date ? date.getSeconds() : defaults.second; 1416 tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec; 1417 1418 //check if within min/max times.. 1419 tp_inst._limitMinMaxDateTime(inst, true); 1420 1421 tp_inst._onTimeChange(); 1422 tp_inst._updateDateTime(inst); 1423 } 1424 }; 1425 1426 /* 1427 * Create new public method to set only time, callable as $().datepicker('setTime', date) 1428 */ 1429 $.datepicker._setTimeDatepicker = function(target, date, withDate) { 1430 var inst = this._getInst(target); 1431 if (!inst) { 1432 return; 1433 } 1434 1435 var tp_inst = this._get(inst, 'timepicker'); 1436 1437 if (tp_inst) { 1438 this._setDateFromField(inst); 1439 var tp_date; 1440 if (date) { 1441 if (typeof date == "string") { 1442 tp_inst._parseTime(date, withDate); 1443 tp_date = new Date(); 1444 tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); 1445 } else { 1446 tp_date = new Date(date.getTime()); 1447 } 1448 if (tp_date.toString() == 'Invalid Date') { 1449 tp_date = undefined; 1450 } 1451 this._setTime(inst, tp_date); 1452 } 1453 } 1454 1455 }; 1456 1457 /* 1458 * override setDate() to allow setting time too within Date object 1459 */ 1460 $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker; 1461 $.datepicker._setDateDatepicker = function(target, date) { 1462 var inst = this._getInst(target); 1463 if (!inst) { 1464 return; 1465 } 1466 1467 var tp_date = (date instanceof Date) ? new Date(date.getTime()) : date; 1468 1469 this._updateDatepicker(inst); 1470 this._base_setDateDatepicker.apply(this, arguments); 1471 this._setTimeDatepicker(target, tp_date, true); 1472 }; 1473 1474 /* 1475 * override getDate() to allow getting time too within Date object 1476 */ 1477 $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker; 1478 $.datepicker._getDateDatepicker = function(target, noDefault) { 1479 var inst = this._getInst(target); 1480 if (!inst) { 1481 return; 1482 } 1483 1484 var tp_inst = this._get(inst, 'timepicker'); 1485 1486 if (tp_inst) { 1487 // if it hasn't yet been defined, grab from field 1488 if(inst.lastVal === undefined){ 1489 this._setDateFromField(inst, noDefault); 1490 } 1491 1492 var date = this._getDate(inst); 1493 if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) { 1494 date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec); 1495 } 1496 return date; 1497 } 1498 return this._base_getDateDatepicker(target, noDefault); 1499 }; 1500 1501 /* 1502 * override parseDate() because UI 1.8.14 throws an error about "Extra characters" 1503 * An option in datapicker to ignore extra format characters would be nicer. 1504 */ 1505 $.datepicker._base_parseDate = $.datepicker.parseDate; 1506 $.datepicker.parseDate = function(format, value, settings) { 1507 var date; 1508 try { 1509 date = this._base_parseDate(format, value, settings); 1510 } catch (err) { 1511 // Hack! The error message ends with a colon, a space, and 1512 // the "extra" characters. We rely on that instead of 1513 // attempting to perfectly reproduce the parsing algorithm. 1514 date = this._base_parseDate(format, value.substring(0,value.length-(err.length-err.indexOf(':')-2)), settings); 1515 $.datepicker.log("Error parsing the date string: " + err + "\ndate string = " + value + "\ndate format = " + format); 1516 } 1517 return date; 1518 }; 1519 1520 /* 1521 * override formatDate to set date with time to the input 1522 */ 1523 $.datepicker._base_formatDate = $.datepicker._formatDate; 1524 $.datepicker._formatDate = function(inst, day, month, year) { 1525 var tp_inst = this._get(inst, 'timepicker'); 1526 if (tp_inst) { 1527 tp_inst._updateDateTime(inst); 1528 return tp_inst.$input.val(); 1529 } 1530 return this._base_formatDate(inst); 1531 }; 1532 1533 /* 1534 * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate 1535 */ 1536 $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker; 1537 $.datepicker._optionDatepicker = function(target, name, value) { 1538 var inst = this._getInst(target), 1539 name_clone; 1540 if (!inst) { 1541 return null; 1542 } 1543 1544 var tp_inst = this._get(inst, 'timepicker'); 1545 if (tp_inst) { 1546 var min = null, 1547 max = null, 1548 onselect = null, 1549 overrides = tp_inst._defaults.evnts, 1550 fns = {}, 1551 prop; 1552 if (typeof name == 'string') { // if min/max was set with the string 1553 if (name === 'minDate' || name === 'minDateTime') { 1554 min = value; 1555 } else if (name === 'maxDate' || name === 'maxDateTime') { 1556 max = value; 1557 } else if (name === 'onSelect') { 1558 onselect = value; 1559 } else if (overrides.hasOwnProperty(name)) { 1560 if (typeof (value) === 'undefined') { 1561 return overrides[name]; 1562 } 1563 fns[name] = value; 1564 name_clone = {}; //empty results in exiting function after overrides updated 1565 } 1566 } else if (typeof name == 'object') { //if min/max was set with the JSON 1567 if (name.minDate) { 1568 min = name.minDate; 1569 } else if (name.minDateTime) { 1570 min = name.minDateTime; 1571 } else if (name.maxDate) { 1572 max = name.maxDate; 1573 } else if (name.maxDateTime) { 1574 max = name.maxDateTime; 1575 } 1576 for (prop in overrides) { 1577 if (overrides.hasOwnProperty(prop) && name[prop]) { 1578 fns[prop] = name[prop]; 1579 } 1580 } 1581 } 1582 for (prop in fns) { 1583 if (fns.hasOwnProperty(prop)) { 1584 overrides[prop] = fns[prop]; 1585 if (!name_clone) { name_clone = $.extend({}, name);} 1586 delete name_clone[prop]; 1587 } 1588 } 1589 if (name_clone && isEmptyObject(name_clone)) { return; } 1590 if (min) { //if min was set 1591 if (min === 0) { 1592 min = new Date(); 1593 } else { 1594 min = new Date(min); 1595 } 1596 tp_inst._defaults.minDate = min; 1597 tp_inst._defaults.minDateTime = min; 1598 } else if (max) { //if max was set 1599 if (max === 0) { 1600 max = new Date(); 1601 } else { 1602 max = new Date(max); 1603 } 1604 tp_inst._defaults.maxDate = max; 1605 tp_inst._defaults.maxDateTime = max; 1606 } else if (onselect) { 1607 tp_inst._defaults.onSelect = onselect; 1608 } 1609 } 1610 if (value === undefined) { 1611 return this._base_optionDatepicker.call($.datepicker, target, name); 1612 } 1613 return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value); 1614 }; 1615 /* 1616 * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype, 1617 * it will return false for all objects 1618 */ 1619 var isEmptyObject = function(obj) { 1620 var prop; 1621 for (prop in obj) { 1622 if (obj.hasOwnProperty(obj)) { 1623 return false;
1624 } 1625 } 1626 return true; 1627 }; 1628 1629 /* 1630 * jQuery extend now ignores nulls! 1631 */ 1632 var extendRemove = function(target, props) { 1633 $.extend(target, props); 1634 for (var name in props) { 1635 if (props[name] === null || props[name] === undefined) { 1636 target[name] = props[name]; 1637 } 1638 } 1639 return target; 1640 }; 1641 1642 /* 1643 * Determine by the time format if should use ampm 1644 * Returns true if should use ampm, false if not 1645 */ 1646 var useAmpm = function(timeFormat){ 1647 return (timeFormat.indexOf('t') !== -1 && timeFormat.indexOf('h') !== -1); 1648 }; 1649 1650 /* 1651 * Converts 24 hour format into 12 hour 1652 * Returns 12 hour with leading 0 1653 */ 1654 var convert24to12 = function(hour) { 1655 if (hour > 12) { 1656 hour = hour - 12; 1657 } 1658 1659 if (hour == 0) { 1660 hour = 12; 1661 } 1662 1663 if (hour < 10) { 1664 hour = "0" + hour; 1665 } 1666 1667 return String(hour); 1668 }; 1669 1670 /* 1671 * Splits datetime string into date ans time substrings. 1672 * Throws exception when date can't be parsed 1673 * Returns [dateString, timeString] 1674 */ 1675 var splitDateTime = function(dateFormat, dateTimeString, dateSettings, timeSettings) { 1676 try { 1677 // The idea is to get the number separator occurances in datetime and the time format requested (since time has 1678 // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split. 1679 var separator = timeSettings && timeSettings.separator ? timeSettings.separator : $.timepicker._defaults.separator, 1680 format = timeSettings && timeSettings.timeFormat ? timeSettings.timeFormat : $.timepicker._defaults.timeFormat, 1681 timeParts = format.split(separator), // how many occurances of separator may be in our format? 1682 timePartsLen = timeParts.length, 1683 allParts = dateTimeString.split(separator), 1684 allPartsLen = allParts.length; 1685 1686 if (allPartsLen > 1) { 1687 return [ 1688 allParts.splice(0,allPartsLen-timePartsLen).join(separator), 1689 allParts.splice(0,timePartsLen).join(separator) 1690 ]; 1691 } 1692 1693 } catch (err) { 1694 $.datepicker.log('Could not split the date from the time. Please check the following datetimepicker options' + 1695 "\nthrown error: " + err + 1696 "\ndateTimeString" + dateTimeString + 1697 "\ndateFormat = " + dateFormat + 1698 "\nseparator = " + timeSettings.separator + 1699 "\ntimeFormat = " + timeSettings.timeFormat); 1700 1701 if (err.indexOf(":") >= 0) { 1702 // Hack! The error message ends with a colon, a space, and 1703 // the "extra" characters. We rely on that instead of 1704 // attempting to perfectly reproduce the parsing algorithm. 1705 var dateStringLength = dateTimeString.length - (err.length - err.indexOf(':') - 2), 1706 timeString = dateTimeString.substring(dateStringLength); 1707 1708 return [$.trim(dateTimeString.substring(0, dateStringLength)), $.trim(dateTimeString.substring(dateStringLength))]; 1709 1710 } else { 1711 throw err; 1712 } 1713 } 1714 return [dateTimeString, '']; 1715 }; 1716 1717 /* 1718 * Internal function to parse datetime interval 1719 * Returns: {date: Date, timeObj: Object}, where 1720 * date - parsed date without time (type Date) 1721 * timeObj = {hour: , minute: , second: , millisec: } - parsed time. Optional 1722 */ 1723 var parseDateTimeInternal = function(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) { 1724 var date; 1725 var splitRes = splitDateTime(dateFormat, dateTimeString, dateSettings, timeSettings); 1726 date = $.datepicker._base_parseDate(dateFormat, splitRes[0], dateSettings); 1727 if (splitRes[1] !== '') { 1728 var timeString = splitRes[1], 1729 parsedTime = $.datepicker.parseTime(timeFormat, timeString, timeSettings); 1730 1731 if (parsedTime === null) { 1732 throw 'Wrong time format'; 1733 } 1734 return { 1735 date: date, 1736 timeObj: parsedTime 1737 }; 1738 } else { 1739 return { 1740 date: date 1741 }; 1742 } 1743 }; 1744 1745 /* 1746 * Internal function to set timezone_select to the local timezone 1747 */ 1748 var selectLocalTimeZone = function(tp_inst, date) { 1749 if (tp_inst && tp_inst.timezone_select) {
1750 tp_inst._defaults.useLocalTimezone = true; 1751 var now = typeof date !== 'undefined' ? date : new Date(); 1752 var tzoffset = $.timepicker.timeZoneOffsetString(now); 1753 if (tp_inst._defaults.timezoneIso8601) { 1754 tzoffset = tzoffset.substring(0, 3) + ':' + tzoffset.substring(3); 1755 } 1756 tp_inst.timezone_select.val(tzoffset); 1757 } 1758 }; 1759 1760 /* 1761 * Create a Singleton Insance 1762 */ 1763 $.timepicker = new Timepicker(); 1764 1765 /** 1766 * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5) 1767 * @param date 1768 * @return string 1769 */ 1770 $.timepicker.timeZoneOffsetString = function(date) { 1771 var off = date.getTimezoneOffset() * -1, 1772 minutes = off % 60, 1773 hours = (off - minutes) / 60; 1774 return (off >= 0 ? '+' : '-') + ('0' + (hours * 101).toString()).substr(-2) + ('0' + (minutes * 101).toString()).substr(-2); 1775 }; 1776 1777 /** 1778 * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to 1779 * enforce date range limits. 1780 * n.b. The input value must be correctly formatted (reformatting is not supported) 1781 * @param Element startTime 1782 * @param Element endTime 1783 * @param obj options Options for the timepicker() call 1784 * @return jQuery 1785 */ 1786 $.timepicker.timeRange = function(startTime, endTime, options) { 1787 return $.timepicker.handleRange('timepicker', startTime, endTime, options); 1788 }; 1789 1790 /** 1791 * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to 1792 * enforce date range limits. 1793 * @param Element startTime 1794 * @param Element endTime 1795 * @param obj options Options for the `timepicker()` call. Also supports `reformat`, 1796 * a boolean value that can be used to reformat the input values to the `dateFormat`. 1797 * @param string method Can be used to specify the type of picker to be added 1798 * @return jQuery 1799 */ 1800 $.timepicker.dateTimeRange = function(startTime, endTime, options) { 1801 $.timepicker.dateRange(startTime, endTime, options, 'datetimepicker'); 1802 }; 1803 1804 /** 1805 * Calls `method` on the `startTime` and `endTime` elements, and configures them to 1806 * enforce date range limits. 1807 * @param Element startTime 1808 * @param Element endTime 1809 * @param obj options Options for the `timepicker()` call. Also supports `reformat`, 1810 * a boolean value that can be used to reformat the input values to the `dateFormat`. 1811 * @param string method Can be used to specify the type of picker to be added 1812 * @return jQuery 1813 */ 1814 $.timepicker.dateRange = function(startTime, endTime, options, method) { 1815 method = method || 'datepicker'; 1816 $.timepicker.handleRange(method, startTime, endTime, options); 1817 }; 1818 1819 /** 1820 * Calls `method` on the `startTime` and `endTime` elements, and configures them to 1821 * enforce date range limits. 1822 * @param string method Can be used to specify the type of picker to be added 1823 * @param Element startTime 1824 * @param Element endTime 1825 * @param obj options Options for the `timepicker()` call. Also supports `reformat`, 1826 * a boolean value that can be used to reformat the input values to the `dateFormat`. 1827 * @return jQuery 1828 */ 1829 $.timepicker.handleRange = function(method, startTime, endTime, options) { 1830 $.fn[method].call(startTime, $.extend({ 1831 onClose: function(dateText, inst) { 1832 checkDates(this, endTime, dateText); 1833 }, 1834 onSelect: function(selectedDateTime) { 1835 selected(this, endTime, 'minDate'); 1836 } 1837 }, options, options.start)); 1838 $.fn[method].call(endTime, $.extend({ 1839 onClose: function(dateText, inst) { 1840 checkDates(this, startTime, dateText); 1841 }, 1842 onSelect: function(selectedDateTime) { 1843 selected(this, startTime, 'maxDate'); 1844 } 1845 }, options, options.end)); 1846 // timepicker doesn't provide access to its 'timeFormat' option, 1847 // nor could I get datepicker.formatTime() to behave with times, so I 1848 // have disabled reformatting for timepicker 1849 if (method != 'timepicker' && options.reformat) { 1850 $([startTime, endTime]).each(function() { 1851 var format = $(this)[method].call($(this), 'option', 'dateFormat'), 1852 date = new Date($(this).val()); 1853 if ($(this).val() && date) { 1854 $(this).val($.datepicker.formatDate(format, date)); 1855 } 1856 }); 1857 } 1858 checkDates(startTime, endTime, startTime.val()); 1859 1860 function checkDates(changed, other, dateText) { 1861 if (other.val() && (new Date(startTime.val()) > new Date(endTime.val()))) { 1862 other.val(dateText); 1863 } 1864 } 1865 selected(startTime, endTime, 'minDate'); 1866 selected(endTime, startTime, 'maxDate'); 1867 1868 function selected(changed, other, option) { 1869 if (!$(changed).val()) { 1870 return; 1871 } 1872 var date = $(changed)[method].call($(changed), 'getDate'); 1873 // timepicker doesn't implement 'getDate' and returns a jQuery 1874 if (date.getTime) { 1875 $(other)[method].call($(other), 'option', option, date); 1876 } 1877 } 1878 return $([startTime.get(0), endTime.get(0)]); 1879 }; 1880 1881 /* 1882 * Keep up with the version 1883 */ 1884 $.timepicker.version = "1.1.0"; 1885 1886})(jQuery);
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.