Best JavaScript code snippet using cypress
timepicker.js
Source:timepicker.js
1/*! jQuery Timepicker Addon - v1.6.1 - 2015-11-142 * http://trentrichardson.com/examples/timepicker3 * Copyright (c) 2015 Trent Richardson; Licensed MIT */4(function (factory) {5 if (typeof define === 'function' && define.amd) {6 define(['jquery', 'jquery-ui'], factory);7 } else {8 factory(jQuery);9 }10}(function ($) {11 /*12 * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded"13 */14 $.ui.timepicker = $.ui.timepicker || {};15 if ($.ui.timepicker.version) {16 return;17 }18 /*19 * Extend jQueryUI, get it started with our version number20 */21 $.extend($.ui, {22 timepicker: {23 version: "1.6.1"24 }25 });26 /*27 * Timepicker manager.28 * Use the singleton instance of this class, $.timepicker, to interact with the time picker.29 * Settings for (groups of) time pickers are maintained in an instance object,30 * allowing multiple different settings on the same page.31 */32 var Timepicker = function () {33 this.regional = []; // Available regional settings, indexed by language code34 this.regional[''] = { // Default regional settings35 currentText: 'Now',36 closeText: 'Done',37 amNames: ['AM', 'A'],38 pmNames: ['PM', 'P'],39 timeFormat: 'HH:mm',40 timeSuffix: '',41 timeOnlyTitle: 'Choose Time',42 timeText: 'Time',43 hourText: 'Hour',44 minuteText: 'Minute',45 secondText: 'Second',46 millisecText: 'Millisecond',47 microsecText: 'Microsecond',48 timezoneText: 'Time Zone',49 isRTL: false50 };51 this._defaults = { // Global defaults for all the datetime picker instances52 showButtonPanel: true,53 timeOnly: false,54 timeOnlyShowDate: false,55 showHour: null,56 showMinute: null,57 showSecond: null,58 showMillisec: null,59 showMicrosec: null,60 showTimezone: null,61 showTime: true,62 stepHour: 1,63 stepMinute: 1,64 stepSecond: 1,65 stepMillisec: 1,66 stepMicrosec: 1,67 hour: 0,68 minute: 0,69 second: 0,70 millisec: 0,71 microsec: 0,72 timezone: null,73 hourMin: 0,74 minuteMin: 0,75 secondMin: 0,76 millisecMin: 0,77 microsecMin: 0,78 hourMax: 23,79 minuteMax: 59,80 secondMax: 59,81 millisecMax: 999,82 microsecMax: 999,83 minDateTime: null,84 maxDateTime: null,85 maxTime: null,86 minTime: null,87 onSelect: null,88 hourGrid: 0,89 minuteGrid: 0,90 secondGrid: 0,91 millisecGrid: 0,92 microsecGrid: 0,93 alwaysSetTime: true,94 separator: ' ',95 altFieldTimeOnly: true,96 altTimeFormat: null,97 altSeparator: null,98 altTimeSuffix: null,99 altRedirectFocus: true,100 pickerTimeFormat: null,101 pickerTimeSuffix: null,102 showTimepicker: true,103 timezoneList: null,104 addSliderAccess: false,105 sliderAccessArgs: null,106 controlType: 'slider',107 oneLine: false,108 defaultValue: null,109 parse: 'strict',110 afterInject: null111 };112 $.extend(this._defaults, this.regional['']);113 };114 $.extend(Timepicker.prototype, {115 $input: null,116 $altInput: null,117 $timeObj: null,118 inst: null,119 hour_slider: null,120 minute_slider: null,121 second_slider: null,122 millisec_slider: null,123 microsec_slider: null,124 timezone_select: null,125 maxTime: null,126 minTime: null,127 hour: 0,128 minute: 0,129 second: 0,130 millisec: 0,131 microsec: 0,132 timezone: null,133 hourMinOriginal: null,134 minuteMinOriginal: null,135 secondMinOriginal: null,136 millisecMinOriginal: null,137 microsecMinOriginal: null,138 hourMaxOriginal: null,139 minuteMaxOriginal: null,140 secondMaxOriginal: null,141 millisecMaxOriginal: null,142 microsecMaxOriginal: null,143 ampm: '',144 formattedDate: '',145 formattedTime: '',146 formattedDateTime: '',147 timezoneList: null,148 units: ['hour', 'minute', 'second', 'millisec', 'microsec'],149 support: {},150 control: null,151 /*152 * Override the default settings for all instances of the time picker.153 * @param {Object} settings object - the new settings to use as defaults (anonymous object)154 * @return {Object} the manager object155 */156 setDefaults: function (settings) {157 extendRemove(this._defaults, settings || {});158 return this;159 },160 /*161 * Create a new Timepicker instance162 */163 _newInst: function ($input, opts) {164 var tp_inst = new Timepicker(),165 inlineSettings = {},166 fns = {},167 overrides, i;168 for (var attrName in this._defaults) {169 if (this._defaults.hasOwnProperty(attrName)) {170 var attrValue = $input.attr('time:' + attrName);171 if (attrValue) {172 try {173 inlineSettings[attrName] = eval(attrValue);174 } catch (err) {175 inlineSettings[attrName] = attrValue;176 }177 }178 }179 }180 overrides = {181 beforeShow: function (input, dp_inst) {182 if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) {183 return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst);184 }185 },186 onChangeMonthYear: function (year, month, dp_inst) {187 // Update the time as well : this prevents the time from disappearing from the $input field.188 // tp_inst._updateDateTime(dp_inst);189 if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) {190 tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);191 }192 },193 onClose: function (dateText, dp_inst) {194 if (tp_inst.timeDefined === true && $input.val() !== '') {195 tp_inst._updateDateTime(dp_inst);196 }197 if ($.isFunction(tp_inst._defaults.evnts.onClose)) {198 tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst);199 }200 }201 };202 for (i in overrides) {203 if (overrides.hasOwnProperty(i)) {204 fns[i] = opts[i] || this._defaults[i] || null;205 }206 }207 tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, {208 evnts: fns,209 timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');210 });211 tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) {212 return val.toUpperCase();213 });214 tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) {215 return val.toUpperCase();216 });217 // detect which units are supported218 tp_inst.support = detectSupport(219 tp_inst._defaults.timeFormat +220 (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') +221 (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : ''));222 // controlType is string - key to our this._controls223 if (typeof(tp_inst._defaults.controlType) === 'string') {224 if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') {225 tp_inst._defaults.controlType = 'select';226 }227 tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType];228 }229 // controlType is an object and must implement create, options, value methods230 else {231 tp_inst.control = tp_inst._defaults.controlType;232 }233 // prep the timezone options234 var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60,235 0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840];236 if (tp_inst._defaults.timezoneList !== null) {237 timezoneList = tp_inst._defaults.timezoneList;238 }239 var tzl = timezoneList.length, tzi = 0, tzv = null;240 if (tzl > 0 && typeof timezoneList[0] !== 'object') {241 for (; tzi < tzl; tzi++) {242 tzv = timezoneList[tzi];243 timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) };244 }245 }246 tp_inst._defaults.timezoneList = timezoneList;247 // set the default units248 tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) :249 ((new Date()).getTimezoneOffset() * -1);250 tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin :251 tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour;252 tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin :253 tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute;254 tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin :255 tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second;256 tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin :257 tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec;258 tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin :259 tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec;260 tp_inst.ampm = '';261 tp_inst.$input = $input;262 if (tp_inst._defaults.altField) {263 tp_inst.$altInput = $(tp_inst._defaults.altField);264 if (tp_inst._defaults.altRedirectFocus === true) {265 tp_inst.$altInput.css({266 cursor: 'pointer'267 }).focus(function () {268 $input.trigger("focus");269 });270 }271 }272 if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) {273 tp_inst._defaults.minDate = new Date();274 }275 if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) {276 tp_inst._defaults.maxDate = new Date();277 }278 // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..279 if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) {280 tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());281 }282 if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) {283 tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());284 }285 if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) {286 tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());287 }288 if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) {289 tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());290 }291 tp_inst.$input.bind('focus', function () {292 tp_inst._onFocus();293 });294 return tp_inst;295 },296 /*297 * add our sliders to the calendar298 */299 _addTimePicker: function (dp_inst) {300 var currDT = $.trim((this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val());301 this.timeDefined = this._parseTime(currDT);302 this._limitMinMaxDateTime(dp_inst, false);303 this._injectTimePicker();304 this._afterInject();305 },306 /*307 * parse the time string from input value or _setTime308 */309 _parseTime: function (timeString, withDate) {310 if (!this.inst) {311 this.inst = $.datepicker._getInst(this.$input[0]);312 }313 if (withDate || !this._defaults.timeOnly) {314 var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');315 try {316 var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults);317 if (!parseRes.timeObj) {318 return false;319 }320 $.extend(this, parseRes.timeObj);321 } catch (err) {322 $.timepicker.log("Error parsing the date/time string: " + err +323 "\ndate/time string = " + timeString +324 "\ntimeFormat = " + this._defaults.timeFormat +325 "\ndateFormat = " + dp_dateFormat);326 return false;327 }328 return true;329 } else {330 var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults);331 if (!timeObj) {332 return false;333 }334 $.extend(this, timeObj);335 return true;336 }337 },338 /*339 * Handle callback option after injecting timepicker340 */341 _afterInject: function() {342 var o = this.inst.settings;343 if ($.isFunction(o.afterInject)) {344 o.afterInject.call(this);345 }346 },347 /*348 * generate and inject html for timepicker into ui datepicker349 */350 _injectTimePicker: function () {351 var $dp = this.inst.dpDiv,352 o = this.inst.settings,353 tp_inst = this,354 litem = '',355 uitem = '',356 show = null,357 max = {},358 gridSize = {},359 size = null,360 i = 0,361 l = 0;362 // Prevent displaying twice363 if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) {364 var noDisplay = ' ui_tpicker_unit_hide',365 html = '<div class="ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + (o.oneLine && o.controlType === 'select' ? ' ui-timepicker-oneLine' : '') + '"><dl>' + '<dt class="ui_tpicker_time_label' + ((o.showTime) ? '' : noDisplay) + '">' + o.timeText + '</dt>' +366 '<dd class="ui_tpicker_time '+ ((o.showTime) ? '' : noDisplay) + '"><input class="ui_tpicker_time_input" ' + (o.timeInput ? '' : 'disabled') + '/></dd>';367 // Create the markup368 for (i = 0, l = this.units.length; i < l; i++) {369 litem = this.units[i];370 uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);371 show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];372 // Added by Peter Medeiros:373 // - Figure out what the hour/minute/second max should be based on the step values.374 // - Example: if stepMinute is 15, then minMax is 45.375 max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10);376 gridSize[litem] = 0;377 html += '<dt class="ui_tpicker_' + litem + '_label' + (show ? '' : noDisplay) + '">' + o[litem + 'Text'] + '</dt>' +378 '<dd class="ui_tpicker_' + litem + (show ? '' : noDisplay) + '"><div class="ui_tpicker_' + litem + '_slider' + (show ? '' : noDisplay) + '"></div>';379 if (show && o[litem + 'Grid'] > 0) {380 html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';381 if (litem === 'hour') {382 for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) {383 gridSize[litem]++;384 var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o);385 html += '<td data-for="' + litem + '">' + tmph + '</td>';386 }387 }388 else {389 for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) {390 gridSize[litem]++;391 html += '<td data-for="' + litem + '">' + ((m < 10) ? '0' : '') + m + '</td>';392 }393 }394 html += '</tr></table></div>';395 }396 html += '</dd>';397 }398 // Timezone399 var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone;400 html += '<dt class="ui_tpicker_timezone_label' + (showTz ? '' : noDisplay) + '">' + o.timezoneText + '</dt>';401 html += '<dd class="ui_tpicker_timezone' + (showTz ? '' : noDisplay) + '"></dd>';402 // Create the elements from string403 html += '</dl></div>';404 var $tp = $(html);405 // if we only want time picker...406 if (o.timeOnly === true) {407 $tp.prepend('<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + '</div>');408 $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();409 }410 // add sliders, adjust grids, add events411 for (i = 0, l = tp_inst.units.length; i < l; i++) {412 litem = tp_inst.units[i];413 uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);414 show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];415 // add the slider416 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]);417 // adjust the grid and add click event418 if (show && o[litem + 'Grid'] > 0) {419 size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']);420 $tp.find('.ui_tpicker_' + litem + ' table').css({421 width: size + "%",422 marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + "%"),423 marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + "%") : '0',424 borderCollapse: 'collapse'425 }).find("td").click(function (e) {426 var $t = $(this),427 h = $t.html(),428 n = parseInt(h.replace(/[^0-9]/g), 10),429 ap = h.replace(/[^apm]/ig),430 f = $t.data('for'); // loses scope, so we use data-for431 if (f === 'hour') {432 if (ap.indexOf('p') !== -1 && n < 12) {433 n += 12;434 }435 else {436 if (ap.indexOf('a') !== -1 && n === 12) {437 n = 0;438 }439 }440 }441 tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n);442 tp_inst._onTimeChange();443 tp_inst._onSelectHandler();444 }).css({445 cursor: 'pointer',446 width: (100 / gridSize[litem]) + '%',447 textAlign: 'center',448 overflow: 'hidden'449 });450 } // end if grid > 0451 } // end for loop452 // Add timezone options453 this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find("select");454 $.fn.append.apply(this.timezone_select,455 $.map(o.timezoneList, function (val, idx) {456 return $("<option />").val(typeof val === "object" ? val.value : val).text(typeof val === "object" ? val.label : val);457 }));458 if (typeof(this.timezone) !== "undefined" && this.timezone !== null && this.timezone !== "") {459 var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1;460 if (local_timezone === this.timezone) {461 selectLocalTimezone(tp_inst);462 } else {463 this.timezone_select.val(this.timezone);464 }465 } else {466 if (typeof(this.hour) !== "undefined" && this.hour !== null && this.hour !== "") {467 this.timezone_select.val(o.timezone);468 } else {469 selectLocalTimezone(tp_inst);470 }471 }472 this.timezone_select.change(function () {473 tp_inst._onTimeChange();474 tp_inst._onSelectHandler();475 tp_inst._afterInject();476 });477 // End timezone options478 // inject timepicker into datepicker479 var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');480 if ($buttonPanel.length) {481 $buttonPanel.before($tp);482 } else {483 $dp.append($tp);484 }485 this.$timeObj = $tp.find('.ui_tpicker_time_input');486 this.$timeObj.change(function () {487 var timeFormat = tp_inst.inst.settings.timeFormat;488 var parsedTime = $.datepicker.parseTime(timeFormat, this.value);489 var update = new Date();490 if (parsedTime) {491 update.setHours(parsedTime.hour);492 update.setMinutes(parsedTime.minute);493 update.setSeconds(parsedTime.second);494 $.datepicker._setTime(tp_inst.inst, update);495 } else {496 this.value = tp_inst.formattedTime;497 this.blur();498 }499 });500 if (this.inst !== null) {501 var timeDefined = this.timeDefined;502 this._onTimeChange();503 this.timeDefined = timeDefined;504 }505 // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/506 if (this._defaults.addSliderAccess) {507 var sliderAccessArgs = this._defaults.sliderAccessArgs,508 rtl = this._defaults.isRTL;509 sliderAccessArgs.isRTL = rtl;510 setTimeout(function () { // fix for inline mode511 if ($tp.find('.ui-slider-access').length === 0) {512 $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);513 // fix any grids since sliders are shorter514 var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);515 if (sliderAccessWidth) {516 $tp.find('table:visible').each(function () {517 var $g = $(this),518 oldWidth = $g.outerWidth(),519 oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''),520 newWidth = oldWidth - sliderAccessWidth,521 newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%',522 css = { width: newWidth, marginRight: 0, marginLeft: 0 };523 css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft;524 $g.css(css);525 });526 }527 }528 }, 10);529 }530 // end slideAccess integration531 tp_inst._limitMinMaxDateTime(this.inst, true);532 }533 },534 /*535 * This function tries to limit the ability to go outside the536 * min/max date range537 */538 _limitMinMaxDateTime: function (dp_inst, adjustSliders) {539 var o = this._defaults,540 dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);541 if (!this._defaults.showTimepicker) {542 return;543 } // No time so nothing to check here544 if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) {545 var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),546 minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);547 if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) {548 this.hourMinOriginal = o.hourMin;549 this.minuteMinOriginal = o.minuteMin;550 this.secondMinOriginal = o.secondMin;551 this.millisecMinOriginal = o.millisecMin;552 this.microsecMinOriginal = o.microsecMin;553 }554 if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) {555 this._defaults.hourMin = minDateTime.getHours();556 if (this.hour <= this._defaults.hourMin) {557 this.hour = this._defaults.hourMin;558 this._defaults.minuteMin = minDateTime.getMinutes();559 if (this.minute <= this._defaults.minuteMin) {560 this.minute = this._defaults.minuteMin;561 this._defaults.secondMin = minDateTime.getSeconds();562 if (this.second <= this._defaults.secondMin) {563 this.second = this._defaults.secondMin;564 this._defaults.millisecMin = minDateTime.getMilliseconds();565 if (this.millisec <= this._defaults.millisecMin) {566 this.millisec = this._defaults.millisecMin;567 this._defaults.microsecMin = minDateTime.getMicroseconds();568 } else {569 if (this.microsec < this._defaults.microsecMin) {570 this.microsec = this._defaults.microsecMin;571 }572 this._defaults.microsecMin = this.microsecMinOriginal;573 }574 } else {575 this._defaults.millisecMin = this.millisecMinOriginal;576 this._defaults.microsecMin = this.microsecMinOriginal;577 }578 } else {579 this._defaults.secondMin = this.secondMinOriginal;580 this._defaults.millisecMin = this.millisecMinOriginal;581 this._defaults.microsecMin = this.microsecMinOriginal;582 }583 } else {584 this._defaults.minuteMin = this.minuteMinOriginal;585 this._defaults.secondMin = this.secondMinOriginal;586 this._defaults.millisecMin = this.millisecMinOriginal;587 this._defaults.microsecMin = this.microsecMinOriginal;588 }589 } else {590 this._defaults.hourMin = this.hourMinOriginal;591 this._defaults.minuteMin = this.minuteMinOriginal;592 this._defaults.secondMin = this.secondMinOriginal;593 this._defaults.millisecMin = this.millisecMinOriginal;594 this._defaults.microsecMin = this.microsecMinOriginal;595 }596 }597 if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) {598 var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),599 maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);600 if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) {601 this.hourMaxOriginal = o.hourMax;602 this.minuteMaxOriginal = o.minuteMax;603 this.secondMaxOriginal = o.secondMax;604 this.millisecMaxOriginal = o.millisecMax;605 this.microsecMaxOriginal = o.microsecMax;606 }607 if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) {608 this._defaults.hourMax = maxDateTime.getHours();609 if (this.hour >= this._defaults.hourMax) {610 this.hour = this._defaults.hourMax;611 this._defaults.minuteMax = maxDateTime.getMinutes();612 if (this.minute >= this._defaults.minuteMax) {613 this.minute = this._defaults.minuteMax;614 this._defaults.secondMax = maxDateTime.getSeconds();615 if (this.second >= this._defaults.secondMax) {616 this.second = this._defaults.secondMax;617 this._defaults.millisecMax = maxDateTime.getMilliseconds();618 if (this.millisec >= this._defaults.millisecMax) {619 this.millisec = this._defaults.millisecMax;620 this._defaults.microsecMax = maxDateTime.getMicroseconds();621 } else {622 if (this.microsec > this._defaults.microsecMax) {623 this.microsec = this._defaults.microsecMax;624 }625 this._defaults.microsecMax = this.microsecMaxOriginal;626 }627 } else {628 this._defaults.millisecMax = this.millisecMaxOriginal;629 this._defaults.microsecMax = this.microsecMaxOriginal;630 }631 } else {632 this._defaults.secondMax = this.secondMaxOriginal;633 this._defaults.millisecMax = this.millisecMaxOriginal;634 this._defaults.microsecMax = this.microsecMaxOriginal;635 }636 } else {637 this._defaults.minuteMax = this.minuteMaxOriginal;638 this._defaults.secondMax = this.secondMaxOriginal;639 this._defaults.millisecMax = this.millisecMaxOriginal;640 this._defaults.microsecMax = this.microsecMaxOriginal;641 }642 } else {643 this._defaults.hourMax = this.hourMaxOriginal;644 this._defaults.minuteMax = this.minuteMaxOriginal;645 this._defaults.secondMax = this.secondMaxOriginal;646 this._defaults.millisecMax = this.millisecMaxOriginal;647 this._defaults.microsecMax = this.microsecMaxOriginal;648 }649 }650 if (dp_inst.settings.minTime!==null) {651 var tempMinTime=new Date("01/01/1970 " + dp_inst.settings.minTime);652 if (this.hour<tempMinTime.getHours()) {653 this.hour=this._defaults.hourMin=tempMinTime.getHours();654 this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();655 } else if (this.hour===tempMinTime.getHours() && this.minute<tempMinTime.getMinutes()) {656 this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();657 } else {658 if (this._defaults.hourMin<tempMinTime.getHours()) {659 this._defaults.hourMin=tempMinTime.getHours();660 this._defaults.minuteMin=tempMinTime.getMinutes();661 } else if (this._defaults.hourMin===tempMinTime.getHours()===this.hour && this._defaults.minuteMin<tempMinTime.getMinutes()) {662 this._defaults.minuteMin=tempMinTime.getMinutes();663 } else {664 this._defaults.minuteMin=0;665 }666 }667 }668 if (dp_inst.settings.maxTime!==null) {669 var tempMaxTime=new Date("01/01/1970 " + dp_inst.settings.maxTime);670 if (this.hour>tempMaxTime.getHours()) {671 this.hour=this._defaults.hourMax=tempMaxTime.getHours();672 this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();673 } else if (this.hour===tempMaxTime.getHours() && this.minute>tempMaxTime.getMinutes()) {674 this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();675 } else {676 if (this._defaults.hourMax>tempMaxTime.getHours()) {677 this._defaults.hourMax=tempMaxTime.getHours();678 this._defaults.minuteMax=tempMaxTime.getMinutes();679 } else if (this._defaults.hourMax===tempMaxTime.getHours()===this.hour && this._defaults.minuteMax>tempMaxTime.getMinutes()) {680 this._defaults.minuteMax=tempMaxTime.getMinutes();681 } else {682 this._defaults.minuteMax=59;683 }684 }685 }686 if (adjustSliders !== undefined && adjustSliders === true) {687 var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10),688 minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10),689 secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10),690 millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10),691 microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10);692 if (this.hour_slider) {693 this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax, step: this._defaults.stepHour });694 this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour));695 }696 if (this.minute_slider) {697 this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax, step: this._defaults.stepMinute });698 this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute));699 }700 if (this.second_slider) {701 this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax, step: this._defaults.stepSecond });702 this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond));703 }704 if (this.millisec_slider) {705 this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax, step: this._defaults.stepMillisec });706 this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec));707 }708 if (this.microsec_slider) {709 this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax, step: this._defaults.stepMicrosec });710 this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec));711 }712 }713 },714 /*715 * when a slider moves, set the internal time...716 * on time change is also called when the time is updated in the text field717 */718 _onTimeChange: function () {719 if (!this._defaults.showTimepicker) {720 return;721 }722 var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false,723 minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false,724 second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false,725 millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false,726 microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false,727 timezone = (this.timezone_select) ? this.timezone_select.val() : false,728 o = this._defaults,729 pickerTimeFormat = o.pickerTimeFormat || o.timeFormat,730 pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix;731 if (typeof(hour) === 'object') {732 hour = false;733 }734 if (typeof(minute) === 'object') {735 minute = false;736 }737 if (typeof(second) === 'object') {738 second = false;739 }740 if (typeof(millisec) === 'object') {741 millisec = false;742 }743 if (typeof(microsec) === 'object') {744 microsec = false;745 }746 if (typeof(timezone) === 'object') {747 timezone = false;748 }749 if (hour !== false) {750 hour = parseInt(hour, 10);751 }752 if (minute !== false) {753 minute = parseInt(minute, 10);754 }755 if (second !== false) {756 second = parseInt(second, 10);757 }758 if (millisec !== false) {759 millisec = parseInt(millisec, 10);760 }761 if (microsec !== false) {762 microsec = parseInt(microsec, 10);763 }764 if (timezone !== false) {765 timezone = timezone.toString();766 }767 var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];768 // If the update was done in the input field, the input field should not be updated.769 // If the update was done using the sliders, update the input field.770 var hasChanged = (771 hour !== parseInt(this.hour,10) || // sliders should all be numeric772 minute !== parseInt(this.minute,10) ||773 second !== parseInt(this.second,10) ||774 millisec !== parseInt(this.millisec,10) ||775 microsec !== parseInt(this.microsec,10) ||776 (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) ||777 (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or "EST" format, so use toString()778 );779 if (hasChanged) {780 if (hour !== false) {781 this.hour = hour;782 }783 if (minute !== false) {784 this.minute = minute;785 }786 if (second !== false) {787 this.second = second;788 }789 if (millisec !== false) {790 this.millisec = millisec;791 }792 if (microsec !== false) {793 this.microsec = microsec;794 }795 if (timezone !== false) {796 this.timezone = timezone;797 }798 if (!this.inst) {799 this.inst = $.datepicker._getInst(this.$input[0]);800 }801 this._limitMinMaxDateTime(this.inst, true);802 }803 if (this.support.ampm) {804 this.ampm = ampm;805 }806 // Updates the time within the timepicker807 this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o);808 if (this.$timeObj) {809 var sPos = this.$timeObj[0].selectionStart;810 var ePos = this.$timeObj[0].selectionEnd;811 if (pickerTimeFormat === o.timeFormat) {812 this.$timeObj.val(this.formattedTime + pickerTimeSuffix);813 }814 else {815 this.$timeObj.val($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix);816 }817 this.$timeObj[0].setSelectionRange(sPos, ePos);818 }819 this.timeDefined = true;820 if (hasChanged) {821 this._updateDateTime();822 //this.$input.focus(); // may automatically open the picker on setDate823 }824 },825 /*826 * call custom onSelect.827 * bind to sliders slidestop, and grid click.828 */829 _onSelectHandler: function () {830 var onSelect = this._defaults.onSelect || this.inst.settings.onSelect;831 var inputEl = this.$input ? this.$input[0] : null;832 if (onSelect && inputEl) {833 onSelect.apply(inputEl, [this.formattedDateTime, this]);834 }835 },836 /*837 * update our input with the new date time..838 */839 _updateDateTime: function (dp_inst) {840 dp_inst = this.inst || dp_inst;841 var dtTmp = (dp_inst.currentYear > 0?842 new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) :843 new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),844 dt = $.datepicker._daylightSavingAdjust(dtTmp),845 //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),846 //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)),847 dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),848 formatCfg = $.datepicker._getFormatConfig(dp_inst),849 timeAvailable = dt !== null && this.timeDefined;850 this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);851 var formattedDateTime = this.formattedDate;852 // if a slider was changed but datepicker doesn't have a value yet, set it853 if (dp_inst.lastVal === "") {854 dp_inst.currentYear = dp_inst.selectedYear;855 dp_inst.currentMonth = dp_inst.selectedMonth;856 dp_inst.currentDay = dp_inst.selectedDay;857 }858 /*859 * remove following lines to force every changes in date picker to change the input value860 * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker.861 * If the user manually empty the value in the input field, the date picker will never change selected value.862 */863 //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) {864 // return;865 //}866 if (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === false) {867 formattedDateTime = this.formattedTime;868 } else if ((this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) || (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === true)) {869 formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;870 }871 this.formattedDateTime = formattedDateTime;872 if (!this._defaults.showTimepicker) {873 this.$input.val(this.formattedDate);874 } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) {875 this.$altInput.val(this.formattedTime);876 this.$input.val(this.formattedDate);877 } else if (this.$altInput) {878 this.$input.val(formattedDateTime);879 var altFormattedDateTime = '',880 altSeparator = this._defaults.altSeparator !== null ? this._defaults.altSeparator : this._defaults.separator,881 altTimeSuffix = this._defaults.altTimeSuffix !== null ? this._defaults.altTimeSuffix : this._defaults.timeSuffix;882 if (!this._defaults.timeOnly) {883 if (this._defaults.altFormat) {884 altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg);885 }886 else {887 altFormattedDateTime = this.formattedDate;888 }889 if (altFormattedDateTime) {890 altFormattedDateTime += altSeparator;891 }892 }893 if (this._defaults.altTimeFormat !== null) {894 altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix;895 }896 else {897 altFormattedDateTime += this.formattedTime + altTimeSuffix;898 }899 this.$altInput.val(altFormattedDateTime);900 } else {901 this.$input.val(formattedDateTime);902 }903 this.$input.trigger("change");904 },905 _onFocus: function () {906 if (!this.$input.val() && this._defaults.defaultValue) {907 this.$input.val(this._defaults.defaultValue);908 var inst = $.datepicker._getInst(this.$input.get(0)),909 tp_inst = $.datepicker._get(inst, 'timepicker');910 if (tp_inst) {911 if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {912 try {913 $.datepicker._updateDatepicker(inst);914 } catch (err) {915 $.timepicker.log(err);916 }917 }918 }919 }920 },921 /*922 * Small abstraction to control types923 * We can add more, just be sure to follow the pattern: create, options, value924 */925 _controls: {926 // slider methods927 slider: {928 create: function (tp_inst, obj, unit, val, min, max, step) {929 var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60930 return obj.prop('slide', null).slider({931 orientation: "horizontal",932 value: rtl ? val * -1 : val,933 min: rtl ? max * -1 : min,934 max: rtl ? min * -1 : max,935 step: step,936 slide: function (event, ui) {937 tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value);938 tp_inst._onTimeChange();939 },940 stop: function (event, ui) {941 tp_inst._onSelectHandler();942 }943 });944 },945 options: function (tp_inst, obj, unit, opts, val) {946 if (tp_inst._defaults.isRTL) {947 if (typeof(opts) === 'string') {948 if (opts === 'min' || opts === 'max') {949 if (val !== undefined) {950 return obj.slider(opts, val * -1);951 }952 return Math.abs(obj.slider(opts));953 }954 return obj.slider(opts);955 }956 var min = opts.min,957 max = opts.max;958 opts.min = opts.max = null;959 if (min !== undefined) {960 opts.max = min * -1;961 }962 if (max !== undefined) {963 opts.min = max * -1;964 }965 return obj.slider(opts);966 }967 if (typeof(opts) === 'string' && val !== undefined) {968 return obj.slider(opts, val);969 }970 return obj.slider(opts);971 },972 value: function (tp_inst, obj, unit, val) {973 if (tp_inst._defaults.isRTL) {974 if (val !== undefined) {975 return obj.slider('value', val * -1);976 }977 return Math.abs(obj.slider('value'));978 }979 if (val !== undefined) {980 return obj.slider('value', val);981 }982 return obj.slider('value');983 }984 },985 // select methods986 select: {987 create: function (tp_inst, obj, unit, val, min, max, step) {988 var sel = '<select class="ui-timepicker-select ui-state-default ui-corner-all" data-unit="' + unit + '" data-min="' + min + '" data-max="' + max + '" data-step="' + step + '">',989 format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat;990 for (var i = min; i <= max; i += step) {991 sel += '<option value="' + i + '"' + (i === val ? ' selected' : '') + '>';992 if (unit === 'hour') {993 sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults);994 }995 else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; }996 else {sel += '0' + i.toString(); }997 sel += '</option>';998 }999 sel += '</select>';1000 obj.children('select').remove();1001 $(sel).appendTo(obj).change(function (e) {1002 tp_inst._onTimeChange();1003 tp_inst._onSelectHandler();1004 tp_inst._afterInject();1005 });1006 return obj;1007 },1008 options: function (tp_inst, obj, unit, opts, val) {1009 var o = {},1010 $t = obj.children('select');1011 if (typeof(opts) === 'string') {1012 if (val === undefined) {1013 return $t.data(opts);1014 }1015 o[opts] = val;1016 }1017 else { o = opts; }1018 return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min>=0 ? o.min : $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step'));1019 },1020 value: function (tp_inst, obj, unit, val) {1021 var $t = obj.children('select');1022 if (val !== undefined) {1023 return $t.val(val);1024 }1025 return $t.val();1026 }1027 }1028 } // end _controls1029 });1030 $.fn.extend({1031 /*1032 * shorthand just to use timepicker.1033 */1034 timepicker: function (o) {1035 o = o || {};1036 var tmp_args = Array.prototype.slice.call(arguments);1037 if (typeof o === 'object') {1038 tmp_args[0] = $.extend(o, {1039 timeOnly: true1040 });1041 }1042 return $(this).each(function () {1043 $.fn.datetimepicker.apply($(this), tmp_args);1044 });1045 },1046 /*1047 * extend timepicker to datepicker1048 */1049 datetimepicker: function (o) {1050 o = o || {};1051 var tmp_args = arguments;1052 if (typeof(o) === 'string') {1053 if (o === 'getDate' || (o === 'option' && tmp_args.length === 2 && typeof (tmp_args[1]) === 'string')) {1054 return $.fn.datepicker.apply($(this[0]), tmp_args);1055 } else {1056 return this.each(function () {1057 var $t = $(this);1058 $t.datepicker.apply($t, tmp_args);1059 });1060 }1061 } else {1062 return this.each(function () {1063 var $t = $(this);1064 $t.datepicker($.timepicker._newInst($t, o)._defaults);1065 });1066 }1067 }1068 });1069 /*1070 * Public Utility to parse date and time1071 */1072 $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {1073 var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings);1074 if (parseRes.timeObj) {1075 var t = parseRes.timeObj;1076 parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec);1077 parseRes.date.setMicroseconds(t.microsec);1078 }1079 return parseRes.date;1080 };1081 /*1082 * Public utility to parse time1083 */1084 $.datepicker.parseTime = function (timeFormat, timeString, options) {1085 var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}),1086 iso8601 = (timeFormat.replace(/\'.*?\'/g, '').indexOf('Z') !== -1);1087 // Strict parse requires the timeString to match the timeFormat exactly1088 var strictParse = function (f, s, o) {1089 // pattern for standard and localized AM/PM markers1090 var getPatternAmpm = function (amNames, pmNames) {1091 var markers = [];1092 if (amNames) {1093 $.merge(markers, amNames);1094 }1095 if (pmNames) {1096 $.merge(markers, pmNames);1097 }1098 markers = $.map(markers, function (val) {1099 return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&');1100 });1101 return '(' + markers.join('|') + ')?';1102 };1103 // figure out position of time elements.. cause js cant do named captures1104 var getFormatPositions = function (timeFormat) {1105 var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),1106 orders = {1107 h: -1,1108 m: -1,1109 s: -1,1110 l: -1,1111 c: -1,1112 t: -1,1113 z: -11114 };1115 if (finds) {1116 for (var i = 0; i < finds.length; i++) {1117 if (orders[finds[i].toString().charAt(0)] === -1) {1118 orders[finds[i].toString().charAt(0)] = i + 1;1119 }1120 }1121 }1122 return orders;1123 };1124 var regstr = '^' + f.toString()1125 .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {1126 var ml = match.length;1127 switch (match.charAt(0).toLowerCase()) {1128 case 'h':1129 return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';1130 case 'm':1131 return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';1132 case 's':1133 return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';1134 case 'l':1135 return '(\\d?\\d?\\d)';1136 case 'c':1137 return '(\\d?\\d?\\d)';1138 case 'z':1139 return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?';1140 case 't':1141 return getPatternAmpm(o.amNames, o.pmNames);1142 default: // literal escaped in quotes1143 return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?';1144 }1145 })1146 .replace(/\s/g, '\\s?') +1147 o.timeSuffix + '$',1148 order = getFormatPositions(f),1149 ampm = '',1150 treg;1151 treg = s.match(new RegExp(regstr, 'i'));1152 var resTime = {1153 hour: 0,1154 minute: 0,1155 second: 0,1156 millisec: 0,1157 microsec: 01158 };1159 if (treg) {1160 if (order.t !== -1) {1161 if (treg[order.t] === undefined || treg[order.t].length === 0) {1162 ampm = '';1163 resTime.ampm = '';1164 } else {1165 ampm = $.inArray(treg[order.t].toUpperCase(), $.map(o.amNames, function (x,i) { return x.toUpperCase(); })) !== -1 ? 'AM' : 'PM';1166 resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0];1167 }1168 }1169 if (order.h !== -1) {1170 if (ampm === 'AM' && treg[order.h] === '12') {1171 resTime.hour = 0; // 12am = 0 hour1172 } else {1173 if (ampm === 'PM' && treg[order.h] !== '12') {1174 resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 121175 } else {1176 resTime.hour = Number(treg[order.h]);1177 }1178 }1179 }1180 if (order.m !== -1) {1181 resTime.minute = Number(treg[order.m]);1182 }1183 if (order.s !== -1) {1184 resTime.second = Number(treg[order.s]);1185 }1186 if (order.l !== -1) {1187 resTime.millisec = Number(treg[order.l]);1188 }1189 if (order.c !== -1) {1190 resTime.microsec = Number(treg[order.c]);1191 }1192 if (order.z !== -1 && treg[order.z] !== undefined) {1193 resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]);1194 }1195 return resTime;1196 }1197 return false;1198 };// end strictParse1199 // First try JS Date, if that fails, use strictParse1200 var looseParse = function (f, s, o) {1201 try {1202 var d = new Date('2012-01-01 ' + s);1203 if (isNaN(d.getTime())) {1204 d = new Date('2012-01-01T' + s);1205 if (isNaN(d.getTime())) {1206 d = new Date('01/01/2012 ' + s);1207 if (isNaN(d.getTime())) {1208 throw "Unable to parse time with native Date: " + s;1209 }1210 }1211 }1212 return {1213 hour: d.getHours(),1214 minute: d.getMinutes(),1215 second: d.getSeconds(),1216 millisec: d.getMilliseconds(),1217 microsec: d.getMicroseconds(),1218 timezone: d.getTimezoneOffset() * -11219 };1220 }1221 catch (err) {1222 try {1223 return strictParse(f, s, o);1224 }1225 catch (err2) {1226 $.timepicker.log("Unable to parse \ntimeString: " + s + "\ntimeFormat: " + f);1227 }1228 }1229 return false;1230 }; // end looseParse1231 if (typeof o.parse === "function") {1232 return o.parse(timeFormat, timeString, o);1233 }1234 if (o.parse === 'loose') {1235 return looseParse(timeFormat, timeString, o);1236 }1237 return strictParse(timeFormat, timeString, o);1238 };1239 /**1240 * Public utility to format the time1241 * @param {string} format format of the time1242 * @param {Object} time Object not a Date for timezones1243 * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm1244 * @returns {string} the formatted time1245 */1246 $.datepicker.formatTime = function (format, time, options) {1247 options = options || {};1248 options = $.extend({}, $.timepicker._defaults, options);1249 time = $.extend({1250 hour: 0,1251 minute: 0,1252 second: 0,1253 millisec: 0,1254 microsec: 0,1255 timezone: null1256 }, time);1257 var tmptime = format,1258 ampmName = options.amNames[0],1259 hour = parseInt(time.hour, 10);1260 if (hour > 11) {1261 ampmName = options.pmNames[0];1262 }1263 tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {1264 switch (match) {1265 case 'HH':1266 return ('0' + hour).slice(-2);1267 case 'H':1268 return hour;1269 case 'hh':1270 return ('0' + convert24to12(hour)).slice(-2);1271 case 'h':1272 return convert24to12(hour);1273 case 'mm':1274 return ('0' + time.minute).slice(-2);1275 case 'm':1276 return time.minute;1277 case 'ss':1278 return ('0' + time.second).slice(-2);1279 case 's':1280 return time.second;1281 case 'l':1282 return ('00' + time.millisec).slice(-3);1283 case 'c':1284 return ('00' + time.microsec).slice(-3);1285 case 'z':1286 return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false);1287 case 'Z':1288 return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true);1289 case 'T':1290 return ampmName.charAt(0).toUpperCase();1291 case 'TT':1292 return ampmName.toUpperCase();1293 case 't':1294 return ampmName.charAt(0).toLowerCase();1295 case 'tt':1296 return ampmName.toLowerCase();1297 default:1298 return match.replace(/'/g, "");1299 }1300 });1301 return tmptime;1302 };1303 /*1304 * the bad hack :/ override datepicker so it doesn't close on select1305 // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#17623781306 */1307 $.datepicker._base_selectDate = $.datepicker._selectDate;1308 $.datepicker._selectDate = function (id, dateStr) {1309 var inst = this._getInst($(id)[0]),1310 tp_inst = this._get(inst, 'timepicker'),1311 was_inline;1312 if (tp_inst && inst.settings.showTimepicker) {1313 tp_inst._limitMinMaxDateTime(inst, true);1314 was_inline = inst.inline;1315 inst.inline = inst.stay_open = true;1316 //This way the onSelect handler called from calendarpicker get the full dateTime1317 this._base_selectDate(id, dateStr);1318 inst.inline = was_inline;1319 inst.stay_open = false;1320 this._notifyChange(inst);1321 this._updateDatepicker(inst);1322 } else {1323 this._base_selectDate(id, dateStr);1324 }1325 };1326 /*1327 * second bad hack :/ override datepicker so it triggers an event when changing the input field1328 * and does not redraw the datepicker on every selectDate event1329 */1330 $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;1331 $.datepicker._updateDatepicker = function (inst) {1332 // don't popup the datepicker if there is another instance already opened1333 var input = inst.input[0];1334 if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) {1335 return;1336 }1337 if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {1338 this._base_updateDatepicker(inst);1339 // Reload the time control when changing something in the input text field.1340 var tp_inst = this._get(inst, 'timepicker');1341 if (tp_inst) {1342 tp_inst._addTimePicker(inst);1343 }1344 }1345 };1346 /*1347 * third bad hack :/ override datepicker so it allows spaces and colon in the input field1348 */1349 $.datepicker._base_doKeyPress = $.datepicker._doKeyPress;1350 $.datepicker._doKeyPress = function (event) {1351 var inst = $.datepicker._getInst(event.target),1352 tp_inst = $.datepicker._get(inst, 'timepicker');1353 if (tp_inst) {1354 if ($.datepicker._get(inst, 'constrainInput')) {1355 var ampm = tp_inst.support.ampm,1356 tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone,1357 dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),1358 datetimeChars = tp_inst._defaults.timeFormat.toString()1359 .replace(/[hms]/g, '')1360 .replace(/TT/g, ampm ? 'APM' : '')1361 .replace(/Tt/g, ampm ? 'AaPpMm' : '')1362 .replace(/tT/g, ampm ? 'AaPpMm' : '')1363 .replace(/T/g, ampm ? 'AP' : '')1364 .replace(/tt/g, ampm ? 'apm' : '')1365 .replace(/t/g, ampm ? 'ap' : '') +1366 " " + tp_inst._defaults.separator +1367 tp_inst._defaults.timeSuffix +1368 (tz ? tp_inst._defaults.timezoneList.join('') : '') +1369 (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) +1370 dateChars,1371 chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);1372 return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);1373 }1374 }1375 return $.datepicker._base_doKeyPress(event);1376 };1377 /*1378 * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField1379 * Update any alternate field to synchronise with the main field.1380 */1381 $.datepicker._base_updateAlternate = $.datepicker._updateAlternate;1382 $.datepicker._updateAlternate = function (inst) {1383 var tp_inst = this._get(inst, 'timepicker');1384 if (tp_inst) {1385 var altField = tp_inst._defaults.altField;1386 if (altField) { // update alternate field too1387 var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat,1388 date = this._getDate(inst),1389 formatCfg = $.datepicker._getFormatConfig(inst),1390 altFormattedDateTime = '',1391 altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator,1392 altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix,1393 altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat;1394 altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix;1395 if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) {1396 if (tp_inst._defaults.altFormat) {1397 altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime;1398 }1399 else {1400 altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime;1401 }1402 }1403 $(altField).val( inst.input.val() ? altFormattedDateTime : "");1404 }1405 }1406 else {1407 $.datepicker._base_updateAlternate(inst);1408 }1409 };1410 /*1411 * Override key up event to sync manual input changes.1412 */1413 $.datepicker._base_doKeyUp = $.datepicker._doKeyUp;1414 $.datepicker._doKeyUp = function (event) {1415 var inst = $.datepicker._getInst(event.target),1416 tp_inst = $.datepicker._get(inst, 'timepicker');1417 if (tp_inst) {1418 if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {1419 try {1420 $.datepicker._updateDatepicker(inst);1421 } catch (err) {1422 $.timepicker.log(err);1423 }1424 }1425 }1426 return $.datepicker._base_doKeyUp(event);1427 };1428 /*1429 * override "Today" button to also grab the time and set it to input field.1430 */1431 $.datepicker._base_gotoToday = $.datepicker._gotoToday;1432 $.datepicker._gotoToday = function (id) {1433 var inst = this._getInst($(id)[0]);1434 this._base_gotoToday(id);1435 var tp_inst = this._get(inst, 'timepicker');1436 var tzoffset = $.timepicker.timezoneOffsetNumber(tp_inst.timezone);1437 var now = new Date();1438 now.setMinutes(now.getMinutes() + now.getTimezoneOffset() + tzoffset);1439 this._setTime(inst, now);1440 this._setDate(inst, now);1441 tp_inst._onSelectHandler();1442 };1443 /*1444 * Disable & enable the Time in the datetimepicker1445 */1446 $.datepicker._disableTimepickerDatepicker = function (target) {1447 var inst = this._getInst(target);1448 if (!inst) {1449 return;1450 }1451 var tp_inst = this._get(inst, 'timepicker');1452 $(target).datepicker('getDate'); // Init selected[Year|Month|Day]1453 if (tp_inst) {1454 inst.settings.showTimepicker = false;1455 tp_inst._defaults.showTimepicker = false;1456 tp_inst._updateDateTime(inst);1457 }1458 };1459 $.datepicker._enableTimepickerDatepicker = function (target) {1460 var inst = this._getInst(target);1461 if (!inst) {1462 return;1463 }1464 var tp_inst = this._get(inst, 'timepicker');1465 $(target).datepicker('getDate'); // Init selected[Year|Month|Day]1466 if (tp_inst) {1467 inst.settings.showTimepicker = true;1468 tp_inst._defaults.showTimepicker = true;1469 tp_inst._addTimePicker(inst); // Could be disabled on page load1470 tp_inst._updateDateTime(inst);1471 }1472 };1473 /*1474 * Create our own set time function1475 */1476 $.datepicker._setTime = function (inst, date) {1477 var tp_inst = this._get(inst, 'timepicker');1478 if (tp_inst) {1479 var defaults = tp_inst._defaults;1480 // calling _setTime with no date sets time to defaults1481 tp_inst.hour = date ? date.getHours() : defaults.hour;1482 tp_inst.minute = date ? date.getMinutes() : defaults.minute;1483 tp_inst.second = date ? date.getSeconds() : defaults.second;1484 tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec;1485 tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec;1486 //check if within min/max times..1487 tp_inst._limitMinMaxDateTime(inst, true);1488 tp_inst._onTimeChange();1489 tp_inst._updateDateTime(inst);1490 }1491 };1492 /*1493 * Create new public method to set only time, callable as $().datepicker('setTime', date)1494 */1495 $.datepicker._setTimeDatepicker = function (target, date, withDate) {1496 var inst = this._getInst(target);1497 if (!inst) {1498 return;1499 }1500 var tp_inst = this._get(inst, 'timepicker');1501 if (tp_inst) {1502 this._setDateFromField(inst);1503 var tp_date;1504 if (date) {1505 if (typeof date === "string") {1506 tp_inst._parseTime(date, withDate);1507 tp_date = new Date();1508 tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);1509 tp_date.setMicroseconds(tp_inst.microsec);1510 } else {1511 tp_date = new Date(date.getTime());1512 tp_date.setMicroseconds(date.getMicroseconds());1513 }1514 if (tp_date.toString() === 'Invalid Date') {1515 tp_date = undefined;1516 }1517 this._setTime(inst, tp_date);1518 }1519 }1520 };1521 /*1522 * override setDate() to allow setting time too within Date object1523 */1524 $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;1525 $.datepicker._setDateDatepicker = function (target, _date) {1526 var inst = this._getInst(target);1527 var date = _date;1528 if (!inst) {1529 return;1530 }1531 if (typeof(_date) === 'string') {1532 date = new Date(_date);1533 if (!date.getTime()) {1534 this._base_setDateDatepicker.apply(this, arguments);1535 date = $(target).datepicker('getDate');1536 }1537 }1538 var tp_inst = this._get(inst, 'timepicker');1539 var tp_date;1540 if (date instanceof Date) {1541 tp_date = new Date(date.getTime());1542 tp_date.setMicroseconds(date.getMicroseconds());1543 } else {1544 tp_date = date;1545 }1546 // This is important if you are using the timezone option, javascript's Date1547 // object will only return the timezone offset for the current locale, so we1548 // adjust it accordingly. If not using timezone option this won't matter..1549 // If a timezone is different in tp, keep the timezone as is1550 if (tp_inst && tp_date) {1551 // look out for DST if tz wasn't specified1552 if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {1553 tp_inst.timezone = tp_date.getTimezoneOffset() * -1;1554 }1555 date = $.timepicker.timezoneAdjust(date, tp_inst.timezone);1556 tp_date = $.timepicker.timezoneAdjust(tp_date, tp_inst.timezone);1557 }1558 this._updateDatepicker(inst);1559 this._base_setDateDatepicker.apply(this, arguments);1560 this._setTimeDatepicker(target, tp_date, true);1561 };1562 /*1563 * override getDate() to allow getting time too within Date object1564 */1565 $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;1566 $.datepicker._getDateDatepicker = function (target, noDefault) {1567 var inst = this._getInst(target);1568 if (!inst) {1569 return;1570 }1571 var tp_inst = this._get(inst, 'timepicker');1572 if (tp_inst) {1573 // if it hasn't yet been defined, grab from field1574 if (inst.lastVal === undefined) {1575 this._setDateFromField(inst, noDefault);1576 }1577 var date = this._getDate(inst);1578 var currDT = $.trim((tp_inst.$altInput && tp_inst._defaults.altFieldTimeOnly) ? tp_inst.$input.val() + ' ' + tp_inst.$altInput.val() : tp_inst.$input.val());1579 if (date && tp_inst._parseTime(currDT, !inst.settings.timeOnly)) {1580 date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);1581 date.setMicroseconds(tp_inst.microsec);1582 // This is important if you are using the timezone option, javascript's Date1583 // object will only return the timezone offset for the current locale, so we1584 // adjust it accordingly. If not using timezone option this won't matter..1585 if (tp_inst.timezone != null) {1586 // look out for DST if tz wasn't specified1587 if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {1588 tp_inst.timezone = date.getTimezoneOffset() * -1;1589 }1590 date = $.timepicker.timezoneAdjust(date, tp_inst.timezone);1591 }1592 }1593 return date;1594 }1595 return this._base_getDateDatepicker(target, noDefault);1596 };1597 /*1598 * override parseDate() because UI 1.8.14 throws an error about "Extra characters"1599 * An option in datapicker to ignore extra format characters would be nicer.1600 */1601 $.datepicker._base_parseDate = $.datepicker.parseDate;1602 $.datepicker.parseDate = function (format, value, settings) {1603 var date;1604 try {1605 date = this._base_parseDate(format, value, settings);1606 } catch (err) {1607 // Hack! The error message ends with a colon, a space, and1608 // the "extra" characters. We rely on that instead of1609 // attempting to perfectly reproduce the parsing algorithm.1610 if (err.indexOf(":") >= 0) {1611 date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings);1612 $.timepicker.log("Error parsing the date string: " + err + "\ndate string = " + value + "\ndate format = " + format);1613 } else {1614 throw err;1615 }1616 }1617 return date;1618 };1619 /*1620 * override formatDate to set date with time to the input1621 */1622 $.datepicker._base_formatDate = $.datepicker._formatDate;1623 $.datepicker._formatDate = function (inst, day, month, year) {1624 var tp_inst = this._get(inst, 'timepicker');1625 if (tp_inst) {1626 tp_inst._updateDateTime(inst);1627 return tp_inst.$input.val();1628 }1629 return this._base_formatDate(inst);1630 };1631 /*1632 * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate1633 */1634 $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;1635 $.datepicker._optionDatepicker = function (target, name, value) {1636 var inst = this._getInst(target),1637 name_clone;1638 if (!inst) {1639 return null;1640 }1641 var tp_inst = this._get(inst, 'timepicker');1642 if (tp_inst) {1643 var min = null,1644 max = null,1645 onselect = null,1646 overrides = tp_inst._defaults.evnts,1647 fns = {},1648 prop,1649 ret,1650 oldVal,1651 $target;1652 if (typeof name === 'string') { // if min/max was set with the string1653 if (name === 'minDate' || name === 'minDateTime') {1654 min = value;1655 } else if (name === 'maxDate' || name === 'maxDateTime') {1656 max = value;1657 } else if (name === 'onSelect') {1658 onselect = value;1659 } else if (overrides.hasOwnProperty(name)) {1660 if (typeof (value) === 'undefined') {1661 return overrides[name];1662 }1663 fns[name] = value;1664 name_clone = {}; //empty results in exiting function after overrides updated1665 }1666 } else if (typeof name === 'object') { //if min/max was set with the JSON1667 if (name.minDate) {1668 min = name.minDate;1669 } else if (name.minDateTime) {1670 min = name.minDateTime;1671 } else if (name.maxDate) {1672 max = name.maxDate;1673 } else if (name.maxDateTime) {1674 max = name.maxDateTime;1675 }1676 for (prop in overrides) {1677 if (overrides.hasOwnProperty(prop) && name[prop]) {1678 fns[prop] = name[prop];1679 }1680 }1681 }1682 for (prop in fns) {1683 if (fns.hasOwnProperty(prop)) {1684 overrides[prop] = fns[prop];1685 if (!name_clone) { name_clone = $.extend({}, name); }1686 delete name_clone[prop];1687 }1688 }1689 if (name_clone && isEmptyObject(name_clone)) { return; }1690 if (min) { //if min was set1691 if (min === 0) {1692 min = new Date();1693 } else {1694 min = new Date(min);1695 }1696 tp_inst._defaults.minDate = min;1697 tp_inst._defaults.minDateTime = min;1698 } else if (max) { //if max was set1699 if (max === 0) {1700 max = new Date();1701 } else {1702 max = new Date(max);1703 }1704 tp_inst._defaults.maxDate = max;1705 tp_inst._defaults.maxDateTime = max;1706 } else if (onselect) {1707 tp_inst._defaults.onSelect = onselect;1708 }1709 // Datepicker will override our date when we call _base_optionDatepicker when1710 // calling minDate/maxDate, so we will first grab the value, call1711 // _base_optionDatepicker, then set our value back.1712 if(min || max){1713 $target = $(target);1714 oldVal = $target.datetimepicker('getDate');1715 ret = this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);1716 $target.datetimepicker('setDate', oldVal);1717 return ret;1718 }1719 }1720 if (value === undefined) {1721 return this._base_optionDatepicker.call($.datepicker, target, name);1722 }1723 return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);1724 };1725 /*1726 * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype,1727 * it will return false for all objects1728 */1729 var isEmptyObject = function (obj) {1730 var prop;1731 for (prop in obj) {1732 if (obj.hasOwnProperty(prop)) {1733 return false;1734 }1735 }1736 return true;1737 };1738 /*1739 * jQuery extend now ignores nulls!1740 */1741 var extendRemove = function (target, props) {1742 $.extend(target, props);1743 for (var name in props) {1744 if (props[name] === null || props[name] === undefined) {1745 target[name] = props[name];1746 }1747 }1748 return target;1749 };1750 /*1751 * Determine by the time format which units are supported1752 * Returns an object of booleans for each unit1753 */1754 var detectSupport = function (timeFormat) {1755 var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals1756 isIn = function (f, t) { // does the format contain the token?1757 return f.indexOf(t) !== -1 ? true : false;1758 };1759 return {1760 hour: isIn(tf, 'h'),1761 minute: isIn(tf, 'm'),1762 second: isIn(tf, 's'),1763 millisec: isIn(tf, 'l'),1764 microsec: isIn(tf, 'c'),1765 timezone: isIn(tf, 'z'),1766 ampm: isIn(tf, 't') && isIn(timeFormat, 'h'),1767 iso8601: isIn(timeFormat, 'Z')1768 };1769 };1770 /*1771 * Converts 24 hour format into 12 hour1772 * Returns 12 hour without leading 01773 */1774 var convert24to12 = function (hour) {1775 hour %= 12;1776 if (hour === 0) {1777 hour = 12;1778 }1779 return String(hour);1780 };1781 var computeEffectiveSetting = function (settings, property) {1782 return settings && settings[property] ? settings[property] : $.timepicker._defaults[property];1783 };1784 /*1785 * Splits datetime string into date and time substrings.1786 * Throws exception when date can't be parsed1787 * Returns {dateString: dateString, timeString: timeString}1788 */1789 var splitDateTime = function (dateTimeString, timeSettings) {1790 // The idea is to get the number separator occurrences in datetime and the time format requested (since time has1791 // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.1792 var separator = computeEffectiveSetting(timeSettings, 'separator'),1793 format = computeEffectiveSetting(timeSettings, 'timeFormat'),1794 timeParts = format.split(separator), // how many occurrences of separator may be in our format?1795 timePartsLen = timeParts.length,1796 allParts = dateTimeString.split(separator),1797 allPartsLen = allParts.length;1798 if (allPartsLen > 1) {1799 return {1800 dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator),1801 timeString: allParts.splice(0, timePartsLen).join(separator)1802 };1803 }1804 return {1805 dateString: dateTimeString,1806 timeString: ''1807 };1808 };1809 /*1810 * Internal function to parse datetime interval1811 * Returns: {date: Date, timeObj: Object}, where1812 * date - parsed date without time (type Date)1813 * timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional1814 */1815 var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {1816 var date,1817 parts,1818 parsedTime;1819 parts = splitDateTime(dateTimeString, timeSettings);1820 date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings);1821 if (parts.timeString === '') {1822 return {1823 date: date1824 };1825 }1826 parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings);1827 if (!parsedTime) {1828 throw 'Wrong time format';1829 }1830 return {1831 date: date,1832 timeObj: parsedTime1833 };1834 };1835 /*1836 * Internal function to set timezone_select to the local timezone1837 */1838 var selectLocalTimezone = function (tp_inst, date) {1839 if (tp_inst && tp_inst.timezone_select) {1840 var now = date || new Date();1841 tp_inst.timezone_select.val(-now.getTimezoneOffset());1842 }1843 };1844 /*1845 * Create a Singleton Instance1846 */1847 $.timepicker = new Timepicker();1848 /**1849 * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)1850 * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned1851 * @param {boolean} iso8601 if true formats in accordance to iso8601 "+12:45"1852 * @return {string}1853 */1854 $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) {1855 if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) {1856 return tzMinutes;1857 }1858 var off = tzMinutes,1859 minutes = off % 60,1860 hours = (off - minutes) / 60,1861 iso = iso8601 ? ':' : '',1862 tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2);1863 if (tz === '+00:00') {1864 return 'Z';1865 }1866 return tz;1867 };1868 /**1869 * Get the number in minutes that represents a timezone string1870 * @param {string} tzString formatted like "+0500", "-1245", "Z"1871 * @return {number} the offset minutes or the original string if it doesn't match expectations1872 */1873 $.timepicker.timezoneOffsetNumber = function (tzString) {1874 var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with "+1245"1875 if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset1876 return 0;1877 }1878 if (!/^(\-|\+)\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back1879 return tzString;1880 }1881 return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus1882 ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes)1883 parseInt(normalized.substr(3, 2), 10))); // minutes1884 };1885 /**1886 * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate)1887 * @param {Date} date1888 * @param {string} toTimezone formatted like "+0500", "-1245"1889 * @return {Date}1890 */1891 $.timepicker.timezoneAdjust = function (date, toTimezone) {1892 var toTz = $.timepicker.timezoneOffsetNumber(toTimezone);1893 if (!isNaN(toTz)) {1894 date.setMinutes(date.getMinutes() + -date.getTimezoneOffset() - toTz);1895 }1896 return date;1897 };1898 /**1899 * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to1900 * enforce date range limits.1901 * n.b. The input value must be correctly formatted (reformatting is not supported)1902 * @param {Element} startTime1903 * @param {Element} endTime1904 * @param {Object} options Options for the timepicker() call1905 * @return {jQuery}1906 */1907 $.timepicker.timeRange = function (startTime, endTime, options) {1908 return $.timepicker.handleRange('timepicker', startTime, endTime, options);1909 };1910 /**1911 * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to1912 * enforce date range limits.1913 * @param {Element} startTime1914 * @param {Element} endTime1915 * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,1916 * a boolean value that can be used to reformat the input values to the `dateFormat`.1917 * @param {string} method Can be used to specify the type of picker to be added1918 * @return {jQuery}1919 */1920 $.timepicker.datetimeRange = function (startTime, endTime, options) {1921 $.timepicker.handleRange('datetimepicker', startTime, endTime, options);1922 };1923 /**1924 * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to1925 * enforce date range limits.1926 * @param {Element} startTime1927 * @param {Element} endTime1928 * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,1929 * a boolean value that can be used to reformat the input values to the `dateFormat`.1930 * @return {jQuery}1931 */1932 $.timepicker.dateRange = function (startTime, endTime, options) {1933 $.timepicker.handleRange('datepicker', startTime, endTime, options);1934 };1935 /**1936 * Calls `method` on the `startTime` and `endTime` elements, and configures them to1937 * enforce date range limits.1938 * @param {string} method Can be used to specify the type of picker to be added1939 * @param {Element} startTime1940 * @param {Element} endTime1941 * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,1942 * a boolean value that can be used to reformat the input values to the `dateFormat`.1943 * @return {jQuery}1944 */1945 $.timepicker.handleRange = function (method, startTime, endTime, options) {1946 options = $.extend({}, {1947 minInterval: 0, // min allowed interval in milliseconds1948 maxInterval: 0, // max allowed interval in milliseconds1949 start: {}, // options for start picker1950 end: {} // options for end picker1951 }, options);1952 // for the mean time this fixes an issue with calling getDate with timepicker()1953 var timeOnly = false;1954 if(method === 'timepicker'){1955 timeOnly = true;1956 method = 'datetimepicker';1957 }1958 function checkDates(changed, other) {1959 var startdt = startTime[method]('getDate'),1960 enddt = endTime[method]('getDate'),1961 changeddt = changed[method]('getDate');1962 if (startdt !== null) {1963 var minDate = new Date(startdt.getTime()),1964 maxDate = new Date(startdt.getTime());1965 minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval);1966 maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval);1967 if (options.minInterval > 0 && minDate > enddt) { // minInterval check1968 endTime[method]('setDate', minDate);1969 }1970 else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check1971 endTime[method]('setDate', maxDate);1972 }1973 else if (startdt > enddt) {1974 other[method]('setDate', changeddt);1975 }1976 }1977 }1978 function selected(changed, other, option) {1979 if (!changed.val()) {1980 return;1981 }1982 var date = changed[method].call(changed, 'getDate');1983 if (date !== null && options.minInterval > 0) {1984 if (option === 'minDate') {1985 date.setMilliseconds(date.getMilliseconds() + options.minInterval);1986 }1987 if (option === 'maxDate') {1988 date.setMilliseconds(date.getMilliseconds() - options.minInterval);1989 }1990 }1991 if (date.getTime) {1992 other[method].call(other, 'option', option, date);1993 }1994 }1995 $.fn[method].call(startTime, $.extend({1996 timeOnly: timeOnly,1997 onClose: function (dateText, inst) {1998 checkDates($(this), endTime);1999 },2000 onSelect: function (selectedDateTime) {2001 selected($(this), endTime, 'minDate');2002 }2003 }, options, options.start));2004 $.fn[method].call(endTime, $.extend({2005 timeOnly: timeOnly,2006 onClose: function (dateText, inst) {2007 checkDates($(this), startTime);2008 },2009 onSelect: function (selectedDateTime) {2010 selected($(this), startTime, 'maxDate');2011 }2012 }, options, options.end));2013 checkDates(startTime, endTime);2014 selected(startTime, endTime, 'minDate');2015 selected(endTime, startTime, 'maxDate');2016 return $([startTime.get(0), endTime.get(0)]);2017 };2018 /**2019 * Log error or data to the console during error or debugging2020 * @param {Object} err pass any type object to log to the console during error or debugging2021 * @return {void}2022 */2023 $.timepicker.log = function () {2024 if (window.console) {2025 window.console.log.apply(window.console, Array.prototype.slice.call(arguments));2026 }2027 };2028 /*2029 * Add util object to allow access to private methods for testability.2030 */2031 $.timepicker._util = {2032 _extendRemove: extendRemove,2033 _isEmptyObject: isEmptyObject,2034 _convert24to12: convert24to12,2035 _detectSupport: detectSupport,2036 _selectLocalTimezone: selectLocalTimezone,2037 _computeEffectiveSetting: computeEffectiveSetting,2038 _splitDateTime: splitDateTime,2039 _parseDateTimeInternal: parseDateTimeInternal2040 };2041 /*2042 * Microsecond support2043 */2044 if (!Date.prototype.getMicroseconds) {2045 Date.prototype.microseconds = 0;2046 Date.prototype.getMicroseconds = function () { return this.microseconds; };2047 Date.prototype.setMicroseconds = function (m) {2048 this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000));2049 this.microseconds = m % 1000;2050 return this;2051 };2052 }2053 /*2054 * Keep up with the version2055 */2056 $.timepicker.version = "1.6.1";...
jquery.timepicker.js
Source:jquery.timepicker.js
1/*! jQuery Timepicker Addon - v1.5.5 - 2015-05-242* http://trentrichardson.com/examples/timepicker3* Copyright (c) 2015 Trent Richardson; Licensed MIT */4(function (factory) {5 if (typeof define === 'function' && define.amd) {6 define(['jquery', 'jquery.ui'], factory);7 } else {8 factory(jQuery);9 }10}(function ($) {1112 /*13 * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded"14 */15 $.ui.timepicker = $.ui.timepicker || {};16 if ($.ui.timepicker.version) {17 return;18 }1920 /*21 * Extend jQueryUI, get it started with our version number22 */23 $.extend($.ui, {24 timepicker: {25 version: "1.5.5"26 }27 });2829 /* 30 * Timepicker manager.31 * Use the singleton instance of this class, $.timepicker, to interact with the time picker.32 * Settings for (groups of) time pickers are maintained in an instance object,33 * allowing multiple different settings on the same page.34 */35 var Timepicker = function () {36 this.regional = []; // Available regional settings, indexed by language code37 this.regional[''] = { // Default regional settings38 currentText: 'Now',39 closeText: 'Done',40 amNames: ['AM', 'A'],41 pmNames: ['PM', 'P'],42 timeFormat: 'HH:mm',43 timeSuffix: '',44 timeOnlyTitle: 'Choose Time',45 timeText: 'Time',46 hourText: 'Hour',47 minuteText: 'Minute',48 secondText: 'Second',49 millisecText: 'Millisecond',50 microsecText: 'Microsecond',51 timezoneText: 'Time Zone',52 isRTL: false53 };54 this._defaults = { // Global defaults for all the datetime picker instances55 showButtonPanel: true,56 timeOnly: false,57 timeOnlyShowDate: false,58 showHour: null,59 showMinute: null,60 showSecond: null,61 showMillisec: null,62 showMicrosec: null,63 showTimezone: null,64 showTime: true,65 stepHour: 1,66 stepMinute: 1,67 stepSecond: 1,68 stepMillisec: 1,69 stepMicrosec: 1,70 hour: 0,71 minute: 0,72 second: 0,73 millisec: 0,74 microsec: 0,75 timezone: null,76 hourMin: 0,77 minuteMin: 0,78 secondMin: 0,79 millisecMin: 0,80 microsecMin: 0,81 hourMax: 23,82 minuteMax: 59,83 secondMax: 59,84 millisecMax: 999,85 microsecMax: 999,86 minDateTime: null,87 maxDateTime: null,88 maxTime: null,89 minTime: null,90 onSelect: null,91 hourGrid: 0,92 minuteGrid: 0,93 secondGrid: 0,94 millisecGrid: 0,95 microsecGrid: 0,96 alwaysSetTime: true,97 separator: ' ',98 altFieldTimeOnly: true,99 altTimeFormat: null,100 altSeparator: null,101 altTimeSuffix: null,102 altRedirectFocus: true,103 pickerTimeFormat: null,104 pickerTimeSuffix: null,105 showTimepicker: true,106 timezoneList: null,107 addSliderAccess: false,108 sliderAccessArgs: null,109 controlType: 'slider',110 oneLine: false,111 defaultValue: null,112 parse: 'strict',113 afterInject: null114 };115 $.extend(this._defaults, this.regional['']);116 };117118 $.extend(Timepicker.prototype, {119 $input: null,120 $altInput: null,121 $timeObj: null,122 inst: null,123 hour_slider: null,124 minute_slider: null,125 second_slider: null,126 millisec_slider: null,127 microsec_slider: null,128 timezone_select: null,129 maxTime: null,130 minTime: null,131 hour: 0,132 minute: 0,133 second: 0,134 millisec: 0,135 microsec: 0,136 timezone: null,137 hourMinOriginal: null,138 minuteMinOriginal: null,139 secondMinOriginal: null,140 millisecMinOriginal: null,141 microsecMinOriginal: null,142 hourMaxOriginal: null,143 minuteMaxOriginal: null,144 secondMaxOriginal: null,145 millisecMaxOriginal: null,146 microsecMaxOriginal: null,147 ampm: '',148 formattedDate: '',149 formattedTime: '',150 formattedDateTime: '',151 timezoneList: null,152 units: ['hour', 'minute', 'second', 'millisec', 'microsec'],153 support: {},154 control: null,155156 /* 157 * Override the default settings for all instances of the time picker.158 * @param {Object} settings object - the new settings to use as defaults (anonymous object)159 * @return {Object} the manager object160 */161 setDefaults: function (settings) {162 extendRemove(this._defaults, settings || {});163 return this;164 },165166 /*167 * Create a new Timepicker instance168 */169 _newInst: function ($input, opts) {170 var tp_inst = new Timepicker(),171 inlineSettings = {},172 fns = {},173 overrides, i;174175 for (var attrName in this._defaults) {176 if (this._defaults.hasOwnProperty(attrName)) {177 var attrValue = $input.attr('time:' + attrName);178 if (attrValue) {179 try {180 inlineSettings[attrName] = eval(attrValue);181 } catch (err) {182 inlineSettings[attrName] = attrValue;183 }184 }185 }186 }187188 overrides = {189 beforeShow: function (input, dp_inst) {190 if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) {191 return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst);192 }193 },194 onChangeMonthYear: function (year, month, dp_inst) {195 // Update the time as well : this prevents the time from disappearing from the $input field.196 // tp_inst._updateDateTime(dp_inst);197 if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) {198 tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);199 }200 },201 onClose: function (dateText, dp_inst) {202 if (tp_inst.timeDefined === true && $input.val() !== '') {203 tp_inst._updateDateTime(dp_inst);204 }205 if ($.isFunction(tp_inst._defaults.evnts.onClose)) {206 tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst);207 }208 }209 };210 for (i in overrides) {211 if (overrides.hasOwnProperty(i)) {212 fns[i] = opts[i] || this._defaults[i] || null;213 }214 }215216 tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, {217 evnts: fns,218 timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');219 });220 tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) {221 return val.toUpperCase();222 });223 tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) {224 return val.toUpperCase();225 });226227 // detect which units are supported228 tp_inst.support = detectSupport(229 tp_inst._defaults.timeFormat + 230 (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') +231 (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : ''));232233 // controlType is string - key to our this._controls234 if (typeof(tp_inst._defaults.controlType) === 'string') {235 if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') {236 tp_inst._defaults.controlType = 'select';237 }238 tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType];239 }240 // controlType is an object and must implement create, options, value methods241 else {242 tp_inst.control = tp_inst._defaults.controlType;243 }244245 // prep the timezone options246 var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60,247 0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840];248 if (tp_inst._defaults.timezoneList !== null) {249 timezoneList = tp_inst._defaults.timezoneList;250 }251 var tzl = timezoneList.length, tzi = 0, tzv = null;252 if (tzl > 0 && typeof timezoneList[0] !== 'object') {253 for (; tzi < tzl; tzi++) {254 tzv = timezoneList[tzi];255 timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) };256 }257 }258 tp_inst._defaults.timezoneList = timezoneList;259260 // set the default units261 tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) :262 ((new Date()).getTimezoneOffset() * -1);263 tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin :264 tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour;265 tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin :266 tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute;267 tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin :268 tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second;269 tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin :270 tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec;271 tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin :272 tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec;273 tp_inst.ampm = '';274 tp_inst.$input = $input;275276 if (tp_inst._defaults.altField) {277 tp_inst.$altInput = $(tp_inst._defaults.altField);278 if (tp_inst._defaults.altRedirectFocus === true) {279 tp_inst.$altInput.css({280 cursor: 'pointer'281 }).focus(function () {282 $input.trigger("focus");283 });284 }285 }286287 if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) {288 tp_inst._defaults.minDate = new Date();289 }290 if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) {291 tp_inst._defaults.maxDate = new Date();292 }293294 // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..295 if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) {296 tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());297 }298 if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) {299 tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());300 }301 if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) {302 tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());303 }304 if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) {305 tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());306 }307 tp_inst.$input.bind('focus', function () {308 tp_inst._onFocus();309 });310311 return tp_inst;312 },313314 /*315 * add our sliders to the calendar316 */317 _addTimePicker: function (dp_inst) {318 var currDT = $.trim((this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val());319320 this.timeDefined = this._parseTime(currDT);321 this._limitMinMaxDateTime(dp_inst, false);322 this._injectTimePicker();323 this._afterInject();324 },325326 /*327 * parse the time string from input value or _setTime328 */329 _parseTime: function (timeString, withDate) {330 if (!this.inst) {331 this.inst = $.datepicker._getInst(this.$input[0]);332 }333334 if (withDate || !this._defaults.timeOnly) {335 var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');336 try {337 var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults);338 if (!parseRes.timeObj) {339 return false;340 }341 $.extend(this, parseRes.timeObj);342 } catch (err) {343 $.timepicker.log("Error parsing the date/time string: " + err +344 "\ndate/time string = " + timeString +345 "\ntimeFormat = " + this._defaults.timeFormat +346 "\ndateFormat = " + dp_dateFormat);347 return false;348 }349 return true;350 } else {351 var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults);352 if (!timeObj) {353 return false;354 }355 $.extend(this, timeObj);356 return true;357 }358 },359360 /*361 * Handle callback option after injecting timepicker362 */363 _afterInject: function() {364 var o = this.inst.settings;365 if ($.isFunction(o.afterInject)) {366 o.afterInject.call(this);367 }368 },369370 /*371 * generate and inject html for timepicker into ui datepicker372 */373 _injectTimePicker: function () {374 var $dp = this.inst.dpDiv,375 o = this.inst.settings,376 tp_inst = this,377 litem = '',378 uitem = '',379 show = null,380 max = {},381 gridSize = {},382 size = null,383 i = 0,384 l = 0;385386 // Prevent displaying twice387 if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) {388 var noDisplay = ' ui_tpicker_unit_hide',389 html = '<div class="ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + (o.oneLine && o.controlType === 'select' ? ' ui-timepicker-oneLine' : '') + '"><dl>' + '<dt class="ui_tpicker_time_label' + ((o.showTime) ? '' : noDisplay) + '">' + o.timeText + '</dt>' +390 '<dd class="ui_tpicker_time '+ ((o.showTime) ? '' : noDisplay) + '"></dd>';391392 // Create the markup393 for (i = 0, l = this.units.length; i < l; i++) {394 litem = this.units[i];395 uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);396 show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];397398 // Added by Peter Medeiros:399 // - Figure out what the hour/minute/second max should be based on the step values.400 // - Example: if stepMinute is 15, then minMax is 45.401 max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10);402 gridSize[litem] = 0;403404 html += '<dt class="ui_tpicker_' + litem + '_label' + (show ? '' : noDisplay) + '">' + o[litem + 'Text'] + '</dt>' +405 '<dd class="ui_tpicker_' + litem + (show ? '' : noDisplay) + '"><div class="ui_tpicker_' + litem + '_slider' + (show ? '' : noDisplay) + '"></div>';406407 if (show && o[litem + 'Grid'] > 0) {408 html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';409410 if (litem === 'hour') {411 for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) {412 gridSize[litem]++;413 var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o);414 html += '<td data-for="' + litem + '">' + tmph + '</td>';415 }416 }417 else {418 for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) {419 gridSize[litem]++;420 html += '<td data-for="' + litem + '">' + ((m < 10) ? '0' : '') + m + '</td>';421 }422 }423424 html += '</tr></table></div>';425 }426 html += '</dd>';427 }428 429 // Timezone430 var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone;431 html += '<dt class="ui_tpicker_timezone_label' + (showTz ? '' : noDisplay) + '">' + o.timezoneText + '</dt>';432 html += '<dd class="ui_tpicker_timezone' + (showTz ? '' : noDisplay) + '"></dd>';433434 // Create the elements from string435 html += '</dl></div>';436 var $tp = $(html);437438 // if we only want time picker...439 if (o.timeOnly === true) {440 $tp.prepend('<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + '</div>');441 $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();442 }443 444 // add sliders, adjust grids, add events445 for (i = 0, l = tp_inst.units.length; i < l; i++) {446 litem = tp_inst.units[i];447 uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);448 show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];449450 // add the slider451 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]);452453 // adjust the grid and add click event454 if (show && o[litem + 'Grid'] > 0) {455 size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']);456 $tp.find('.ui_tpicker_' + litem + ' table').css({457 width: size + "%",458 marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + "%"),459 marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + "%") : '0',460 borderCollapse: 'collapse'461 }).find("td").click(function (e) {462 var $t = $(this),463 h = $t.html(),464 n = parseInt(h.replace(/[^0-9]/g), 10),465 ap = h.replace(/[^apm]/ig),466 f = $t.data('for'); // loses scope, so we use data-for467468 if (f === 'hour') {469 if (ap.indexOf('p') !== -1 && n < 12) {470 n += 12;471 }472 else {473 if (ap.indexOf('a') !== -1 && n === 12) {474 n = 0;475 }476 }477 }478 479 tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n);480481 tp_inst._onTimeChange();482 tp_inst._onSelectHandler();483 }).css({484 cursor: 'pointer',485 width: (100 / gridSize[litem]) + '%',486 textAlign: 'center',487 overflow: 'hidden'488 });489 } // end if grid > 0490 } // end for loop491492 // Add timezone options493 this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find("select");494 $.fn.append.apply(this.timezone_select,495 $.map(o.timezoneList, function (val, idx) {496 return $("<option />").val(typeof val === "object" ? val.value : val).text(typeof val === "object" ? val.label : val);497 }));498 if (typeof(this.timezone) !== "undefined" && this.timezone !== null && this.timezone !== "") {499 var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1;500 if (local_timezone === this.timezone) {501 selectLocalTimezone(tp_inst);502 } else {503 this.timezone_select.val(this.timezone);504 }505 } else {506 if (typeof(this.hour) !== "undefined" && this.hour !== null && this.hour !== "") {507 this.timezone_select.val(o.timezone);508 } else {509 selectLocalTimezone(tp_inst);510 }511 }512 this.timezone_select.change(function () {513 tp_inst._onTimeChange();514 tp_inst._onSelectHandler();515 tp_inst._afterInject();516 });517 // End timezone options518 519 // inject timepicker into datepicker520 var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');521 if ($buttonPanel.length) {522 $buttonPanel.before($tp);523 } else {524 $dp.append($tp);525 }526527 this.$timeObj = $tp.find('.ui_tpicker_time');528529 if (this.inst !== null) {530 var timeDefined = this.timeDefined;531 this._onTimeChange();532 this.timeDefined = timeDefined;533 }534535 // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/536 if (this._defaults.addSliderAccess) {537 var sliderAccessArgs = this._defaults.sliderAccessArgs,538 rtl = this._defaults.isRTL;539 sliderAccessArgs.isRTL = rtl;540 541 setTimeout(function () { // fix for inline mode542 if ($tp.find('.ui-slider-access').length === 0) {543 $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);544545 // fix any grids since sliders are shorter546 var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);547 if (sliderAccessWidth) {548 $tp.find('table:visible').each(function () {549 var $g = $(this),550 oldWidth = $g.outerWidth(),551 oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''),552 newWidth = oldWidth - sliderAccessWidth,553 newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%',554 css = { width: newWidth, marginRight: 0, marginLeft: 0 };555 css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft;556 $g.css(css);557 });558 }559 }560 }, 10);561 }562 // end slideAccess integration563564 tp_inst._limitMinMaxDateTime(this.inst, true);565 }566 },567568 /*569 * This function tries to limit the ability to go outside the570 * min/max date range571 */572 _limitMinMaxDateTime: function (dp_inst, adjustSliders) {573 var o = this._defaults,574 dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);575576 if (!this._defaults.showTimepicker) {577 return;578 } // No time so nothing to check here579580 if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) {581 var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),582 minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);583584 if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) {585 this.hourMinOriginal = o.hourMin;586 this.minuteMinOriginal = o.minuteMin;587 this.secondMinOriginal = o.secondMin;588 this.millisecMinOriginal = o.millisecMin;589 this.microsecMinOriginal = o.microsecMin;590 }591592 if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) {593 this._defaults.hourMin = minDateTime.getHours();594 if (this.hour <= this._defaults.hourMin) {595 this.hour = this._defaults.hourMin;596 this._defaults.minuteMin = minDateTime.getMinutes();597 if (this.minute <= this._defaults.minuteMin) {598 this.minute = this._defaults.minuteMin;599 this._defaults.secondMin = minDateTime.getSeconds();600 if (this.second <= this._defaults.secondMin) {601 this.second = this._defaults.secondMin;602 this._defaults.millisecMin = minDateTime.getMilliseconds();603 if (this.millisec <= this._defaults.millisecMin) {604 this.millisec = this._defaults.millisecMin;605 this._defaults.microsecMin = minDateTime.getMicroseconds();606 } else {607 if (this.microsec < this._defaults.microsecMin) {608 this.microsec = this._defaults.microsecMin;609 }610 this._defaults.microsecMin = this.microsecMinOriginal;611 }612 } else {613 this._defaults.millisecMin = this.millisecMinOriginal;614 this._defaults.microsecMin = this.microsecMinOriginal;615 }616 } else {617 this._defaults.secondMin = this.secondMinOriginal;618 this._defaults.millisecMin = this.millisecMinOriginal;619 this._defaults.microsecMin = this.microsecMinOriginal;620 }621 } else {622 this._defaults.minuteMin = this.minuteMinOriginal;623 this._defaults.secondMin = this.secondMinOriginal;624 this._defaults.millisecMin = this.millisecMinOriginal;625 this._defaults.microsecMin = this.microsecMinOriginal;626 }627 } else {628 this._defaults.hourMin = this.hourMinOriginal;629 this._defaults.minuteMin = this.minuteMinOriginal;630 this._defaults.secondMin = this.secondMinOriginal;631 this._defaults.millisecMin = this.millisecMinOriginal;632 this._defaults.microsecMin = this.microsecMinOriginal;633 }634 }635636 if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) {637 var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),638 maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);639640 if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) {641 this.hourMaxOriginal = o.hourMax;642 this.minuteMaxOriginal = o.minuteMax;643 this.secondMaxOriginal = o.secondMax;644 this.millisecMaxOriginal = o.millisecMax;645 this.microsecMaxOriginal = o.microsecMax;646 }647648 if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) {649 this._defaults.hourMax = maxDateTime.getHours();650 if (this.hour >= this._defaults.hourMax) {651 this.hour = this._defaults.hourMax;652 this._defaults.minuteMax = maxDateTime.getMinutes();653 if (this.minute >= this._defaults.minuteMax) {654 this.minute = this._defaults.minuteMax;655 this._defaults.secondMax = maxDateTime.getSeconds();656 if (this.second >= this._defaults.secondMax) {657 this.second = this._defaults.secondMax;658 this._defaults.millisecMax = maxDateTime.getMilliseconds();659 if (this.millisec >= this._defaults.millisecMax) {660 this.millisec = this._defaults.millisecMax;661 this._defaults.microsecMax = maxDateTime.getMicroseconds();662 } else {663 if (this.microsec > this._defaults.microsecMax) {664 this.microsec = this._defaults.microsecMax;665 }666 this._defaults.microsecMax = this.microsecMaxOriginal;667 }668 } else {669 this._defaults.millisecMax = this.millisecMaxOriginal;670 this._defaults.microsecMax = this.microsecMaxOriginal;671 }672 } else {673 this._defaults.secondMax = this.secondMaxOriginal;674 this._defaults.millisecMax = this.millisecMaxOriginal;675 this._defaults.microsecMax = this.microsecMaxOriginal;676 }677 } else {678 this._defaults.minuteMax = this.minuteMaxOriginal;679 this._defaults.secondMax = this.secondMaxOriginal;680 this._defaults.millisecMax = this.millisecMaxOriginal;681 this._defaults.microsecMax = this.microsecMaxOriginal;682 }683 } else {684 this._defaults.hourMax = this.hourMaxOriginal;685 this._defaults.minuteMax = this.minuteMaxOriginal;686 this._defaults.secondMax = this.secondMaxOriginal;687 this._defaults.millisecMax = this.millisecMaxOriginal;688 this._defaults.microsecMax = this.microsecMaxOriginal;689 }690 }691692 if (dp_inst.settings.minTime!==null) { 693 var tempMinTime=new Date("01/01/1970 " + dp_inst.settings.minTime); 694 if (this.hour<tempMinTime.getHours()) {695 this.hour=this._defaults.hourMin=tempMinTime.getHours();696 this.minute=this._defaults.minuteMin=tempMinTime.getMinutes(); 697 } else if (this.hour===tempMinTime.getHours() && this.minute<tempMinTime.getMinutes()) {698 this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();699 } else { 700 if (this._defaults.hourMin<tempMinTime.getHours()) {701 this._defaults.hourMin=tempMinTime.getHours();702 this._defaults.minuteMin=tempMinTime.getMinutes(); 703 } else if (this._defaults.hourMin===tempMinTime.getHours()===this.hour && this._defaults.minuteMin<tempMinTime.getMinutes()) {704 this._defaults.minuteMin=tempMinTime.getMinutes(); 705 } else {706 this._defaults.minuteMin=0;707 }708 } 709 }710 711 if (dp_inst.settings.maxTime!==null) { 712 var tempMaxTime=new Date("01/01/1970 " + dp_inst.settings.maxTime);713 if (this.hour>tempMaxTime.getHours()) {714 this.hour=this._defaults.hourMax=tempMaxTime.getHours(); 715 this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();716 } else if (this.hour===tempMaxTime.getHours() && this.minute>tempMaxTime.getMinutes()) { 717 this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes(); 718 } else {719 if (this._defaults.hourMax>tempMaxTime.getHours()) {720 this._defaults.hourMax=tempMaxTime.getHours();721 this._defaults.minuteMax=tempMaxTime.getMinutes(); 722 } else if (this._defaults.hourMax===tempMaxTime.getHours()===this.hour && this._defaults.minuteMax>tempMaxTime.getMinutes()) {723 this._defaults.minuteMax=tempMaxTime.getMinutes(); 724 } else {725 this._defaults.minuteMax=59;726 }727 } 728 }729 730 if (adjustSliders !== undefined && adjustSliders === true) {731 var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10),732 minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10),733 secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10),734 millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10),735 microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10);736737 if (this.hour_slider) {738 this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax, step: this._defaults.stepHour });739 this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour));740 }741 if (this.minute_slider) {742 this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax, step: this._defaults.stepMinute });743 this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute));744 }745 if (this.second_slider) {746 this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax, step: this._defaults.stepSecond });747 this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond));748 }749 if (this.millisec_slider) {750 this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax, step: this._defaults.stepMillisec });751 this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec));752 }753 if (this.microsec_slider) {754 this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax, step: this._defaults.stepMicrosec });755 this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec));756 }757 }758759 },760761 /*762 * when a slider moves, set the internal time...763 * on time change is also called when the time is updated in the text field764 */765 _onTimeChange: function () {766 if (!this._defaults.showTimepicker) {767 return;768 }769 var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false,770 minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false,771 second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false,772 millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false,773 microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false,774 timezone = (this.timezone_select) ? this.timezone_select.val() : false,775 o = this._defaults,776 pickerTimeFormat = o.pickerTimeFormat || o.timeFormat,777 pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix;778779 if (typeof(hour) === 'object') {780 hour = false;781 }782 if (typeof(minute) === 'object') {783 minute = false;784 }785 if (typeof(second) === 'object') {786 second = false;787 }788 if (typeof(millisec) === 'object') {789 millisec = false;790 }791 if (typeof(microsec) === 'object') {792 microsec = false;793 }794 if (typeof(timezone) === 'object') {795 timezone = false;796 }797798 if (hour !== false) {799 hour = parseInt(hour, 10);800 }801 if (minute !== false) {802 minute = parseInt(minute, 10);803 }804 if (second !== false) {805 second = parseInt(second, 10);806 }807 if (millisec !== false) {808 millisec = parseInt(millisec, 10);809 }810 if (microsec !== false) {811 microsec = parseInt(microsec, 10);812 }813 if (timezone !== false) {814 timezone = timezone.toString();815 }816817 var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];818819 // If the update was done in the input field, the input field should not be updated.820 // If the update was done using the sliders, update the input field.821 var hasChanged = (822 hour !== parseInt(this.hour,10) || // sliders should all be numeric823 minute !== parseInt(this.minute,10) || 824 second !== parseInt(this.second,10) || 825 millisec !== parseInt(this.millisec,10) || 826 microsec !== parseInt(this.microsec,10) || 827 (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) || 828 (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or "EST" format, so use toString()829 );830831 if (hasChanged) {832833 if (hour !== false) {834 this.hour = hour;835 }836 if (minute !== false) {837 this.minute = minute;838 }839 if (second !== false) {840 this.second = second;841 }842 if (millisec !== false) {843 this.millisec = millisec;844 }845 if (microsec !== false) {846 this.microsec = microsec;847 }848 if (timezone !== false) {849 this.timezone = timezone;850 }851852 if (!this.inst) {853 this.inst = $.datepicker._getInst(this.$input[0]);854 }855856 this._limitMinMaxDateTime(this.inst, true);857 }858 if (this.support.ampm) {859 this.ampm = ampm;860 }861862 // Updates the time within the timepicker863 this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o);864 if (this.$timeObj) {865 if (pickerTimeFormat === o.timeFormat) {866 this.$timeObj.text(this.formattedTime + pickerTimeSuffix);867 }868 else {869 this.$timeObj.text($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix);870 }871 }872873 this.timeDefined = true;874 if (hasChanged) {875 this._updateDateTime();876 //this.$input.focus(); // may automatically open the picker on setDate877 }878 },879880 /*881 * call custom onSelect.882 * bind to sliders slidestop, and grid click.883 */884 _onSelectHandler: function () {885 var onSelect = this._defaults.onSelect || this.inst.settings.onSelect;886 var inputEl = this.$input ? this.$input[0] : null;887 if (onSelect && inputEl) {888 onSelect.apply(inputEl, [this.formattedDateTime, this]);889 }890 },891892 /*893 * update our input with the new date time..894 */895 _updateDateTime: function (dp_inst) {896 dp_inst = this.inst || dp_inst;897 var dtTmp = (dp_inst.currentYear > 0? 898 new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) : 899 new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),900 dt = $.datepicker._daylightSavingAdjust(dtTmp),901 //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),902 //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)),903 dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),904 formatCfg = $.datepicker._getFormatConfig(dp_inst),905 timeAvailable = dt !== null && this.timeDefined;906 this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);907 var formattedDateTime = this.formattedDate;908 909 // if a slider was changed but datepicker doesn't have a value yet, set it910 if (dp_inst.lastVal === "") {911 dp_inst.currentYear = dp_inst.selectedYear;912 dp_inst.currentMonth = dp_inst.selectedMonth;913 dp_inst.currentDay = dp_inst.selectedDay;914 }915916 /*917 * remove following lines to force every changes in date picker to change the input value918 * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker. 919 * If the user manually empty the value in the input field, the date picker will never change selected value.920 */921 //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) {922 // return;923 //}924925 if (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === false) {926 formattedDateTime = this.formattedTime;927 } else if ((this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) || (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === true)) {928 formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;929 }930931 this.formattedDateTime = formattedDateTime;932933 if (!this._defaults.showTimepicker) {934 this.$input.val(this.formattedDate);935 } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) {936 this.$altInput.val(this.formattedTime);937 this.$input.val(this.formattedDate);938 } else if (this.$altInput) {939 this.$input.val(formattedDateTime);940 var altFormattedDateTime = '',941 altSeparator = this._defaults.altSeparator !== null ? this._defaults.altSeparator : this._defaults.separator,942 altTimeSuffix = this._defaults.altTimeSuffix !== null ? this._defaults.altTimeSuffix : this._defaults.timeSuffix;943 944 if (!this._defaults.timeOnly) {945 if (this._defaults.altFormat) {946 altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg);947 }948 else {949 altFormattedDateTime = this.formattedDate;950 }951952 if (altFormattedDateTime) {953 altFormattedDateTime += altSeparator;954 }955 }956957 if (this._defaults.altTimeFormat !== null) {958 altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix;959 }960 else {961 altFormattedDateTime += this.formattedTime + altTimeSuffix;962 }963 this.$altInput.val(altFormattedDateTime);964 } else {965 this.$input.val(formattedDateTime);966 }967968 this.$input.trigger("change");969 },970971 _onFocus: function () {972 if (!this.$input.val() && this._defaults.defaultValue) {973 this.$input.val(this._defaults.defaultValue);974 var inst = $.datepicker._getInst(this.$input.get(0)),975 tp_inst = $.datepicker._get(inst, 'timepicker');976 if (tp_inst) {977 if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {978 try {979 $.datepicker._updateDatepicker(inst);980 } catch (err) {981 $.timepicker.log(err);982 }983 }984 }985 }986 },987988 /*989 * Small abstraction to control types990 * We can add more, just be sure to follow the pattern: create, options, value991 */992 _controls: {993 // slider methods994 slider: {995 create: function (tp_inst, obj, unit, val, min, max, step) {996 var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60997 return obj.prop('slide', null).slider({998 orientation: "horizontal",999 value: rtl ? val * -1 : val,1000 min: rtl ? max * -1 : min,1001 max: rtl ? min * -1 : max,1002 step: step,1003 slide: function (event, ui) {1004 tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value);1005 tp_inst._onTimeChange();1006 },1007 stop: function (event, ui) {1008 tp_inst._onSelectHandler();1009 }1010 }); 1011 },1012 options: function (tp_inst, obj, unit, opts, val) {1013 if (tp_inst._defaults.isRTL) {1014 if (typeof(opts) === 'string') {1015 if (opts === 'min' || opts === 'max') {1016 if (val !== undefined) {1017 return obj.slider(opts, val * -1);1018 }1019 return Math.abs(obj.slider(opts));1020 }1021 return obj.slider(opts);1022 }1023 var min = opts.min, 1024 max = opts.max;1025 opts.min = opts.max = null;1026 if (min !== undefined) {1027 opts.max = min * -1;1028 }1029 if (max !== undefined) {1030 opts.min = max * -1;1031 }1032 return obj.slider(opts);1033 }1034 if (typeof(opts) === 'string' && val !== undefined) {1035 return obj.slider(opts, val);1036 }1037 return obj.slider(opts);1038 },1039 value: function (tp_inst, obj, unit, val) {1040 if (tp_inst._defaults.isRTL) {1041 if (val !== undefined) {1042 return obj.slider('value', val * -1);1043 }1044 return Math.abs(obj.slider('value'));1045 }1046 if (val !== undefined) {1047 return obj.slider('value', val);1048 }1049 return obj.slider('value');1050 }1051 },1052 // select methods1053 select: {1054 create: function (tp_inst, obj, unit, val, min, max, step) {1055 var sel = '<select class="ui-timepicker-select ui-state-default ui-corner-all" data-unit="' + unit + '" data-min="' + min + '" data-max="' + max + '" data-step="' + step + '">',1056 format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat;10571058 for (var i = min; i <= max; i += step) {1059 sel += '<option value="' + i + '"' + (i === val ? ' selected' : '') + '>';1060 if (unit === 'hour') {1061 sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults);1062 }1063 else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; }1064 else {sel += '0' + i.toString(); }1065 sel += '</option>';1066 }1067 sel += '</select>';10681069 obj.children('select').remove();10701071 $(sel).appendTo(obj).change(function (e) {1072 tp_inst._onTimeChange();1073 tp_inst._onSelectHandler();1074 tp_inst._afterInject();1075 });10761077 return obj;1078 },1079 options: function (tp_inst, obj, unit, opts, val) {1080 var o = {},1081 $t = obj.children('select');1082 if (typeof(opts) === 'string') {1083 if (val === undefined) {1084 return $t.data(opts);1085 }1086 o[opts] = val; 1087 }1088 else { o = opts; }1089 return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min>=0 ? o.min : $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step'));1090 },1091 value: function (tp_inst, obj, unit, val) {1092 var $t = obj.children('select');1093 if (val !== undefined) {1094 return $t.val(val);1095 }1096 return $t.val();1097 }1098 }1099 } // end _controls11001101 });11021103 $.fn.extend({1104 /*1105 * shorthand just to use timepicker.1106 */1107 timepicker: function (o) {1108 o = o || {};1109 var tmp_args = Array.prototype.slice.call(arguments);11101111 if (typeof o === 'object') {1112 tmp_args[0] = $.extend(o, {1113 timeOnly: true1114 });1115 }11161117 return $(this).each(function () {1118 $.fn.datetimepicker.apply($(this), tmp_args);1119 });1120 },11211122 /*1123 * extend timepicker to datepicker1124 */1125 datetimepicker: function (o) {1126 o = o || {};1127 var tmp_args = arguments;11281129 if (typeof(o) === 'string') {1130 if (o === 'getDate' || (o === 'option' && tmp_args.length === 2 && typeof (tmp_args[1]) === 'string')) {1131 return $.fn.datepicker.apply($(this[0]), tmp_args);1132 } else {1133 return this.each(function () {1134 var $t = $(this);1135 $t.datepicker.apply($t, tmp_args);1136 });1137 }1138 } else {1139 return this.each(function () {1140 var $t = $(this);1141 $t.datepicker($.timepicker._newInst($t, o)._defaults);1142 });1143 }1144 }1145 });11461147 /*1148 * Public Utility to parse date and time1149 */1150 $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {1151 var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings);1152 if (parseRes.timeObj) {1153 var t = parseRes.timeObj;1154 parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec);1155 parseRes.date.setMicroseconds(t.microsec);1156 }11571158 return parseRes.date;1159 };11601161 /*1162 * Public utility to parse time1163 */1164 $.datepicker.parseTime = function (timeFormat, timeString, options) {1165 var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}),1166 iso8601 = (timeFormat.replace(/\'.*?\'/g, '').indexOf('Z') !== -1);11671168 // Strict parse requires the timeString to match the timeFormat exactly1169 var strictParse = function (f, s, o) {11701171 // pattern for standard and localized AM/PM markers1172 var getPatternAmpm = function (amNames, pmNames) {1173 var markers = [];1174 if (amNames) {1175 $.merge(markers, amNames);1176 }1177 if (pmNames) {1178 $.merge(markers, pmNames);1179 }1180 markers = $.map(markers, function (val) {1181 return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&');1182 });1183 return '(' + markers.join('|') + ')?';1184 };11851186 // figure out position of time elements.. cause js cant do named captures1187 var getFormatPositions = function (timeFormat) {1188 var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),1189 orders = {1190 h: -1,1191 m: -1,1192 s: -1,1193 l: -1,1194 c: -1,1195 t: -1,1196 z: -11197 };11981199 if (finds) {1200 for (var i = 0; i < finds.length; i++) {1201 if (orders[finds[i].toString().charAt(0)] === -1) {1202 orders[finds[i].toString().charAt(0)] = i + 1;1203 }1204 }1205 }1206 return orders;1207 };12081209 var regstr = '^' + f.toString()1210 .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {1211 var ml = match.length;1212 switch (match.charAt(0).toLowerCase()) {1213 case 'h':1214 return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';1215 case 'm':1216 return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';1217 case 's':1218 return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';1219 case 'l':1220 return '(\\d?\\d?\\d)';1221 case 'c':1222 return '(\\d?\\d?\\d)';1223 case 'z':1224 return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?';1225 case 't':1226 return getPatternAmpm(o.amNames, o.pmNames);1227 default: // literal escaped in quotes1228 return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?';1229 }1230 })1231 .replace(/\s/g, '\\s?') +1232 o.timeSuffix + '$',1233 order = getFormatPositions(f),1234 ampm = '',1235 treg;12361237 treg = s.match(new RegExp(regstr, 'i'));12381239 var resTime = {1240 hour: 0,1241 minute: 0,1242 second: 0,1243 millisec: 0,1244 microsec: 01245 };12461247 if (treg) {1248 if (order.t !== -1) {1249 if (treg[order.t] === undefined || treg[order.t].length === 0) {1250 ampm = '';1251 resTime.ampm = '';1252 } else {1253 ampm = $.inArray(treg[order.t].toUpperCase(), $.map(o.amNames, function (x,i) { return x.toUpperCase(); })) !== -1 ? 'AM' : 'PM';1254 resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0];1255 }1256 }12571258 if (order.h !== -1) {1259 if (ampm === 'AM' && treg[order.h] === '12') {1260 resTime.hour = 0; // 12am = 0 hour1261 } else {1262 if (ampm === 'PM' && treg[order.h] !== '12') {1263 resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 121264 } else {1265 resTime.hour = Number(treg[order.h]);1266 }1267 }1268 }12691270 if (order.m !== -1) {1271 resTime.minute = Number(treg[order.m]);1272 }1273 if (order.s !== -1) {1274 resTime.second = Number(treg[order.s]);1275 }1276 if (order.l !== -1) {1277 resTime.millisec = Number(treg[order.l]);1278 }1279 if (order.c !== -1) {1280 resTime.microsec = Number(treg[order.c]);1281 }1282 if (order.z !== -1 && treg[order.z] !== undefined) {1283 resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]);1284 }128512861287 return resTime;1288 }1289 return false;1290 };// end strictParse12911292 // First try JS Date, if that fails, use strictParse1293 var looseParse = function (f, s, o) {1294 try {1295 var d = new Date('2012-01-01 ' + s);1296 if (isNaN(d.getTime())) {1297 d = new Date('2012-01-01T' + s);1298 if (isNaN(d.getTime())) {1299 d = new Date('01/01/2012 ' + s);1300 if (isNaN(d.getTime())) {1301 throw "Unable to parse time with native Date: " + s;1302 }1303 }1304 }13051306 return {1307 hour: d.getHours(),1308 minute: d.getMinutes(),1309 second: d.getSeconds(),1310 millisec: d.getMilliseconds(),1311 microsec: d.getMicroseconds(),1312 timezone: d.getTimezoneOffset() * -11313 };1314 }1315 catch (err) {1316 try {1317 return strictParse(f, s, o);1318 }1319 catch (err2) {1320 $.timepicker.log("Unable to parse \ntimeString: " + s + "\ntimeFormat: " + f);1321 } 1322 }1323 return false;1324 }; // end looseParse1325 1326 if (typeof o.parse === "function") {1327 return o.parse(timeFormat, timeString, o);1328 }1329 if (o.parse === 'loose') {1330 return looseParse(timeFormat, timeString, o);1331 }1332 return strictParse(timeFormat, timeString, o);1333 };13341335 /**1336 * Public utility to format the time1337 * @param {string} format format of the time1338 * @param {Object} time Object not a Date for timezones1339 * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm1340 * @returns {string} the formatted time1341 */1342 $.datepicker.formatTime = function (format, time, options) {1343 options = options || {};1344 options = $.extend({}, $.timepicker._defaults, options);1345 time = $.extend({1346 hour: 0,1347 minute: 0,1348 second: 0,1349 millisec: 0,1350 microsec: 0,1351 timezone: null1352 }, time);13531354 var tmptime = format,1355 ampmName = options.amNames[0],1356 hour = parseInt(time.hour, 10);13571358 if (hour > 11) {1359 ampmName = options.pmNames[0];1360 }13611362 tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {1363 switch (match) {1364 case 'HH':1365 return ('0' + hour).slice(-2);1366 case 'H':1367 return hour;1368 case 'hh':1369 return ('0' + convert24to12(hour)).slice(-2);1370 case 'h':1371 return convert24to12(hour);1372 case 'mm':1373 return ('0' + time.minute).slice(-2);1374 case 'm':1375 return time.minute;1376 case 'ss':1377 return ('0' + time.second).slice(-2);1378 case 's':1379 return time.second;1380 case 'l':1381 return ('00' + time.millisec).slice(-3);1382 case 'c':1383 return ('00' + time.microsec).slice(-3);1384 case 'z':1385 return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false);1386 case 'Z':1387 return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true);1388 case 'T':1389 return ampmName.charAt(0).toUpperCase();1390 case 'TT':1391 return ampmName.toUpperCase();1392 case 't':1393 return ampmName.charAt(0).toLowerCase();1394 case 'tt':1395 return ampmName.toLowerCase();1396 default:1397 return match.replace(/'/g, "");1398 }1399 });14001401 return tmptime;1402 };14031404 /*1405 * the bad hack :/ override datepicker so it doesn't close on select1406 // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#17623781407 */1408 $.datepicker._base_selectDate = $.datepicker._selectDate;1409 $.datepicker._selectDate = function (id, dateStr) {1410 var inst = this._getInst($(id)[0]),1411 tp_inst = this._get(inst, 'timepicker'),1412 was_inline;14131414 if (tp_inst && inst.settings.showTimepicker) {1415 tp_inst._limitMinMaxDateTime(inst, true);1416 was_inline = inst.inline;1417 inst.inline = inst.stay_open = true;1418 //This way the onSelect handler called from calendarpicker get the full dateTime1419 this._base_selectDate(id, dateStr);1420 inst.inline = was_inline;1421 inst.stay_open = false;1422 this._notifyChange(inst);1423 this._updateDatepicker(inst);1424 } else {1425 this._base_selectDate(id, dateStr);1426 }1427 };14281429 /*1430 * second bad hack :/ override datepicker so it triggers an event when changing the input field1431 * and does not redraw the datepicker on every selectDate event1432 */1433 $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;1434 $.datepicker._updateDatepicker = function (inst) {14351436 // don't popup the datepicker if there is another instance already opened1437 var input = inst.input[0];1438 if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) {1439 return;1440 }14411442 if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {14431444 this._base_updateDatepicker(inst);14451446 // Reload the time control when changing something in the input text field.1447 var tp_inst = this._get(inst, 'timepicker');1448 if (tp_inst) {1449 tp_inst._addTimePicker(inst);1450 }1451 }1452 };14531454 /*1455 * third bad hack :/ override datepicker so it allows spaces and colon in the input field1456 */1457 $.datepicker._base_doKeyPress = $.datepicker._doKeyPress;1458 $.datepicker._doKeyPress = function (event) {1459 var inst = $.datepicker._getInst(event.target),1460 tp_inst = $.datepicker._get(inst, 'timepicker');14611462 if (tp_inst) {1463 if ($.datepicker._get(inst, 'constrainInput')) {1464 var ampm = tp_inst.support.ampm,1465 tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone,1466 dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),1467 datetimeChars = tp_inst._defaults.timeFormat.toString()1468 .replace(/[hms]/g, '')1469 .replace(/TT/g, ampm ? 'APM' : '')1470 .replace(/Tt/g, ampm ? 'AaPpMm' : '')1471 .replace(/tT/g, ampm ? 'AaPpMm' : '')1472 .replace(/T/g, ampm ? 'AP' : '')1473 .replace(/tt/g, ampm ? 'apm' : '')1474 .replace(/t/g, ampm ? 'ap' : '') + 1475 " " + tp_inst._defaults.separator + 1476 tp_inst._defaults.timeSuffix + 1477 (tz ? tp_inst._defaults.timezoneList.join('') : '') + 1478 (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) + 1479 dateChars,1480 chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);1481 return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);1482 }1483 }14841485 return $.datepicker._base_doKeyPress(event);1486 };14871488 /*1489 * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField1490 * Update any alternate field to synchronise with the main field.1491 */1492 $.datepicker._base_updateAlternate = $.datepicker._updateAlternate;1493 $.datepicker._updateAlternate = function (inst) {1494 var tp_inst = this._get(inst, 'timepicker');1495 if (tp_inst) {1496 var altField = tp_inst._defaults.altField;1497 if (altField) { // update alternate field too1498 var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat,1499 date = this._getDate(inst),1500 formatCfg = $.datepicker._getFormatConfig(inst),1501 altFormattedDateTime = '', 1502 altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator, 1503 altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix,1504 altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat;1505 1506 altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix;1507 if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) {1508 if (tp_inst._defaults.altFormat) {1509 altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime;1510 }1511 else {1512 altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime;1513 }1514 }1515 $(altField).val( inst.input.val() ? altFormattedDateTime : "");1516 }1517 }1518 else {1519 $.datepicker._base_updateAlternate(inst); 1520 }1521 };15221523 /*1524 * Override key up event to sync manual input changes.1525 */1526 $.datepicker._base_doKeyUp = $.datepicker._doKeyUp;1527 $.datepicker._doKeyUp = function (event) {1528 var inst = $.datepicker._getInst(event.target),1529 tp_inst = $.datepicker._get(inst, 'timepicker');15301531 if (tp_inst) {1532 if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {1533 try {1534 $.datepicker._updateDatepicker(inst);1535 } catch (err) {1536 $.timepicker.log(err);1537 }1538 }1539 }15401541 return $.datepicker._base_doKeyUp(event);1542 };15431544 /*1545 * override "Today" button to also grab the time.1546 */1547 $.datepicker._base_gotoToday = $.datepicker._gotoToday;1548 $.datepicker._gotoToday = function (id) {1549 var inst = this._getInst($(id)[0]),1550 $dp = inst.dpDiv;1551 var tp_inst = this._get(inst, 'timepicker');1552 selectLocalTimezone(tp_inst);1553 var now = new Date();1554 this._setTime(inst, now);1555 this._setDate(inst, now);1556 this._base_gotoToday(id);1557 };15581559 /*1560 * Disable & enable the Time in the datetimepicker1561 */1562 $.datepicker._disableTimepickerDatepicker = function (target) {1563 var inst = this._getInst(target);1564 if (!inst) {1565 return;1566 }15671568 var tp_inst = this._get(inst, 'timepicker');1569 $(target).datepicker('getDate'); // Init selected[Year|Month|Day]1570 if (tp_inst) {1571 inst.settings.showTimepicker = false;1572 tp_inst._defaults.showTimepicker = false;1573 tp_inst._updateDateTime(inst);1574 }1575 };15761577 $.datepicker._enableTimepickerDatepicker = function (target) {1578 var inst = this._getInst(target);1579 if (!inst) {1580 return;1581 }15821583 var tp_inst = this._get(inst, 'timepicker');1584 $(target).datepicker('getDate'); // Init selected[Year|Month|Day]1585 if (tp_inst) {1586 inst.settings.showTimepicker = true;1587 tp_inst._defaults.showTimepicker = true;1588 tp_inst._addTimePicker(inst); // Could be disabled on page load1589 tp_inst._updateDateTime(inst);1590 }1591 };15921593 /*1594 * Create our own set time function1595 */1596 $.datepicker._setTime = function (inst, date) {1597 var tp_inst = this._get(inst, 'timepicker');1598 if (tp_inst) {1599 var defaults = tp_inst._defaults;16001601 // calling _setTime with no date sets time to defaults1602 tp_inst.hour = date ? date.getHours() : defaults.hour;1603 tp_inst.minute = date ? date.getMinutes() : defaults.minute;1604 tp_inst.second = date ? date.getSeconds() : defaults.second;1605 tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec;1606 tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec;16071608 //check if within min/max times.. 1609 tp_inst._limitMinMaxDateTime(inst, true);16101611 tp_inst._onTimeChange();1612 tp_inst._updateDateTime(inst);1613 }1614 };16151616 /*1617 * Create new public method to set only time, callable as $().datepicker('setTime', date)1618 */1619 $.datepicker._setTimeDatepicker = function (target, date, withDate) {1620 var inst = this._getInst(target);1621 if (!inst) {1622 return;1623 }16241625 var tp_inst = this._get(inst, 'timepicker');16261627 if (tp_inst) {1628 this._setDateFromField(inst);1629 var tp_date;1630 if (date) {1631 if (typeof date === "string") {1632 tp_inst._parseTime(date, withDate);1633 tp_date = new Date();1634 tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);1635 tp_date.setMicroseconds(tp_inst.microsec);1636 } else {1637 tp_date = new Date(date.getTime());1638 tp_date.setMicroseconds(date.getMicroseconds());1639 }1640 if (tp_date.toString() === 'Invalid Date') {1641 tp_date = undefined;1642 }1643 this._setTime(inst, tp_date);1644 }1645 }16461647 };16481649 /*1650 * override setDate() to allow setting time too within Date object1651 */1652 $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;1653 $.datepicker._setDateDatepicker = function (target, _date) {1654 var inst = this._getInst(target);1655 var date = _date;1656 if (!inst) {1657 return;1658 }16591660 if (typeof(_date) === 'string') {1661 date = new Date(_date);1662 if (!date.getTime()) {1663 this._base_setDateDatepicker.apply(this, arguments);1664 date = $(target).datepicker('getDate');1665 }1666 }16671668 var tp_inst = this._get(inst, 'timepicker');1669 var tp_date;1670 if (date instanceof Date) {1671 tp_date = new Date(date.getTime());1672 tp_date.setMicroseconds(date.getMicroseconds());1673 } else {1674 tp_date = date;1675 }1676 1677 // This is important if you are using the timezone option, javascript's Date 1678 // object will only return the timezone offset for the current locale, so we 1679 // adjust it accordingly. If not using timezone option this won't matter..1680 // If a timezone is different in tp, keep the timezone as is1681 if (tp_inst && tp_date) {1682 // look out for DST if tz wasn't specified1683 if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {1684 tp_inst.timezone = tp_date.getTimezoneOffset() * -1;1685 }1686 date = $.timepicker.timezoneAdjust(date, tp_inst.timezone);1687 tp_date = $.timepicker.timezoneAdjust(tp_date, tp_inst.timezone);1688 }16891690 this._updateDatepicker(inst);1691 this._base_setDateDatepicker.apply(this, arguments);1692 this._setTimeDatepicker(target, tp_date, true);1693 };16941695 /*1696 * override getDate() to allow getting time too within Date object1697 */1698 $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;1699 $.datepicker._getDateDatepicker = function (target, noDefault) {1700 var inst = this._getInst(target);1701 if (!inst) {1702 return;1703 }17041705 var tp_inst = this._get(inst, 'timepicker');17061707 if (tp_inst) {1708 // if it hasn't yet been defined, grab from field1709 if (inst.lastVal === undefined) {1710 this._setDateFromField(inst, noDefault);1711 }17121713 var date = this._getDate(inst);1714 var currDT = $.trim((tp_inst.$altInput && tp_inst._defaults.altFieldTimeOnly) ? tp_inst.$input.val() + ' ' + tp_inst.$altInput.val() : tp_inst.$input.val());1715 if (date && tp_inst._parseTime(currDT, !inst.settings.timeOnly)) {1716 date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);1717 date.setMicroseconds(tp_inst.microsec);17181719 // This is important if you are using the timezone option, javascript's Date 1720 // object will only return the timezone offset for the current locale, so we 1721 // adjust it accordingly. If not using timezone option this won't matter..1722 if (tp_inst.timezone != null) {1723 // look out for DST if tz wasn't specified1724 if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {1725 tp_inst.timezone = date.getTimezoneOffset() * -1;1726 }1727 date = $.timepicker.timezoneAdjust(date, tp_inst.timezone);1728 }1729 }1730 return date;1731 }1732 return this._base_getDateDatepicker(target, noDefault);1733 };17341735 /*1736 * override parseDate() because UI 1.8.14 throws an error about "Extra characters"1737 * An option in datapicker to ignore extra format characters would be nicer.1738 */1739 $.datepicker._base_parseDate = $.datepicker.parseDate;1740 $.datepicker.parseDate = function (format, value, settings) {1741 var date;1742 try {1743 date = this._base_parseDate(format, value, settings);1744 } catch (err) {1745 // Hack! The error message ends with a colon, a space, and1746 // the "extra" characters. We rely on that instead of1747 // attempting to perfectly reproduce the parsing algorithm.1748 if (err.indexOf(":") >= 0) {1749 date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings);1750 $.timepicker.log("Error parsing the date string: " + err + "\ndate string = " + value + "\ndate format = " + format);1751 } else {1752 throw err;1753 }1754 }1755 return date;1756 };17571758 /*1759 * override formatDate to set date with time to the input1760 */1761 $.datepicker._base_formatDate = $.datepicker._formatDate;1762 $.datepicker._formatDate = function (inst, day, month, year) {1763 var tp_inst = this._get(inst, 'timepicker');1764 if (tp_inst) {1765 tp_inst._updateDateTime(inst);1766 return tp_inst.$input.val();1767 }1768 return this._base_formatDate(inst);1769 };17701771 /*1772 * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate1773 */1774 $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;1775 $.datepicker._optionDatepicker = function (target, name, value) {1776 var inst = this._getInst(target),1777 name_clone;1778 if (!inst) {1779 return null;1780 }17811782 var tp_inst = this._get(inst, 'timepicker');1783 if (tp_inst) {1784 var min = null,1785 max = null,1786 onselect = null,1787 overrides = tp_inst._defaults.evnts,1788 fns = {},1789 prop,1790 ret,1791 oldVal,1792 $target;1793 if (typeof name === 'string') { // if min/max was set with the string1794 if (name === 'minDate' || name === 'minDateTime') {1795 min = value;1796 } else if (name === 'maxDate' || name === 'maxDateTime') {1797 max = value;1798 } else if (name === 'onSelect') {1799 onselect = value;1800 } else if (overrides.hasOwnProperty(name)) {1801 if (typeof (value) === 'undefined') {1802 return overrides[name];1803 }1804 fns[name] = value;1805 name_clone = {}; //empty results in exiting function after overrides updated1806 }1807 } else if (typeof name === 'object') { //if min/max was set with the JSON1808 if (name.minDate) {1809 min = name.minDate;1810 } else if (name.minDateTime) {1811 min = name.minDateTime;1812 } else if (name.maxDate) {1813 max = name.maxDate;1814 } else if (name.maxDateTime) {1815 max = name.maxDateTime;1816 }1817 for (prop in overrides) {1818 if (overrides.hasOwnProperty(prop) && name[prop]) {1819 fns[prop] = name[prop];1820 }1821 }1822 }1823 for (prop in fns) {1824 if (fns.hasOwnProperty(prop)) {1825 overrides[prop] = fns[prop];1826 if (!name_clone) { name_clone = $.extend({}, name); }1827 delete name_clone[prop];1828 }1829 }1830 if (name_clone && isEmptyObject(name_clone)) { return; }1831 if (min) { //if min was set1832 if (min === 0) {1833 min = new Date();1834 } else {1835 min = new Date(min);1836 }1837 tp_inst._defaults.minDate = min;1838 tp_inst._defaults.minDateTime = min;1839 } else if (max) { //if max was set1840 if (max === 0) {1841 max = new Date();1842 } else {1843 max = new Date(max);1844 }1845 tp_inst._defaults.maxDate = max;1846 tp_inst._defaults.maxDateTime = max;1847 } else if (onselect) {1848 tp_inst._defaults.onSelect = onselect;1849 }18501851 // Datepicker will override our date when we call _base_optionDatepicker when 1852 // calling minDate/maxDate, so we will first grab the value, call 1853 // _base_optionDatepicker, then set our value back.1854 if(min || max){1855 $target = $(target);1856 oldVal = $target.datetimepicker('getDate');1857 ret = this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);1858 $target.datetimepicker('setDate', oldVal);1859 return ret;1860 }1861 }1862 if (value === undefined) {1863 return this._base_optionDatepicker.call($.datepicker, target, name);1864 }1865 return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);1866 };1867 1868 /*1869 * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype,1870 * it will return false for all objects1871 */1872 var isEmptyObject = function (obj) {1873 var prop;1874 for (prop in obj) {1875 if (obj.hasOwnProperty(prop)) {1876 return false;1877 }1878 }1879 return true;1880 };18811882 /*1883 * jQuery extend now ignores nulls!1884 */1885 var extendRemove = function (target, props) {1886 $.extend(target, props);1887 for (var name in props) {1888 if (props[name] === null || props[name] === undefined) {1889 target[name] = props[name];1890 }1891 }1892 return target;1893 };18941895 /*1896 * Determine by the time format which units are supported1897 * Returns an object of booleans for each unit1898 */1899 var detectSupport = function (timeFormat) {1900 var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals1901 isIn = function (f, t) { // does the format contain the token?1902 return f.indexOf(t) !== -1 ? true : false;1903 };1904 return {1905 hour: isIn(tf, 'h'),1906 minute: isIn(tf, 'm'),1907 second: isIn(tf, 's'),1908 millisec: isIn(tf, 'l'),1909 microsec: isIn(tf, 'c'),1910 timezone: isIn(tf, 'z'),1911 ampm: isIn(tf, 't') && isIn(timeFormat, 'h'),1912 iso8601: isIn(timeFormat, 'Z')1913 };1914 };19151916 /*1917 * Converts 24 hour format into 12 hour1918 * Returns 12 hour without leading 01919 */1920 var convert24to12 = function (hour) {1921 hour %= 12;19221923 if (hour === 0) {1924 hour = 12;1925 }19261927 return String(hour);1928 };19291930 var computeEffectiveSetting = function (settings, property) {1931 return settings && settings[property] ? settings[property] : $.timepicker._defaults[property];1932 };19331934 /*1935 * Splits datetime string into date and time substrings.1936 * Throws exception when date can't be parsed1937 * Returns {dateString: dateString, timeString: timeString}1938 */1939 var splitDateTime = function (dateTimeString, timeSettings) {1940 // The idea is to get the number separator occurrences in datetime and the time format requested (since time has1941 // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.1942 var separator = computeEffectiveSetting(timeSettings, 'separator'),1943 format = computeEffectiveSetting(timeSettings, 'timeFormat'),1944 timeParts = format.split(separator), // how many occurrences of separator may be in our format?1945 timePartsLen = timeParts.length,1946 allParts = dateTimeString.split(separator),1947 allPartsLen = allParts.length;19481949 if (allPartsLen > 1) {1950 return {1951 dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator),1952 timeString: allParts.splice(0, timePartsLen).join(separator)1953 };1954 }19551956 return {1957 dateString: dateTimeString,1958 timeString: ''1959 };1960 };19611962 /*1963 * Internal function to parse datetime interval1964 * Returns: {date: Date, timeObj: Object}, where1965 * date - parsed date without time (type Date)1966 * timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional1967 */1968 var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {1969 var date,1970 parts,1971 parsedTime;19721973 parts = splitDateTime(dateTimeString, timeSettings);1974 date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings);19751976 if (parts.timeString === '') {1977 return {1978 date: date1979 };1980 }19811982 parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings);19831984 if (!parsedTime) {1985 throw 'Wrong time format';1986 }19871988 return {1989 date: date,1990 timeObj: parsedTime1991 };1992 };19931994 /*1995 * Internal function to set timezone_select to the local timezone1996 */1997 var selectLocalTimezone = function (tp_inst, date) {1998 if (tp_inst && tp_inst.timezone_select) {1999 var now = date || new Date();2000 tp_inst.timezone_select.val(-now.getTimezoneOffset());2001 }2002 };20032004 /*2005 * Create a Singleton Instance2006 */2007 $.timepicker = new Timepicker();20082009 /**2010 * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)2011 * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned2012 * @param {boolean} iso8601 if true formats in accordance to iso8601 "+12:45"2013 * @return {string}2014 */2015 $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) {2016 if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) {2017 return tzMinutes;2018 }20192020 var off = tzMinutes,2021 minutes = off % 60,2022 hours = (off - minutes) / 60,2023 iso = iso8601 ? ':' : '',2024 tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2);2025 2026 if (tz === '+00:00') {2027 return 'Z';2028 }2029 return tz;2030 };20312032 /**2033 * Get the number in minutes that represents a timezone string2034 * @param {string} tzString formatted like "+0500", "-1245", "Z"2035 * @return {number} the offset minutes or the original string if it doesn't match expectations2036 */2037 $.timepicker.timezoneOffsetNumber = function (tzString) {2038 var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with "+1245"20392040 if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset2041 return 0;2042 }20432044 if (!/^(\-|\+)\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back2045 return tzString;2046 }20472048 return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus2049 ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes)2050 parseInt(normalized.substr(3, 2), 10))); // minutes2051 };20522053 /**2054 * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate)2055 * @param {Date} date2056 * @param {string} toTimezone formatted like "+0500", "-1245"2057 * @return {Date}2058 */2059 $.timepicker.timezoneAdjust = function (date, toTimezone) {2060 var toTz = $.timepicker.timezoneOffsetNumber(toTimezone);2061 if (!isNaN(toTz)) {2062 date.setMinutes(date.getMinutes() + -date.getTimezoneOffset() - toTz);2063 }2064 return date;2065 };20662067 /**2068 * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to2069 * enforce date range limits.2070 * n.b. The input value must be correctly formatted (reformatting is not supported)2071 * @param {Element} startTime2072 * @param {Element} endTime2073 * @param {Object} options Options for the timepicker() call2074 * @return {jQuery}2075 */2076 $.timepicker.timeRange = function (startTime, endTime, options) {2077 return $.timepicker.handleRange('timepicker', startTime, endTime, options);2078 };20792080 /**2081 * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to2082 * enforce date range limits.2083 * @param {Element} startTime2084 * @param {Element} endTime2085 * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,2086 * a boolean value that can be used to reformat the input values to the `dateFormat`.2087 * @param {string} method Can be used to specify the type of picker to be added2088 * @return {jQuery}2089 */2090 $.timepicker.datetimeRange = function (startTime, endTime, options) {2091 $.timepicker.handleRange('datetimepicker', startTime, endTime, options);2092 };20932094 /**2095 * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to2096 * enforce date range limits.2097 * @param {Element} startTime2098 * @param {Element} endTime2099 * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,2100 * a boolean value that can be used to reformat the input values to the `dateFormat`.2101 * @return {jQuery}2102 */2103 $.timepicker.dateRange = function (startTime, endTime, options) {2104 $.timepicker.handleRange('datepicker', startTime, endTime, options);2105 };21062107 /**2108 * Calls `method` on the `startTime` and `endTime` elements, and configures them to2109 * enforce date range limits.2110 * @param {string} method Can be used to specify the type of picker to be added2111 * @param {Element} startTime2112 * @param {Element} endTime2113 * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,2114 * a boolean value that can be used to reformat the input values to the `dateFormat`.2115 * @return {jQuery}2116 */2117 $.timepicker.handleRange = function (method, startTime, endTime, options) {2118 options = $.extend({}, {2119 minInterval: 0, // min allowed interval in milliseconds2120 maxInterval: 0, // max allowed interval in milliseconds2121 start: {}, // options for start picker2122 end: {} // options for end picker2123 }, options);21242125 // for the mean time this fixes an issue with calling getDate with timepicker()2126 var timeOnly = false;2127 if(method === 'timepicker'){2128 timeOnly = true;2129 method = 'datetimepicker';2130 }21312132 function checkDates(changed, other) {2133 var startdt = startTime[method]('getDate'),2134 enddt = endTime[method]('getDate'),2135 changeddt = changed[method]('getDate');21362137 if (startdt !== null) {2138 var minDate = new Date(startdt.getTime()),2139 maxDate = new Date(startdt.getTime());21402141 minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval);2142 maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval);21432144 if (options.minInterval > 0 && minDate > enddt) { // minInterval check2145 endTime[method]('setDate', minDate);2146 }2147 else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check2148 endTime[method]('setDate', maxDate);2149 }2150 else if (startdt > enddt) {2151 other[method]('setDate', changeddt);2152 }2153 }2154 }21552156 function selected(changed, other, option) {2157 if (!changed.val()) {2158 return;2159 }2160 var date = changed[method].call(changed, 'getDate');2161 if (date !== null && options.minInterval > 0) {2162 if (option === 'minDate') {2163 date.setMilliseconds(date.getMilliseconds() + options.minInterval);2164 }2165 if (option === 'maxDate') {2166 date.setMilliseconds(date.getMilliseconds() - options.minInterval);2167 }2168 }2169 2170 if (date.getTime) {2171 other[method].call(other, 'option', option, date);2172 }2173 }21742175 $.fn[method].call(startTime, $.extend({2176 timeOnly: timeOnly,2177 onClose: function (dateText, inst) {2178 checkDates($(this), endTime);2179 },2180 onSelect: function (selectedDateTime) {2181 selected($(this), endTime, 'minDate');2182 }2183 }, options, options.start));2184 $.fn[method].call(endTime, $.extend({2185 timeOnly: timeOnly,2186 onClose: function (dateText, inst) {2187 checkDates($(this), startTime);2188 },2189 onSelect: function (selectedDateTime) {2190 selected($(this), startTime, 'maxDate');2191 }2192 }, options, options.end));21932194 checkDates(startTime, endTime);2195 2196 selected(startTime, endTime, 'minDate');2197 selected(endTime, startTime, 'maxDate');21982199 return $([startTime.get(0), endTime.get(0)]);2200 };22012202 /**2203 * Log error or data to the console during error or debugging2204 * @param {Object} err pass any type object to log to the console during error or debugging2205 * @return {void}2206 */2207 $.timepicker.log = function () {2208 if (window.console) {2209 window.console.log.apply(window.console, Array.prototype.slice.call(arguments));2210 }2211 };22122213 /*2214 * Add util object to allow access to private methods for testability.2215 */2216 $.timepicker._util = {2217 _extendRemove: extendRemove,2218 _isEmptyObject: isEmptyObject,2219 _convert24to12: convert24to12,2220 _detectSupport: detectSupport,2221 _selectLocalTimezone: selectLocalTimezone,2222 _computeEffectiveSetting: computeEffectiveSetting,2223 _splitDateTime: splitDateTime,2224 _parseDateTimeInternal: parseDateTimeInternal2225 };22262227 /*2228 * Microsecond support2229 */2230 if (!Date.prototype.getMicroseconds) {2231 Date.prototype.microseconds = 0;2232 Date.prototype.getMicroseconds = function () { return this.microseconds; };2233 Date.prototype.setMicroseconds = function (m) {2234 this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000));2235 this.microseconds = m % 1000;2236 return this;2237 };2238 }22392240 /*2241 * Keep up with the version2242 */2243 $.timepicker.version = "1.5.5";2244
...
jquery-ui-timepicker.js
Source:jquery-ui-timepicker.js
1/*! jQuery Timepicker Addon - v1.4.6 - 2014-08-092* http://trentrichardson.com/examples/timepicker3* Copyright (c) 2014 Trent Richardson; Licensed MIT */4(function ($) {5 /*6 * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded"7 */8 $.ui.timepicker = $.ui.timepicker || {};9 if ($.ui.timepicker.version) {10 return;11 }12 /*13 * Extend jQueryUI, get it started with our version number14 */15 $.extend($.ui, {16 timepicker: {17 version: "1.4.6"18 }19 });20 /* 21 * Timepicker manager.22 * Use the singleton instance of this class, $.timepicker, to interact with the time picker.23 * Settings for (groups of) time pickers are maintained in an instance object,24 * allowing multiple different settings on the same page.25 */26 var Timepicker = function () {27 this.regional = []; // Available regional settings, indexed by language code28 this.regional[''] = { // Default regional settings29 currentText: 'Now',30 closeText: 'Done',31 amNames: ['AM', 'A'],32 pmNames: ['PM', 'P'],33 timeFormat: 'HH:mm',34 timeSuffix: '',35 timeOnlyTitle: 'Choose Time',36 timeText: 'Time',37 hourText: 'Hour',38 minuteText: 'Minute',39 secondText: 'Second',40 millisecText: 'Millisecond',41 microsecText: 'Microsecond',42 timezoneText: 'Time Zone',43 isRTL: false44 };45 this._defaults = { // Global defaults for all the datetime picker instances46 showButtonPanel: true,47 timeOnly: false,48 timeOnlyShowDate: false,49 showHour: null,50 showMinute: null,51 showSecond: null,52 showMillisec: null,53 showMicrosec: null,54 showTimezone: null,55 showTime: true,56 stepHour: 1,57 stepMinute: 1,58 stepSecond: 1,59 stepMillisec: 1,60 stepMicrosec: 1,61 hour: 0,62 minute: 0,63 second: 0,64 millisec: 0,65 microsec: 0,66 timezone: null,67 hourMin: 0,68 minuteMin: 0,69 secondMin: 0,70 millisecMin: 0,71 microsecMin: 0,72 hourMax: 23,73 minuteMax: 59,74 secondMax: 59,75 millisecMax: 999,76 microsecMax: 999,77 minDateTime: null,78 maxDateTime: null,79 maxTime: null,80 minTime: null,81 onSelect: null,82 hourGrid: 0,83 minuteGrid: 0,84 secondGrid: 0,85 millisecGrid: 0,86 microsecGrid: 0,87 alwaysSetTime: true,88 separator: ' ',89 altFieldTimeOnly: true,90 altTimeFormat: null,91 altSeparator: null,92 altTimeSuffix: null,93 altRedirectFocus: true,94 pickerTimeFormat: null,95 pickerTimeSuffix: null,96 showTimepicker: true,97 timezoneList: null,98 addSliderAccess: false,99 sliderAccessArgs: null,100 controlType: 'slider',101 defaultValue: null,102 parse: 'strict'103 };104 $.extend(this._defaults, this.regional['']);105 };106 $.extend(Timepicker.prototype, {107 $input: null,108 $altInput: null,109 $timeObj: null,110 inst: null,111 hour_slider: null,112 minute_slider: null,113 second_slider: null,114 millisec_slider: null,115 microsec_slider: null,116 timezone_select: null,117 maxTime: null,118 minTime: null,119 hour: 0,120 minute: 0,121 second: 0,122 millisec: 0,123 microsec: 0,124 timezone: null,125 hourMinOriginal: null,126 minuteMinOriginal: null,127 secondMinOriginal: null,128 millisecMinOriginal: null,129 microsecMinOriginal: null,130 hourMaxOriginal: null,131 minuteMaxOriginal: null,132 secondMaxOriginal: null,133 millisecMaxOriginal: null,134 microsecMaxOriginal: null,135 ampm: '',136 formattedDate: '',137 formattedTime: '',138 formattedDateTime: '',139 timezoneList: null,140 units: ['hour', 'minute', 'second', 'millisec', 'microsec'],141 support: {},142 control: null,143 /* 144 * Override the default settings for all instances of the time picker.145 * @param {Object} settings object - the new settings to use as defaults (anonymous object)146 * @return {Object} the manager object147 */148 setDefaults: function (settings) {149 extendRemove(this._defaults, settings || {});150 return this;151 },152 /*153 * Create a new Timepicker instance154 */155 _newInst: function ($input, opts) {156 var tp_inst = new Timepicker(),157 inlineSettings = {},158 fns = {},159 overrides, i;160 for (var attrName in this._defaults) {161 if (this._defaults.hasOwnProperty(attrName)) {162 var attrValue = $input.attr('time:' + attrName);163 if (attrValue) {164 try {165 inlineSettings[attrName] = eval(attrValue);166 } catch (err) {167 inlineSettings[attrName] = attrValue;168 }169 }170 }171 }172 overrides = {173 beforeShow: function (input, dp_inst) {174 if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) {175 return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst);176 }177 },178 onChangeMonthYear: function (year, month, dp_inst) {179 // Update the time as well : this prevents the time from disappearing from the $input field.180 tp_inst._updateDateTime(dp_inst);181 if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) {182 tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);183 }184 },185 onClose: function (dateText, dp_inst) {186 if (tp_inst.timeDefined === true && $input.val() !== '') {187 tp_inst._updateDateTime(dp_inst);188 }189 if ($.isFunction(tp_inst._defaults.evnts.onClose)) {190 tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst);191 }192 }193 };194 for (i in overrides) {195 if (overrides.hasOwnProperty(i)) {196 fns[i] = opts[i] || null;197 }198 }199 tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, {200 evnts: fns,201 timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');202 });203 tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) {204 return val.toUpperCase();205 });206 tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) {207 return val.toUpperCase();208 });209 // detect which units are supported210 tp_inst.support = detectSupport(211 tp_inst._defaults.timeFormat + 212 (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') +213 (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : ''));214 // controlType is string - key to our this._controls215 if (typeof(tp_inst._defaults.controlType) === 'string') {216 if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === '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 methods222 else {223 tp_inst.control = tp_inst._defaults.controlType;224 }225 // prep the timezone options226 var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60,227 0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840];228 if (tp_inst._defaults.timezoneList !== null) {229 timezoneList = tp_inst._defaults.timezoneList;230 }231 var tzl = timezoneList.length, tzi = 0, tzv = null;232 if (tzl > 0 && typeof timezoneList[0] !== 'object') {233 for (; tzi < tzl; tzi++) {234 tzv = timezoneList[tzi];235 timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) };236 }237 }238 tp_inst._defaults.timezoneList = timezoneList;239 // set the default units240 tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) :241 ((new Date()).getTimezoneOffset() * -1);242 tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin :243 tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour;244 tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin :245 tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute;246 tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin :247 tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second;248 tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin :249 tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec;250 tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin :251 tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec;252 tp_inst.ampm = '';253 tp_inst.$input = $input;254 if (tp_inst._defaults.altField) {255 tp_inst.$altInput = $(tp_inst._defaults.altField);256 if (tp_inst._defaults.altRedirectFocus === true) {257 tp_inst.$altInput.css({258 cursor: 'pointer'259 }).focus(function () {260 $input.trigger("focus");261 });262 }263 }264 if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) {265 tp_inst._defaults.minDate = new Date();266 }267 if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) {268 tp_inst._defaults.maxDate = new Date();269 }270 // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..271 if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) {272 tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());273 }274 if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) {275 tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());276 }277 if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) {278 tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());279 }280 if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) {281 tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());282 }283 tp_inst.$input.bind('focus', function () {284 tp_inst._onFocus();285 });286 return tp_inst;287 },288 /*289 * add our sliders to the calendar290 */291 _addTimePicker: function (dp_inst) {292 var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val();293 this.timeDefined = this._parseTime(currDT);294 this._limitMinMaxDateTime(dp_inst, false);295 this._injectTimePicker();296 },297 /*298 * parse the time string from input value or _setTime299 */300 _parseTime: function (timeString, withDate) {301 if (!this.inst) {302 this.inst = $.datepicker._getInst(this.$input[0]);303 }304 if (withDate || !this._defaults.timeOnly) {305 var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');306 try {307 var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults);308 if (!parseRes.timeObj) {309 return false;310 }311 $.extend(this, parseRes.timeObj);312 } catch (err) {313 $.timepicker.log("Error parsing the date/time string: " + err +314 "\ndate/time string = " + timeString +315 "\ntimeFormat = " + this._defaults.timeFormat +316 "\ndateFormat = " + dp_dateFormat);317 return false;318 }319 return true;320 } else {321 var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults);322 if (!timeObj) {323 return false;324 }325 $.extend(this, timeObj);326 return true;327 }328 },329 /*330 * generate and inject html for timepicker into ui datepicker331 */332 _injectTimePicker: function () {333 var $dp = this.inst.dpDiv,334 o = this.inst.settings,335 tp_inst = this,336 litem = '',337 uitem = '',338 show = null,339 max = {},340 gridSize = {},341 size = null,342 i = 0,343 l = 0;344 // Prevent displaying twice345 if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) {346 var noDisplay = ' style="display:none;"',347 html = '<div class="ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + '"><dl>' + '<dt class="ui_tpicker_time_label"' + ((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' +348 '<dd class="ui_tpicker_time"' + ((o.showTime) ? '' : noDisplay) + '></dd>';349 // Create the markup350 for (i = 0, l = this.units.length; i < l; i++) {351 litem = this.units[i];352 uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);353 show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];354 // Added by Peter Medeiros:355 // - Figure out what the hour/minute/second max should be based on the step values.356 // - Example: if stepMinute is 15, then minMax is 45.357 max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10);358 gridSize[litem] = 0;359 html += '<dt class="ui_tpicker_' + litem + '_label"' + (show ? '' : noDisplay) + '>' + o[litem + 'Text'] + '</dt>' +360 '<dd class="ui_tpicker_' + litem + '"><div class="ui_tpicker_' + litem + '_slider"' + (show ? '' : noDisplay) + '></div>';361 if (show && o[litem + 'Grid'] > 0) {362 html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';363 if (litem === 'hour') {364 for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) {365 gridSize[litem]++;366 var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o);367 html += '<td data-for="' + litem + '">' + tmph + '</td>';368 }369 }370 else {371 for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) {372 gridSize[litem]++;373 html += '<td data-for="' + litem + '">' + ((m < 10) ? '0' : '') + m + '</td>';374 }375 }376 html += '</tr></table></div>';377 }378 html += '</dd>';379 }380 381 // Timezone382 var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone;383 html += '<dt class="ui_tpicker_timezone_label"' + (showTz ? '' : noDisplay) + '>' + o.timezoneText + '</dt>';384 html += '<dd class="ui_tpicker_timezone" ' + (showTz ? '' : noDisplay) + '></dd>';385 // Create the elements from string386 html += '</dl></div>';387 var $tp = $(html);388 // if we only want time picker...389 if (o.timeOnly === true) {390 $tp.prepend('<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + '</div>');391 $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();392 }393 394 // add sliders, adjust grids, add events395 for (i = 0, l = tp_inst.units.length; i < l; i++) {396 litem = tp_inst.units[i];397 uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);398 show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];399 // add the slider400 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]);401 // adjust the grid and add click event402 if (show && o[litem + 'Grid'] > 0) {403 size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']);404 $tp.find('.ui_tpicker_' + litem + ' table').css({405 width: size + "%",406 marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + "%"),407 marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + "%") : '0',408 borderCollapse: 'collapse'409 }).find("td").click(function (e) {410 var $t = $(this),411 h = $t.html(),412 n = parseInt(h.replace(/[^0-9]/g), 10),413 ap = h.replace(/[^apm]/ig),414 f = $t.data('for'); // loses scope, so we use data-for415 if (f === 'hour') {416 if (ap.indexOf('p') !== -1 && n < 12) {417 n += 12;418 }419 else {420 if (ap.indexOf('a') !== -1 && n === 12) {421 n = 0;422 }423 }424 }425 426 tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n);427 tp_inst._onTimeChange();428 tp_inst._onSelectHandler();429 }).css({430 cursor: 'pointer',431 width: (100 / gridSize[litem]) + '%',432 textAlign: 'center',433 overflow: 'hidden'434 });435 } // end if grid > 0436 } // end for loop437 // Add timezone options438 this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find("select");439 $.fn.append.apply(this.timezone_select,440 $.map(o.timezoneList, function (val, idx) {441 return $("<option />").val(typeof val === "object" ? val.value : val).text(typeof val === "object" ? val.label : val);442 }));443 if (typeof(this.timezone) !== "undefined" && this.timezone !== null && this.timezone !== "") {444 var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1;445 if (local_timezone === this.timezone) {446 selectLocalTimezone(tp_inst);447 } else {448 this.timezone_select.val(this.timezone);449 }450 } else {451 if (typeof(this.hour) !== "undefined" && this.hour !== null && this.hour !== "") {452 this.timezone_select.val(o.timezone);453 } else {454 selectLocalTimezone(tp_inst);455 }456 }457 this.timezone_select.change(function () {458 tp_inst._onTimeChange();459 tp_inst._onSelectHandler();460 });461 // End timezone options462 463 // inject timepicker into datepicker464 var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');465 if ($buttonPanel.length) {466 $buttonPanel.before($tp);467 } else {468 $dp.append($tp);469 }470 this.$timeObj = $tp.find('.ui_tpicker_time');471 if (this.inst !== null) {472 var timeDefined = this.timeDefined;473 this._onTimeChange();474 this.timeDefined = timeDefined;475 }476 // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/477 if (this._defaults.addSliderAccess) {478 var sliderAccessArgs = this._defaults.sliderAccessArgs,479 rtl = this._defaults.isRTL;480 sliderAccessArgs.isRTL = rtl;481 482 setTimeout(function () { // fix for inline mode483 if ($tp.find('.ui-slider-access').length === 0) {484 $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);485 // fix any grids since sliders are shorter486 var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);487 if (sliderAccessWidth) {488 $tp.find('table:visible').each(function () {489 var $g = $(this),490 oldWidth = $g.outerWidth(),491 oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''),492 newWidth = oldWidth - sliderAccessWidth,493 newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%',494 css = { width: newWidth, marginRight: 0, marginLeft: 0 };495 css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft;496 $g.css(css);497 });498 }499 }500 }, 10);501 }502 // end slideAccess integration503 tp_inst._limitMinMaxDateTime(this.inst, true);504 }505 },506 /*507 * This function tries to limit the ability to go outside the508 * min/max date range509 */510 _limitMinMaxDateTime: function (dp_inst, adjustSliders) {511 var o = this._defaults,512 dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);513 if (!this._defaults.showTimepicker) {514 return;515 } // No time so nothing to check here516 if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) {517 var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),518 minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);519 if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) {520 this.hourMinOriginal = o.hourMin;521 this.minuteMinOriginal = o.minuteMin;522 this.secondMinOriginal = o.secondMin;523 this.millisecMinOriginal = o.millisecMin;524 this.microsecMinOriginal = o.microsecMin;525 }526 if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) {527 this._defaults.hourMin = minDateTime.getHours();528 if (this.hour <= this._defaults.hourMin) {529 this.hour = this._defaults.hourMin;530 this._defaults.minuteMin = minDateTime.getMinutes();531 if (this.minute <= this._defaults.minuteMin) {532 this.minute = this._defaults.minuteMin;533 this._defaults.secondMin = minDateTime.getSeconds();534 if (this.second <= this._defaults.secondMin) {535 this.second = this._defaults.secondMin;536 this._defaults.millisecMin = minDateTime.getMilliseconds();537 if (this.millisec <= this._defaults.millisecMin) {538 this.millisec = this._defaults.millisecMin;539 this._defaults.microsecMin = minDateTime.getMicroseconds();540 } else {541 if (this.microsec < this._defaults.microsecMin) {542 this.microsec = this._defaults.microsecMin;543 }544 this._defaults.microsecMin = this.microsecMinOriginal;545 }546 } else {547 this._defaults.millisecMin = this.millisecMinOriginal;548 this._defaults.microsecMin = this.microsecMinOriginal;549 }550 } else {551 this._defaults.secondMin = this.secondMinOriginal;552 this._defaults.millisecMin = this.millisecMinOriginal;553 this._defaults.microsecMin = this.microsecMinOriginal;554 }555 } else {556 this._defaults.minuteMin = this.minuteMinOriginal;557 this._defaults.secondMin = this.secondMinOriginal;558 this._defaults.millisecMin = this.millisecMinOriginal;559 this._defaults.microsecMin = this.microsecMinOriginal;560 }561 } else {562 this._defaults.hourMin = this.hourMinOriginal;563 this._defaults.minuteMin = this.minuteMinOriginal;564 this._defaults.secondMin = this.secondMinOriginal;565 this._defaults.millisecMin = this.millisecMinOriginal;566 this._defaults.microsecMin = this.microsecMinOriginal;567 }568 }569 if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) {570 var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),571 maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);572 if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) {573 this.hourMaxOriginal = o.hourMax;574 this.minuteMaxOriginal = o.minuteMax;575 this.secondMaxOriginal = o.secondMax;576 this.millisecMaxOriginal = o.millisecMax;577 this.microsecMaxOriginal = o.microsecMax;578 }579 if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) {580 this._defaults.hourMax = maxDateTime.getHours();581 if (this.hour >= this._defaults.hourMax) {582 this.hour = this._defaults.hourMax;583 this._defaults.minuteMax = maxDateTime.getMinutes();584 if (this.minute >= this._defaults.minuteMax) {585 this.minute = this._defaults.minuteMax;586 this._defaults.secondMax = maxDateTime.getSeconds();587 if (this.second >= this._defaults.secondMax) {588 this.second = this._defaults.secondMax;589 this._defaults.millisecMax = maxDateTime.getMilliseconds();590 if (this.millisec >= this._defaults.millisecMax) {591 this.millisec = this._defaults.millisecMax;592 this._defaults.microsecMax = maxDateTime.getMicroseconds();593 } else {594 if (this.microsec > this._defaults.microsecMax) {595 this.microsec = this._defaults.microsecMax;596 }597 this._defaults.microsecMax = this.microsecMaxOriginal;598 }599 } else {600 this._defaults.millisecMax = this.millisecMaxOriginal;601 this._defaults.microsecMax = this.microsecMaxOriginal;602 }603 } else {604 this._defaults.secondMax = this.secondMaxOriginal;605 this._defaults.millisecMax = this.millisecMaxOriginal;606 this._defaults.microsecMax = this.microsecMaxOriginal;607 }608 } else {609 this._defaults.minuteMax = this.minuteMaxOriginal;610 this._defaults.secondMax = this.secondMaxOriginal;611 this._defaults.millisecMax = this.millisecMaxOriginal;612 this._defaults.microsecMax = this.microsecMaxOriginal;613 }614 } else {615 this._defaults.hourMax = this.hourMaxOriginal;616 this._defaults.minuteMax = this.minuteMaxOriginal;617 this._defaults.secondMax = this.secondMaxOriginal;618 this._defaults.millisecMax = this.millisecMaxOriginal;619 this._defaults.microsecMax = this.microsecMaxOriginal;620 }621 }622 if (dp_inst.settings.minTime!==null) { 623 var tempMinTime=new Date("01/01/1970 " + dp_inst.settings.minTime); 624 if (this.hour<tempMinTime.getHours()) {625 this.hour=this._defaults.hourMin=tempMinTime.getHours();626 this.minute=this._defaults.minuteMin=tempMinTime.getMinutes(); 627 } else if (this.hour===tempMinTime.getHours() && this.minute<tempMinTime.getMinutes()) {628 this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();629 } else { 630 if (this._defaults.hourMin<tempMinTime.getHours()) {631 this._defaults.hourMin=tempMinTime.getHours();632 this._defaults.minuteMin=tempMinTime.getMinutes(); 633 } else if (this._defaults.hourMin===tempMinTime.getHours()===this.hour && this._defaults.minuteMin<tempMinTime.getMinutes()) {634 this._defaults.minuteMin=tempMinTime.getMinutes(); 635 } else {636 this._defaults.minuteMin=0;637 }638 } 639 }640 641 if (dp_inst.settings.maxTime!==null) { 642 var tempMaxTime=new Date("01/01/1970 " + dp_inst.settings.maxTime);643 if (this.hour>tempMaxTime.getHours()) {644 this.hour=this._defaults.hourMax=tempMaxTime.getHours(); 645 this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();646 } else if (this.hour===tempMaxTime.getHours() && this.minute>tempMaxTime.getMinutes()) { 647 this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes(); 648 } else {649 if (this._defaults.hourMax>tempMaxTime.getHours()) {650 this._defaults.hourMax=tempMaxTime.getHours();651 this._defaults.minuteMax=tempMaxTime.getMinutes(); 652 } else if (this._defaults.hourMax===tempMaxTime.getHours()===this.hour && this._defaults.minuteMax>tempMaxTime.getMinutes()) {653 this._defaults.minuteMax=tempMaxTime.getMinutes(); 654 } else {655 this._defaults.minuteMax=59;656 }657 } 658 }659 660 if (adjustSliders !== undefined && adjustSliders === true) {661 var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10),662 minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10),663 secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10),664 millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10),665 microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10);666 if (this.hour_slider) {667 this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax, step: this._defaults.stepHour });668 this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour));669 }670 if (this.minute_slider) {671 this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax, step: this._defaults.stepMinute });672 this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute));673 }674 if (this.second_slider) {675 this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax, step: this._defaults.stepSecond });676 this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond));677 }678 if (this.millisec_slider) {679 this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax, step: this._defaults.stepMillisec });680 this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec));681 }682 if (this.microsec_slider) {683 this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax, step: this._defaults.stepMicrosec });684 this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec));685 }686 }687 },688 /*689 * when a slider moves, set the internal time...690 * on time change is also called when the time is updated in the text field691 */692 _onTimeChange: function () {693 if (!this._defaults.showTimepicker) {694 return;695 }696 var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false,697 minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false,698 second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false,699 millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false,700 microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false,701 timezone = (this.timezone_select) ? this.timezone_select.val() : false,702 o = this._defaults,703 pickerTimeFormat = o.pickerTimeFormat || o.timeFormat,704 pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix;705 if (typeof(hour) === 'object') {706 hour = false;707 }708 if (typeof(minute) === 'object') {709 minute = false;710 }711 if (typeof(second) === 'object') {712 second = false;713 }714 if (typeof(millisec) === 'object') {715 millisec = false;716 }717 if (typeof(microsec) === 'object') {718 microsec = false;719 }720 if (typeof(timezone) === 'object') {721 timezone = false;722 }723 if (hour !== false) {724 hour = parseInt(hour, 10);725 }726 if (minute !== false) {727 minute = parseInt(minute, 10);728 }729 if (second !== false) {730 second = parseInt(second, 10);731 }732 if (millisec !== false) {733 millisec = parseInt(millisec, 10);734 }735 if (microsec !== false) {736 microsec = parseInt(microsec, 10);737 }738 if (timezone !== false) {739 timezone = timezone.toString();740 }741 var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];742 // If the update was done in the input field, the input field should not be updated.743 // If the update was done using the sliders, update the input field.744 var hasChanged = (745 hour !== parseInt(this.hour,10) || // sliders should all be numeric746 minute !== parseInt(this.minute,10) || 747 second !== parseInt(this.second,10) || 748 millisec !== parseInt(this.millisec,10) || 749 microsec !== parseInt(this.microsec,10) || 750 (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) || 751 (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or "EST" format, so use toString()752 );753 if (hasChanged) {754 if (hour !== false) {755 this.hour = hour;756 }757 if (minute !== false) {758 this.minute = minute;759 }760 if (second !== false) {761 this.second = second;762 }763 if (millisec !== false) {764 this.millisec = millisec;765 }766 if (microsec !== false) {767 this.microsec = microsec;768 }769 if (timezone !== false) {770 this.timezone = timezone;771 }772 if (!this.inst) {773 this.inst = $.datepicker._getInst(this.$input[0]);774 }775 this._limitMinMaxDateTime(this.inst, true);776 }777 if (this.support.ampm) {778 this.ampm = ampm;779 }780 // Updates the time within the timepicker781 this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o);782 if (this.$timeObj) {783 if (pickerTimeFormat === o.timeFormat) {784 this.$timeObj.text(this.formattedTime + pickerTimeSuffix);785 }786 else {787 this.$timeObj.text($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix);788 }789 }790 this.timeDefined = true;791 if (hasChanged) {792 this._updateDateTime();793 //this.$input.focus(); // may automatically open the picker on setDate794 }795 },796 /*797 * call custom onSelect.798 * bind to sliders slidestop, and grid click.799 */800 _onSelectHandler: function () {801 var onSelect = this._defaults.onSelect || this.inst.settings.onSelect;802 var inputEl = this.$input ? this.$input[0] : null;803 if (onSelect && inputEl) {804 onSelect.apply(inputEl, [this.formattedDateTime, this]);805 }806 },807 /*808 * update our input with the new date time..809 */810 _updateDateTime: function (dp_inst) {811 dp_inst = this.inst || dp_inst;812 var dtTmp = (dp_inst.currentYear > 0? 813 new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) : 814 new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),815 dt = $.datepicker._daylightSavingAdjust(dtTmp),816 //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),817 //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)),818 dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),819 formatCfg = $.datepicker._getFormatConfig(dp_inst),820 timeAvailable = dt !== null && this.timeDefined;821 this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);822 var formattedDateTime = this.formattedDate;823 824 // if a slider was changed but datepicker doesn't have a value yet, set it825 if (dp_inst.lastVal === "") {826 dp_inst.currentYear = dp_inst.selectedYear;827 dp_inst.currentMonth = dp_inst.selectedMonth;828 dp_inst.currentDay = dp_inst.selectedDay;829 }830 /*831 * remove following lines to force every changes in date picker to change the input value832 * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker. 833 * If the user manually empty the value in the input field, the date picker will never change selected value.834 */835 //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) {836 // return;837 //}838 if (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === false) {839 formattedDateTime = this.formattedTime;840 } else if ((this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) || (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === true)) {841 formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;842 }843 this.formattedDateTime = formattedDateTime;844 if (!this._defaults.showTimepicker) {845 this.$input.val(this.formattedDate);846 } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) {847 this.$altInput.val(this.formattedTime);848 this.$input.val(this.formattedDate);849 } else if (this.$altInput) {850 this.$input.val(formattedDateTime);851 var altFormattedDateTime = '',852 altSeparator = this._defaults.altSeparator !== null ? this._defaults.altSeparator : this._defaults.separator,853 altTimeSuffix = this._defaults.altTimeSuffix !== null ? this._defaults.altTimeSuffix : this._defaults.timeSuffix;854 855 if (!this._defaults.timeOnly) {856 if (this._defaults.altFormat) {857 altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg);858 }859 else {860 altFormattedDateTime = this.formattedDate;861 }862 if (altFormattedDateTime) {863 altFormattedDateTime += altSeparator;864 }865 }866 if (this._defaults.altTimeFormat !== null) {867 altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix;868 }869 else {870 altFormattedDateTime += this.formattedTime + altTimeSuffix;871 }872 this.$altInput.val(altFormattedDateTime);873 } else {874 this.$input.val(formattedDateTime);875 }876 this.$input.trigger("change");877 },878 _onFocus: function () {879 if (!this.$input.val() && this._defaults.defaultValue) {880 this.$input.val(this._defaults.defaultValue);881 var inst = $.datepicker._getInst(this.$input.get(0)),882 tp_inst = $.datepicker._get(inst, 'timepicker');883 if (tp_inst) {884 if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {885 try {886 $.datepicker._updateDatepicker(inst);887 } catch (err) {888 $.timepicker.log(err);889 }890 }891 }892 }893 },894 /*895 * Small abstraction to control types896 * We can add more, just be sure to follow the pattern: create, options, value897 */898 _controls: {899 // slider methods900 slider: {901 create: function (tp_inst, obj, unit, val, min, max, step) {902 var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60903 return obj.prop('slide', null).slider({904 orientation: "horizontal",905 value: rtl ? val * -1 : val,906 min: rtl ? max * -1 : min,907 max: rtl ? min * -1 : max,908 step: step,909 slide: function (event, ui) {910 tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value);911 tp_inst._onTimeChange();912 },913 stop: function (event, ui) {914 tp_inst._onSelectHandler();915 }916 }); 917 },918 options: function (tp_inst, obj, unit, opts, val) {919 if (tp_inst._defaults.isRTL) {920 if (typeof(opts) === 'string') {921 if (opts === 'min' || opts === 'max') {922 if (val !== undefined) {923 return obj.slider(opts, val * -1);924 }925 return Math.abs(obj.slider(opts));926 }927 return obj.slider(opts);928 }929 var min = opts.min, 930 max = opts.max;931 opts.min = opts.max = null;932 if (min !== undefined) {933 opts.max = min * -1;934 }935 if (max !== undefined) {936 opts.min = max * -1;937 }938 return obj.slider(opts);939 }940 if (typeof(opts) === 'string' && val !== undefined) {941 return obj.slider(opts, val);942 }943 return obj.slider(opts);944 },945 value: function (tp_inst, obj, unit, val) {946 if (tp_inst._defaults.isRTL) {947 if (val !== undefined) {948 return obj.slider('value', val * -1);949 }950 return Math.abs(obj.slider('value'));951 }952 if (val !== undefined) {953 return obj.slider('value', val);954 }955 return obj.slider('value');956 }957 },958 // select methods959 select: {960 create: function (tp_inst, obj, unit, val, min, max, step) {961 var sel = '<select class="ui-timepicker-select" data-unit="' + unit + '" data-min="' + min + '" data-max="' + max + '" data-step="' + step + '">',962 format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat;963 for (var i = min; i <= max; i += step) {964 sel += '<option value="' + i + '"' + (i === val ? ' selected' : '') + '>';965 if (unit === 'hour') {966 sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults);967 }968 else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; }969 else {sel += '0' + i.toString(); }970 sel += '</option>';971 }972 sel += '</select>';973 obj.children('select').remove();974 $(sel).appendTo(obj).change(function (e) {975 tp_inst._onTimeChange();976 tp_inst._onSelectHandler();977 });978 return obj;979 },980 options: function (tp_inst, obj, unit, opts, val) {981 var o = {},982 $t = obj.children('select');983 if (typeof(opts) === 'string') {984 if (val === undefined) {985 return $t.data(opts);986 }987 o[opts] = val; 988 }989 else { o = opts; }990 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'));991 },992 value: function (tp_inst, obj, unit, val) {993 var $t = obj.children('select');994 if (val !== undefined) {995 return $t.val(val);996 }997 return $t.val();998 }999 }1000 } // end _controls1001 });1002 $.fn.extend({1003 /*1004 * shorthand just to use timepicker.1005 */1006 timepicker: function (o) {1007 o = o || {};1008 var tmp_args = Array.prototype.slice.call(arguments);1009 if (typeof o === 'object') {1010 tmp_args[0] = $.extend(o, {1011 timeOnly: true1012 });1013 }1014 return $(this).each(function () {1015 $.fn.datetimepicker.apply($(this), tmp_args);1016 });1017 },1018 /*1019 * extend timepicker to datepicker1020 */1021 datetimepicker: function (o) {1022 o = o || {};1023 var tmp_args = arguments;1024 if (typeof(o) === 'string') {1025 if (o === 'getDate' || (o === 'option' && tmp_args.length === 2 && typeof (tmp_args[1]) === 'string')) {1026 return $.fn.datepicker.apply($(this[0]), tmp_args);1027 } else {1028 return this.each(function () {1029 var $t = $(this);1030 $t.datepicker.apply($t, tmp_args);1031 });1032 }1033 } else {1034 return this.each(function () {1035 var $t = $(this);1036 $t.datepicker($.timepicker._newInst($t, o)._defaults);1037 });1038 }1039 }1040 });1041 /*1042 * Public Utility to parse date and time1043 */1044 $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {1045 var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings);1046 if (parseRes.timeObj) {1047 var t = parseRes.timeObj;1048 parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec);1049 parseRes.date.setMicroseconds(t.microsec);1050 }1051 return parseRes.date;1052 };1053 /*1054 * Public utility to parse time1055 */1056 $.datepicker.parseTime = function (timeFormat, timeString, options) {1057 var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}),1058 iso8601 = (timeFormat.replace(/\'.*?\'/g, '').indexOf('Z') !== -1);1059 // Strict parse requires the timeString to match the timeFormat exactly1060 var strictParse = function (f, s, o) {1061 // pattern for standard and localized AM/PM markers1062 var getPatternAmpm = function (amNames, pmNames) {1063 var markers = [];1064 if (amNames) {1065 $.merge(markers, amNames);1066 }1067 if (pmNames) {1068 $.merge(markers, pmNames);1069 }1070 markers = $.map(markers, function (val) {1071 return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&');1072 });1073 return '(' + markers.join('|') + ')?';1074 };1075 // figure out position of time elements.. cause js cant do named captures1076 var getFormatPositions = function (timeFormat) {1077 var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),1078 orders = {1079 h: -1,1080 m: -1,1081 s: -1,1082 l: -1,1083 c: -1,1084 t: -1,1085 z: -11086 };1087 if (finds) {1088 for (var i = 0; i < finds.length; i++) {1089 if (orders[finds[i].toString().charAt(0)] === -1) {1090 orders[finds[i].toString().charAt(0)] = i + 1;1091 }1092 }1093 }1094 return orders;1095 };1096 var regstr = '^' + f.toString()1097 .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {1098 var ml = match.length;1099 switch (match.charAt(0).toLowerCase()) {1100 case 'h':1101 return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';1102 case 'm':1103 return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';1104 case 's':1105 return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';1106 case 'l':1107 return '(\\d?\\d?\\d)';1108 case 'c':1109 return '(\\d?\\d?\\d)';1110 case 'z':1111 return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?';1112 case 't':1113 return getPatternAmpm(o.amNames, o.pmNames);1114 default: // literal escaped in quotes1115 return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?';1116 }1117 })1118 .replace(/\s/g, '\\s?') +1119 o.timeSuffix + '$',1120 order = getFormatPositions(f),1121 ampm = '',1122 treg;1123 treg = s.match(new RegExp(regstr, 'i'));1124 var resTime = {1125 hour: 0,1126 minute: 0,1127 second: 0,1128 millisec: 0,1129 microsec: 01130 };1131 if (treg) {1132 if (order.t !== -1) {1133 if (treg[order.t] === undefined || treg[order.t].length === 0) {1134 ampm = '';1135 resTime.ampm = '';1136 } else {1137 ampm = $.inArray(treg[order.t].toUpperCase(), o.amNames) !== -1 ? 'AM' : 'PM';1138 resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0];1139 }1140 }1141 if (order.h !== -1) {1142 if (ampm === 'AM' && treg[order.h] === '12') {1143 resTime.hour = 0; // 12am = 0 hour1144 } else {1145 if (ampm === 'PM' && treg[order.h] !== '12') {1146 resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 121147 } else {1148 resTime.hour = Number(treg[order.h]);1149 }1150 }1151 }1152 if (order.m !== -1) {1153 resTime.minute = Number(treg[order.m]);1154 }1155 if (order.s !== -1) {1156 resTime.second = Number(treg[order.s]);1157 }1158 if (order.l !== -1) {1159 resTime.millisec = Number(treg[order.l]);1160 }1161 if (order.c !== -1) {1162 resTime.microsec = Number(treg[order.c]);1163 }1164 if (order.z !== -1 && treg[order.z] !== undefined) {1165 resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]);1166 }1167 return resTime;1168 }1169 return false;1170 };// end strictParse1171 // First try JS Date, if that fails, use strictParse1172 var looseParse = function (f, s, o) {1173 try {1174 var d = new Date('2012-01-01 ' + s);1175 if (isNaN(d.getTime())) {1176 d = new Date('2012-01-01T' + s);1177 if (isNaN(d.getTime())) {1178 d = new Date('01/01/2012 ' + s);1179 if (isNaN(d.getTime())) {1180 throw "Unable to parse time with native Date: " + s;1181 }1182 }1183 }1184 return {1185 hour: d.getHours(),1186 minute: d.getMinutes(),1187 second: d.getSeconds(),1188 millisec: d.getMilliseconds(),1189 microsec: d.getMicroseconds(),1190 timezone: d.getTimezoneOffset() * -11191 };1192 }1193 catch (err) {1194 try {1195 return strictParse(f, s, o);1196 }1197 catch (err2) {1198 $.timepicker.log("Unable to parse \ntimeString: " + s + "\ntimeFormat: " + f);1199 } 1200 }1201 return false;1202 }; // end looseParse1203 1204 if (typeof o.parse === "function") {1205 return o.parse(timeFormat, timeString, o);1206 }1207 if (o.parse === 'loose') {1208 return looseParse(timeFormat, timeString, o);1209 }1210 return strictParse(timeFormat, timeString, o);1211 };1212 /**1213 * Public utility to format the time1214 * @param {string} format format of the time1215 * @param {Object} time Object not a Date for timezones1216 * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm1217 * @returns {string} the formatted time1218 */1219 $.datepicker.formatTime = function (format, time, options) {1220 options = options || {};1221 options = $.extend({}, $.timepicker._defaults, options);1222 time = $.extend({1223 hour: 0,1224 minute: 0,1225 second: 0,1226 millisec: 0,1227 microsec: 0,1228 timezone: null1229 }, time);1230 var tmptime = format,1231 ampmName = options.amNames[0],1232 hour = parseInt(time.hour, 10);1233 if (hour > 11) {1234 ampmName = options.pmNames[0];1235 }1236 tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {1237 switch (match) {1238 case 'HH':1239 return ('0' + hour).slice(-2);1240 case 'H':1241 return hour;1242 case 'hh':1243 return ('0' + convert24to12(hour)).slice(-2);1244 case 'h':1245 return convert24to12(hour);1246 case 'mm':1247 return ('0' + time.minute).slice(-2);1248 case 'm':1249 return time.minute;1250 case 'ss':1251 return ('0' + time.second).slice(-2);1252 case 's':1253 return time.second;1254 case 'l':1255 return ('00' + time.millisec).slice(-3);1256 case 'c':1257 return ('00' + time.microsec).slice(-3);1258 case 'z':1259 return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false);1260 case 'Z':1261 return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true);1262 case 'T':1263 return ampmName.charAt(0).toUpperCase();1264 case 'TT':1265 return ampmName.toUpperCase();1266 case 't':1267 return ampmName.charAt(0).toLowerCase();1268 case 'tt':1269 return ampmName.toLowerCase();1270 default:1271 return match.replace(/'/g, "");1272 }1273 });1274 return tmptime;1275 };1276 /*1277 * the bad hack :/ override datepicker so it doesn't close on select1278 // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#17623781279 */1280 $.datepicker._base_selectDate = $.datepicker._selectDate;1281 $.datepicker._selectDate = function (id, dateStr) {1282 var inst = this._getInst($(id)[0]),1283 tp_inst = this._get(inst, 'timepicker');1284 if (tp_inst && inst.settings.showTimepicker) {1285 tp_inst._limitMinMaxDateTime(inst, true);1286 inst.inline = inst.stay_open = true;1287 //This way the onSelect handler called from calendarpicker get the full dateTime1288 this._base_selectDate(id, dateStr);1289 inst.inline = inst.stay_open = false;1290 this._notifyChange(inst);1291 this._updateDatepicker(inst);1292 } else {1293 this._base_selectDate(id, dateStr);1294 }1295 };1296 /*1297 * second bad hack :/ override datepicker so it triggers an event when changing the input field1298 * and does not redraw the datepicker on every selectDate event1299 */1300 $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;1301 $.datepicker._updateDatepicker = function (inst) {1302 // don't popup the datepicker if there is another instance already opened1303 var input = inst.input[0];1304 if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) {1305 return;1306 }1307 if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {1308 this._base_updateDatepicker(inst);1309 // Reload the time control when changing something in the input text field.1310 var tp_inst = this._get(inst, 'timepicker');1311 if (tp_inst) {1312 tp_inst._addTimePicker(inst);1313 }1314 }1315 };1316 /*1317 * third bad hack :/ override datepicker so it allows spaces and colon in the input field1318 */1319 $.datepicker._base_doKeyPress = $.datepicker._doKeyPress;1320 $.datepicker._doKeyPress = function (event) {1321 var inst = $.datepicker._getInst(event.target),1322 tp_inst = $.datepicker._get(inst, 'timepicker');1323 if (tp_inst) {1324 if ($.datepicker._get(inst, 'constrainInput')) {1325 var ampm = tp_inst.support.ampm,1326 tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone,1327 dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),1328 datetimeChars = tp_inst._defaults.timeFormat.toString()1329 .replace(/[hms]/g, '')1330 .replace(/TT/g, ampm ? 'APM' : '')1331 .replace(/Tt/g, ampm ? 'AaPpMm' : '')1332 .replace(/tT/g, ampm ? 'AaPpMm' : '')1333 .replace(/T/g, ampm ? 'AP' : '')1334 .replace(/tt/g, ampm ? 'apm' : '')1335 .replace(/t/g, ampm ? 'ap' : '') + 1336 " " + tp_inst._defaults.separator + 1337 tp_inst._defaults.timeSuffix + 1338 (tz ? tp_inst._defaults.timezoneList.join('') : '') + 1339 (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) + 1340 dateChars,1341 chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);1342 return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);1343 }1344 }1345 return $.datepicker._base_doKeyPress(event);1346 };1347 /*1348 * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField1349 * Update any alternate field to synchronise with the main field.1350 */1351 $.datepicker._base_updateAlternate = $.datepicker._updateAlternate;1352 $.datepicker._updateAlternate = function (inst) {1353 var tp_inst = this._get(inst, 'timepicker');1354 if (tp_inst) {1355 var altField = tp_inst._defaults.altField;1356 if (altField) { // update alternate field too1357 var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat,1358 date = this._getDate(inst),1359 formatCfg = $.datepicker._getFormatConfig(inst),1360 altFormattedDateTime = '', 1361 altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator, 1362 altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix,1363 altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat;1364 1365 altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix;1366 if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) {1367 if (tp_inst._defaults.altFormat) {1368 altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime;1369 }1370 else {1371 altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime;1372 }1373 }1374 $(altField).val( inst.input.val() ? altFormattedDateTime : "");1375 }1376 }1377 else {1378 $.datepicker._base_updateAlternate(inst); 1379 }1380 };1381 /*1382 * Override key up event to sync manual input changes.1383 */1384 $.datepicker._base_doKeyUp = $.datepicker._doKeyUp;1385 $.datepicker._doKeyUp = function (event) {1386 var inst = $.datepicker._getInst(event.target),1387 tp_inst = $.datepicker._get(inst, 'timepicker');1388 if (tp_inst) {1389 if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {1390 try {1391 $.datepicker._updateDatepicker(inst);1392 } catch (err) {1393 $.timepicker.log(err);1394 }1395 }1396 }1397 return $.datepicker._base_doKeyUp(event);1398 };1399 /*1400 * override "Today" button to also grab the time.1401 */1402 $.datepicker._base_gotoToday = $.datepicker._gotoToday;1403 $.datepicker._gotoToday = function (id) {1404 var inst = this._getInst($(id)[0]),1405 $dp = inst.dpDiv;1406 this._base_gotoToday(id);1407 var tp_inst = this._get(inst, 'timepicker');1408 selectLocalTimezone(tp_inst);1409 var now = new Date();1410 this._setTime(inst, now);1411 $('.ui-datepicker-today', $dp).click();1412 };1413 /*1414 * Disable & enable the Time in the datetimepicker1415 */1416 $.datepicker._disableTimepickerDatepicker = function (target) {1417 var inst = this._getInst(target);1418 if (!inst) {1419 return;1420 }1421 var tp_inst = this._get(inst, 'timepicker');1422 $(target).datepicker('getDate'); // Init selected[Year|Month|Day]1423 if (tp_inst) {1424 inst.settings.showTimepicker = false;1425 tp_inst._defaults.showTimepicker = false;1426 tp_inst._updateDateTime(inst);1427 }1428 };1429 $.datepicker._enableTimepickerDatepicker = function (target) {1430 var inst = this._getInst(target);1431 if (!inst) {1432 return;1433 }1434 var tp_inst = this._get(inst, 'timepicker');1435 $(target).datepicker('getDate'); // Init selected[Year|Month|Day]1436 if (tp_inst) {1437 inst.settings.showTimepicker = true;1438 tp_inst._defaults.showTimepicker = true;1439 tp_inst._addTimePicker(inst); // Could be disabled on page load1440 tp_inst._updateDateTime(inst);1441 }1442 };1443 /*1444 * Create our own set time function1445 */1446 $.datepicker._setTime = function (inst, date) {1447 var tp_inst = this._get(inst, 'timepicker');1448 if (tp_inst) {1449 var defaults = tp_inst._defaults;1450 // calling _setTime with no date sets time to defaults1451 tp_inst.hour = date ? date.getHours() : defaults.hour;1452 tp_inst.minute = date ? date.getMinutes() : defaults.minute;1453 tp_inst.second = date ? date.getSeconds() : defaults.second;1454 tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec;1455 tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec;1456 //check if within min/max times.. 1457 tp_inst._limitMinMaxDateTime(inst, true);1458 tp_inst._onTimeChange();1459 tp_inst._updateDateTime(inst);1460 }1461 };1462 /*1463 * Create new public method to set only time, callable as $().datepicker('setTime', date)1464 */1465 $.datepicker._setTimeDatepicker = function (target, date, withDate) {1466 var inst = this._getInst(target);1467 if (!inst) {1468 return;1469 }1470 var tp_inst = this._get(inst, 'timepicker');1471 if (tp_inst) {1472 this._setDateFromField(inst);1473 var tp_date;1474 if (date) {1475 if (typeof date === "string") {1476 tp_inst._parseTime(date, withDate);1477 tp_date = new Date();1478 tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);1479 tp_date.setMicroseconds(tp_inst.microsec);1480 } else {1481 tp_date = new Date(date.getTime());1482 tp_date.setMicroseconds(date.getMicroseconds());1483 }1484 if (tp_date.toString() === 'Invalid Date') {1485 tp_date = undefined;1486 }1487 this._setTime(inst, tp_date);1488 }1489 }1490 };1491 /*1492 * override setDate() to allow setting time too within Date object1493 */1494 $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;1495 $.datepicker._setDateDatepicker = function (target, _date) {1496 var inst = this._getInst(target);1497 var date = _date;1498 if (!inst) {1499 return;1500 }1501 if (typeof(_date) === 'string') {1502 date = new Date(_date);1503 if (!date.getTime()) {1504 this._base_setDateDatepicker.apply(this, arguments);1505 date = $(target).datepicker('getDate');1506 }1507 }1508 var tp_inst = this._get(inst, 'timepicker');1509 var tp_date;1510 if (date instanceof Date) {1511 tp_date = new Date(date.getTime());1512 tp_date.setMicroseconds(date.getMicroseconds());1513 } else {1514 tp_date = date;1515 }1516 1517 // This is important if you are using the timezone option, javascript's Date 1518 // object will only return the timezone offset for the current locale, so we 1519 // adjust it accordingly. If not using timezone option this won't matter..1520 // If a timezone is different in tp, keep the timezone as is1521 if (tp_inst && tp_date) {1522 // look out for DST if tz wasn't specified1523 if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {1524 tp_inst.timezone = tp_date.getTimezoneOffset() * -1;1525 }1526 date = $.timepicker.timezoneAdjust(date, tp_inst.timezone);1527 tp_date = $.timepicker.timezoneAdjust(tp_date, tp_inst.timezone);1528 }1529 this._updateDatepicker(inst);1530 this._base_setDateDatepicker.apply(this, arguments);1531 this._setTimeDatepicker(target, tp_date, true);1532 };1533 /*1534 * override getDate() to allow getting time too within Date object1535 */1536 $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;1537 $.datepicker._getDateDatepicker = function (target, noDefault) {1538 var inst = this._getInst(target);1539 if (!inst) {1540 return;1541 }1542 var tp_inst = this._get(inst, 'timepicker');1543 if (tp_inst) {1544 // if it hasn't yet been defined, grab from field1545 if (inst.lastVal === undefined) {1546 this._setDateFromField(inst, noDefault);1547 }1548 var date = this._getDate(inst);1549 if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) {1550 date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);1551 date.setMicroseconds(tp_inst.microsec);1552 // This is important if you are using the timezone option, javascript's Date 1553 // object will only return the timezone offset for the current locale, so we 1554 // adjust it accordingly. If not using timezone option this won't matter..1555 if (tp_inst.timezone != null) {1556 // look out for DST if tz wasn't specified1557 if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {1558 tp_inst.timezone = date.getTimezoneOffset() * -1;1559 }1560 date = $.timepicker.timezoneAdjust(date, tp_inst.timezone);1561 }1562 }1563 return date;1564 }1565 return this._base_getDateDatepicker(target, noDefault);1566 };1567 /*1568 * override parseDate() because UI 1.8.14 throws an error about "Extra characters"1569 * An option in datapicker to ignore extra format characters would be nicer.1570 */1571 $.datepicker._base_parseDate = $.datepicker.parseDate;1572 $.datepicker.parseDate = function (format, value, settings) {1573 var date;1574 try {1575 date = this._base_parseDate(format, value, settings);1576 } catch (err) {1577 // Hack! The error message ends with a colon, a space, and1578 // the "extra" characters. We rely on that instead of1579 // attempting to perfectly reproduce the parsing algorithm.1580 if (err.indexOf(":") >= 0) {1581 date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings);1582 $.timepicker.log("Error parsing the date string: " + err + "\ndate string = " + value + "\ndate format = " + format);1583 } else {1584 throw err;1585 }1586 }1587 return date;1588 };1589 /*1590 * override formatDate to set date with time to the input1591 */1592 $.datepicker._base_formatDate = $.datepicker._formatDate;1593 $.datepicker._formatDate = function (inst, day, month, year) {1594 var tp_inst = this._get(inst, 'timepicker');1595 if (tp_inst) {1596 tp_inst._updateDateTime(inst);1597 return tp_inst.$input.val();1598 }1599 return this._base_formatDate(inst);1600 };1601 /*1602 * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate1603 */1604 $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;1605 $.datepicker._optionDatepicker = function (target, name, value) {1606 var inst = this._getInst(target),1607 name_clone;1608 if (!inst) {1609 return null;1610 }1611 var tp_inst = this._get(inst, 'timepicker');1612 if (tp_inst) {1613 var min = null,1614 max = null,1615 onselect = null,1616 overrides = tp_inst._defaults.evnts,1617 fns = {},1618 prop;1619 if (typeof name === 'string') { // if min/max was set with the string1620 if (name === 'minDate' || name === 'minDateTime') {1621 min = value;1622 } else if (name === 'maxDate' || name === 'maxDateTime') {1623 max = value;1624 } else if (name === 'onSelect') {1625 onselect = value;1626 } else if (overrides.hasOwnProperty(name)) {1627 if (typeof (value) === 'undefined') {1628 return overrides[name];1629 }1630 fns[name] = value;1631 name_clone = {}; //empty results in exiting function after overrides updated1632 }1633 } else if (typeof name === 'object') { //if min/max was set with the JSON1634 if (name.minDate) {1635 min = name.minDate;1636 } else if (name.minDateTime) {1637 min = name.minDateTime;1638 } else if (name.maxDate) {1639 max = name.maxDate;1640 } else if (name.maxDateTime) {1641 max = name.maxDateTime;1642 }1643 for (prop in overrides) {1644 if (overrides.hasOwnProperty(prop) && name[prop]) {1645 fns[prop] = name[prop];1646 }1647 }1648 }1649 for (prop in fns) {1650 if (fns.hasOwnProperty(prop)) {1651 overrides[prop] = fns[prop];1652 if (!name_clone) { name_clone = $.extend({}, name); }1653 delete name_clone[prop];1654 }1655 }1656 if (name_clone && isEmptyObject(name_clone)) { return; }1657 if (min) { //if min was set1658 if (min === 0) {1659 min = new Date();1660 } else {1661 min = new Date(min);1662 }1663 tp_inst._defaults.minDate = min;1664 tp_inst._defaults.minDateTime = min;1665 } else if (max) { //if max was set1666 if (max === 0) {1667 max = new Date();1668 } else {1669 max = new Date(max);1670 }1671 tp_inst._defaults.maxDate = max;1672 tp_inst._defaults.maxDateTime = max;1673 } else if (onselect) {1674 tp_inst._defaults.onSelect = onselect;1675 }1676 }1677 if (value === undefined) {1678 return this._base_optionDatepicker.call($.datepicker, target, name);1679 }1680 return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);1681 };1682 1683 /*1684 * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype,1685 * it will return false for all objects1686 */1687 var isEmptyObject = function (obj) {1688 var prop;1689 for (prop in obj) {1690 if (obj.hasOwnProperty(prop)) {1691 return false;1692 }1693 }1694 return true;1695 };1696 /*1697 * jQuery extend now ignores nulls!1698 */1699 var extendRemove = function (target, props) {1700 $.extend(target, props);1701 for (var name in props) {1702 if (props[name] === null || props[name] === undefined) {1703 target[name] = props[name];1704 }1705 }1706 return target;1707 };1708 /*1709 * Determine by the time format which units are supported1710 * Returns an object of booleans for each unit1711 */1712 var detectSupport = function (timeFormat) {1713 var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals1714 isIn = function (f, t) { // does the format contain the token?1715 return f.indexOf(t) !== -1 ? true : false;1716 };1717 return {1718 hour: isIn(tf, 'h'),1719 minute: isIn(tf, 'm'),1720 second: isIn(tf, 's'),1721 millisec: isIn(tf, 'l'),1722 microsec: isIn(tf, 'c'),1723 timezone: isIn(tf, 'z'),1724 ampm: isIn(tf, 't') && isIn(timeFormat, 'h'),1725 iso8601: isIn(timeFormat, 'Z')1726 };1727 };1728 /*1729 * Converts 24 hour format into 12 hour1730 * Returns 12 hour without leading 01731 */1732 var convert24to12 = function (hour) {1733 hour %= 12;1734 if (hour === 0) {1735 hour = 12;1736 }1737 return String(hour);1738 };1739 var computeEffectiveSetting = function (settings, property) {1740 return settings && settings[property] ? settings[property] : $.timepicker._defaults[property];1741 };1742 /*1743 * Splits datetime string into date and time substrings.1744 * Throws exception when date can't be parsed1745 * Returns {dateString: dateString, timeString: timeString}1746 */1747 var splitDateTime = function (dateTimeString, timeSettings) {1748 // The idea is to get the number separator occurrences in datetime and the time format requested (since time has1749 // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.1750 var separator = computeEffectiveSetting(timeSettings, 'separator'),1751 format = computeEffectiveSetting(timeSettings, 'timeFormat'),1752 timeParts = format.split(separator), // how many occurrences of separator may be in our format?1753 timePartsLen = timeParts.length,1754 allParts = dateTimeString.split(separator),1755 allPartsLen = allParts.length;1756 if (allPartsLen > 1) {1757 return {1758 dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator),1759 timeString: allParts.splice(0, timePartsLen).join(separator)1760 };1761 }1762 return {1763 dateString: dateTimeString,1764 timeString: ''1765 };1766 };1767 /*1768 * Internal function to parse datetime interval1769 * Returns: {date: Date, timeObj: Object}, where1770 * date - parsed date without time (type Date)1771 * timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional1772 */1773 var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {1774 var date,1775 parts,1776 parsedTime;1777 parts = splitDateTime(dateTimeString, timeSettings);1778 date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings);1779 if (parts.timeString === '') {1780 return {1781 date: date1782 };1783 }1784 parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings);1785 if (!parsedTime) {1786 throw 'Wrong time format';1787 }1788 return {1789 date: date,1790 timeObj: parsedTime1791 };1792 };1793 /*1794 * Internal function to set timezone_select to the local timezone1795 */1796 var selectLocalTimezone = function (tp_inst, date) {1797 if (tp_inst && tp_inst.timezone_select) {1798 var now = date || new Date();1799 tp_inst.timezone_select.val(-now.getTimezoneOffset());1800 }1801 };1802 /*1803 * Create a Singleton Instance1804 */1805 $.timepicker = new Timepicker();1806 /**1807 * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)1808 * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned1809 * @param {boolean} iso8601 if true formats in accordance to iso8601 "+12:45"1810 * @return {string}1811 */1812 $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) {1813 if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) {1814 return tzMinutes;1815 }1816 var off = tzMinutes,1817 minutes = off % 60,1818 hours = (off - minutes) / 60,1819 iso = iso8601 ? ':' : '',1820 tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2);1821 1822 if (tz === '+00:00') {1823 return 'Z';1824 }1825 return tz;1826 };1827 /**1828 * Get the number in minutes that represents a timezone string1829 * @param {string} tzString formatted like "+0500", "-1245", "Z"1830 * @return {number} the offset minutes or the original string if it doesn't match expectations1831 */1832 $.timepicker.timezoneOffsetNumber = function (tzString) {1833 var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with "+1245"1834 if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset1835 return 0;1836 }1837 if (!/^(\-|\+)\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back1838 return tzString;1839 }1840 return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus1841 ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes)1842 parseInt(normalized.substr(3, 2), 10))); // minutes1843 };1844 /**1845 * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate)1846 * @param {Date} date1847 * @param {string} toTimezone formatted like "+0500", "-1245"1848 * @return {Date}1849 */1850 $.timepicker.timezoneAdjust = function (date, toTimezone) {1851 var toTz = $.timepicker.timezoneOffsetNumber(toTimezone);1852 if (!isNaN(toTz)) {1853 date.setMinutes(date.getMinutes() + -date.getTimezoneOffset() - toTz);1854 }1855 return date;1856 };1857 /**1858 * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to1859 * enforce date range limits.1860 * n.b. The input value must be correctly formatted (reformatting is not supported)1861 * @param {Element} startTime1862 * @param {Element} endTime1863 * @param {Object} options Options for the timepicker() call1864 * @return {jQuery}1865 */1866 $.timepicker.timeRange = function (startTime, endTime, options) {1867 return $.timepicker.handleRange('timepicker', startTime, endTime, options);1868 };1869 /**1870 * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to1871 * enforce date range limits.1872 * @param {Element} startTime1873 * @param {Element} endTime1874 * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,1875 * a boolean value that can be used to reformat the input values to the `dateFormat`.1876 * @param {string} method Can be used to specify the type of picker to be added1877 * @return {jQuery}1878 */1879 $.timepicker.datetimeRange = function (startTime, endTime, options) {1880 $.timepicker.handleRange('datetimepicker', startTime, endTime, options);1881 };1882 /**1883 * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to1884 * enforce date range limits.1885 * @param {Element} startTime1886 * @param {Element} endTime1887 * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,1888 * a boolean value that can be used to reformat the input values to the `dateFormat`.1889 * @return {jQuery}1890 */1891 $.timepicker.dateRange = function (startTime, endTime, options) {1892 $.timepicker.handleRange('datepicker', startTime, endTime, options);1893 };1894 /**1895 * Calls `method` on the `startTime` and `endTime` elements, and configures them to1896 * enforce date range limits.1897 * @param {string} method Can be used to specify the type of picker to be added1898 * @param {Element} startTime1899 * @param {Element} endTime1900 * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,1901 * a boolean value that can be used to reformat the input values to the `dateFormat`.1902 * @return {jQuery}1903 */1904 $.timepicker.handleRange = function (method, startTime, endTime, options) {1905 options = $.extend({}, {1906 minInterval: 0, // min allowed interval in milliseconds1907 maxInterval: 0, // max allowed interval in milliseconds1908 start: {}, // options for start picker1909 end: {} // options for end picker1910 }, options);1911 // for the mean time this fixes an issue with calling getDate with timepicker()1912 var timeOnly = false;1913 if(method === 'timepicker'){1914 timeOnly = true;1915 method = 'datetimepicker';1916 }1917 function checkDates(changed, other) {1918 var startdt = startTime[method]('getDate'),1919 enddt = endTime[method]('getDate'),1920 changeddt = changed[method]('getDate');1921 if (startdt !== null) {1922 var minDate = new Date(startdt.getTime()),1923 maxDate = new Date(startdt.getTime());1924 minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval);1925 maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval);1926 if (options.minInterval > 0 && minDate > enddt) { // minInterval check1927 endTime[method]('setDate', minDate);1928 }1929 else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check1930 endTime[method]('setDate', maxDate);1931 }1932 else if (startdt > enddt) {1933 other[method]('setDate', changeddt);1934 }1935 }1936 }1937 function selected(changed, other, option) {1938 if (!changed.val()) {1939 return;1940 }1941 var date = changed[method].call(changed, 'getDate');1942 if (date !== null && options.minInterval > 0) {1943 if (option === 'minDate') {1944 date.setMilliseconds(date.getMilliseconds() + options.minInterval);1945 }1946 if (option === 'maxDate') {1947 date.setMilliseconds(date.getMilliseconds() - options.minInterval);1948 }1949 }1950 if (date.getTime) {1951 other[method].call(other, 'option', option, date);1952 }1953 }1954 $.fn[method].call(startTime, $.extend({1955 timeOnly: timeOnly,1956 onClose: function (dateText, inst) {1957 checkDates($(this), endTime);1958 },1959 onSelect: function (selectedDateTime) {1960 selected($(this), endTime, 'minDate');1961 }1962 }, options, options.start));1963 $.fn[method].call(endTime, $.extend({1964 timeOnly: timeOnly,1965 onClose: function (dateText, inst) {1966 checkDates($(this), startTime);1967 },1968 onSelect: function (selectedDateTime) {1969 selected($(this), startTime, 'maxDate');1970 }1971 }, options, options.end));1972 checkDates(startTime, endTime);1973 selected(startTime, endTime, 'minDate');1974 selected(endTime, startTime, 'maxDate');1975 return $([startTime.get(0), endTime.get(0)]);1976 };1977 /**1978 * Log error or data to the console during error or debugging1979 * @param {Object} err pass any type object to log to the console during error or debugging1980 * @return {void}1981 */1982 $.timepicker.log = function (err) {1983 if (window.console) {1984 window.console.log(err);1985 }1986 };1987 /*1988 * Add util object to allow access to private methods for testability.1989 */1990 $.timepicker._util = {1991 _extendRemove: extendRemove,1992 _isEmptyObject: isEmptyObject,1993 _convert24to12: convert24to12,1994 _detectSupport: detectSupport,1995 _selectLocalTimezone: selectLocalTimezone,1996 _computeEffectiveSetting: computeEffectiveSetting,1997 _splitDateTime: splitDateTime,1998 _parseDateTimeInternal: parseDateTimeInternal1999 };2000 /*2001 * Microsecond support2002 */2003 if (!Date.prototype.getMicroseconds) {2004 Date.prototype.microseconds = 0;2005 Date.prototype.getMicroseconds = function () { return this.microseconds; };2006 Date.prototype.setMicroseconds = function (m) {2007 this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000));2008 this.microseconds = m % 1000;2009 return this;2010 };2011 }2012 /*2013 * Keep up with the version2014 */2015 $.timepicker.version = "1.4.6";...
jquery-ui-timepicker-addon.js
Source:jquery-ui-timepicker-addon.js
1/*2* jQuery timepicker addon3* By: Trent Richardson [http://trentrichardson.com]4* Version 0.9.75* Last Modified: 10/02/20116* 7* Copyright 2011 Trent Richardson8* Dual licensed under the MIT and GPL licenses.9* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt10* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt11* 12* HERES THE CSS:13* .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }14* .ui-timepicker-div dl { text-align: left; }15* .ui-timepicker-div dl dt { height: 25px; }16* .ui-timepicker-div dl dd { margin: -25px 10px 10px 65px; }17* .ui-timepicker-div td { font-size: 90%; }18* .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }19*/20(function($) {21$.extend($.ui, { timepicker: { version: "0.9.7" } });22/* Time picker manager.23 Use the singleton instance of this class, $.timepicker, to interact with the time picker.24 Settings for (groups of) time pickers are maintained in an instance object,25 allowing multiple different settings on the same page. */26function Timepicker() {27 this.regional = []; // Available regional settings, indexed by language code28 this.regional[''] = { // Default regional settings29 currentText: 'Now',30 closeText: 'Done',31 ampm: false,32 amNames: ['AM', 'A'],33 pmNames: ['PM', 'P'],34 timeFormat: 'hh:mm tt',35 timeSuffix: '',36 timeOnlyTitle: 'Choose Time',37 timeText: 'Time',38 hourText: 'Hour',39 minuteText: 'Minute',40 secondText: 'Second',41 millisecText: 'Millisecond',42 timezoneText: 'Time Zone'43 };44 this._defaults = { // Global defaults for all the datetime picker instances45 showButtonPanel: true,46 timeOnly: false,47 showHour: true,48 showMinute: true,49 showSecond: false,50 showMillisec: false,51 showTimezone: false,52 showTime: true,53 stepHour: 0.05,54 stepMinute: 0.05,55 stepSecond: 0.05,56 stepMillisec: 0.5,57 hour: 0,58 minute: 0,59 second: 0,60 millisec: 0,61 timezone: '+0000',62 hourMin: 0,63 minuteMin: 0,64 secondMin: 0,65 millisecMin: 0,66 hourMax: 23,67 minuteMax: 59,68 secondMax: 59,69 millisecMax: 999,70 minDateTime: null,71 maxDateTime: null,72 onSelect: null,73 hourGrid: 0,74 minuteGrid: 0,75 secondGrid: 0,76 millisecGrid: 0,77 alwaysSetTime: true,78 separator: ' ',79 altFieldTimeOnly: true,80 showTimepicker: true,81 timezoneIso8609: false,82 timezoneList: null83 };84 $.extend(this._defaults, this.regional['']);85}86$.extend(Timepicker.prototype, {87 $input: null,88 $altInput: null,89 $timeObj: null,90 inst: null,91 hour_slider: null,92 minute_slider: null,93 second_slider: null,94 millisec_slider: null,95 timezone_select: null,96 hour: 0,97 minute: 0,98 second: 0,99 millisec: 0,100 timezone: '+0000',101 hourMinOriginal: null,102 minuteMinOriginal: null,103 secondMinOriginal: null,104 millisecMinOriginal: null,105 hourMaxOriginal: null,106 minuteMaxOriginal: null,107 secondMaxOriginal: null,108 millisecMaxOriginal: null,109 ampm: '',110 formattedDate: '',111 formattedTime: '',112 formattedDateTime: '',113 timezoneList: null,114 /* Override the default settings for all instances of the time picker.115 @param settings object - the new settings to use as defaults (anonymous object)116 @return the manager object */117 setDefaults: function(settings) {118 extendRemove(this._defaults, settings || {});119 return this;120 },121 //########################################################################122 // Create a new Timepicker instance123 //########################################################################124 _newInst: function($input, o) {125 var tp_inst = new Timepicker(),126 inlineSettings = {};127 128 for (var attrName in this._defaults) {129 var attrValue = $input.attr('time:' + attrName);130 if (attrValue) {131 try {132 inlineSettings[attrName] = eval(attrValue);133 } catch (err) {134 inlineSettings[attrName] = attrValue;135 }136 }137 }138 tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, {139 beforeShow: function(input, dp_inst) {140 if ($.isFunction(o.beforeShow))141 o.beforeShow(input, dp_inst, tp_inst);142 },143 onChangeMonthYear: function(year, month, dp_inst) {144 // Update the time as well : this prevents the time from disappearing from the $input field.145 tp_inst._updateDateTime(dp_inst);146 if ($.isFunction(o.onChangeMonthYear))147 o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);148 },149 onClose: function(dateText, dp_inst) {150 if (tp_inst.timeDefined === true && $input.val() != '')151 tp_inst._updateDateTime(dp_inst);152 if ($.isFunction(o.onClose))153 o.onClose.call($input[0], dateText, dp_inst, tp_inst);154 },155 timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');156 });157 tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { return val.toUpperCase() });158 tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { return val.toUpperCase() });159 if (tp_inst._defaults.timezoneList === null) {160 var timezoneList = [];161 for (var i = -11; i <= 12; i++)162 timezoneList.push((i >= 0 ? '+' : '-') + ('0' + Math.abs(i).toString()).slice(-2) + '00');163 if (tp_inst._defaults.timezoneIso8609)164 timezoneList = $.map(timezoneList, function(val) {165 return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3));166 });167 tp_inst._defaults.timezoneList = timezoneList;168 }169 tp_inst.hour = tp_inst._defaults.hour;170 tp_inst.minute = tp_inst._defaults.minute;171 tp_inst.second = tp_inst._defaults.second;172 tp_inst.millisec = tp_inst._defaults.millisec;173 tp_inst.ampm = '';174 tp_inst.$input = $input;175 if (o.altField)176 tp_inst.$altInput = $(o.altField)177 .css({ cursor: 'pointer' })178 .focus(function(){ $input.trigger("focus"); });179 180 if(tp_inst._defaults.minDate==0 || tp_inst._defaults.minDateTime==0)181 {182 tp_inst._defaults.minDate=new Date();183 }184 if(tp_inst._defaults.maxDate==0 || tp_inst._defaults.maxDateTime==0)185 {186 tp_inst._defaults.maxDate=new Date();187 }188 189 // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..190 if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date)191 tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());192 if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date)193 tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());194 if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date)195 tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());196 if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date)197 tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());198 return tp_inst;199 },200 //########################################################################201 // add our sliders to the calendar202 //########################################################################203 _addTimePicker: function(dp_inst) {204 var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ?205 this.$input.val() + ' ' + this.$altInput.val() : 206 this.$input.val();207 this.timeDefined = this._parseTime(currDT);208 this._limitMinMaxDateTime(dp_inst, false);209 this._injectTimePicker();210 },211 //########################################################################212 // parse the time string from input value or _setTime213 //########################################################################214 _parseTime: function(timeString, withDate) {215 var regstr = this._defaults.timeFormat.toString()216 .replace(/h{1,2}/ig, '(\\d?\\d)')217 .replace(/m{1,2}/ig, '(\\d?\\d)')218 .replace(/s{1,2}/ig, '(\\d?\\d)')219 .replace(/l{1}/ig, '(\\d?\\d?\\d)')220 .replace(/t{1,2}/ig, this._getPatternAmpm())221 .replace(/z{1}/ig, '(z|[-+]\\d\\d:?\\d\\d)?')222 .replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$',223 order = this._getFormatPositions(),224 ampm = '',225 treg;226 if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);227 if (withDate || !this._defaults.timeOnly) {228 // the time should come after x number of characters and a space.229 // x = at least the length of text specified by the date format230 var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');231 // escape special regex characters in the seperator232 var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g");233 regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator.replace(specials, "\\$&") + regstr;234 }235 236 treg = timeString.match(new RegExp(regstr, 'i'));237 if (treg) {238 if (order.t !== -1) {239 if (treg[order.t] === undefined || treg[order.t].length === 0) {240 ampm = '';241 this.ampm = '';242 } else {243 ampm = $.inArray(treg[order.t].toUpperCase(), this.amNames) !== -1 ? 'AM' : 'PM';244 this.ampm = this._defaults[ampm == 'AM' ? 'amNames' : 'pmNames'][0];245 }246 }247 if (order.h !== -1) {248 if (ampm == 'AM' && treg[order.h] == '12')249 this.hour = 0; // 12am = 0 hour250 else if (ampm == 'PM' && treg[order.h] != '12')251 this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12252 else this.hour = Number(treg[order.h]);253 }254 if (order.m !== -1) this.minute = Number(treg[order.m]);255 if (order.s !== -1) this.second = Number(treg[order.s]);256 if (order.l !== -1) this.millisec = Number(treg[order.l]);257 if (order.z !== -1 && treg[order.z] !== undefined) {258 var tz = treg[order.z].toUpperCase();259 switch (tz.length) {260 case 1: // Z261 tz = this._defaults.timezoneIso8609 ? 'Z' : '+0000';262 break;263 case 5: // +hhmm264 if (this._defaults.timezoneIso8609)265 tz = tz.substring(1) == '0000'266 ? 'Z'267 : tz.substring(0, 3) + ':' + tz.substring(3);268 break;269 case 6: // +hh:mm270 if (!this._defaults.timezoneIso8609)271 tz = tz == 'Z' || tz.substring(1) == '00:00'272 ? '+0000'273 : tz.replace(/:/, '');274 else if (tz.substring(1) == '00:00')275 tz = 'Z';276 break;277 }278 this.timezone = tz;279 }280 281 return true;282 }283 return false;284 },285 //########################################################################286 // pattern for standard and localized AM/PM markers287 //########################################################################288 _getPatternAmpm: function() {289 var markers = [];290 o = this._defaults;291 if (o.amNames)292 $.merge(markers, o.amNames);293 if (o.pmNames)294 $.merge(markers, o.pmNames);295 markers = $.map(markers, function(val) { return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&') });296 return '(' + markers.join('|') + ')?';297 },298 //########################################################################299 // figure out position of time elements.. cause js cant do named captures300 //########################################################################301 _getFormatPositions: function() {302 var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|t{1,2}|z)/g),303 orders = { h: -1, m: -1, s: -1, l: -1, t: -1, z: -1 };304 if (finds)305 for (var i = 0; i < finds.length; i++)306 if (orders[finds[i].toString().charAt(0)] == -1)307 orders[finds[i].toString().charAt(0)] = i + 1;308 return orders;309 },310 //########################################################################311 // generate and inject html for timepicker into ui datepicker312 //########################################################################313 _injectTimePicker: function() {314 var $dp = this.inst.dpDiv,315 o = this._defaults,316 tp_inst = this,317 // Added by Peter Medeiros:318 // - Figure out what the hour/minute/second max should be based on the step values.319 // - Example: if stepMinute is 15, then minMax is 45.320 hourMax = (o.hourMax - ((o.hourMax - o.hourMin) % o.stepHour)).toFixed(0),321 minMax = (o.minuteMax - ((o.minuteMax - o.minuteMin) % o.stepMinute)).toFixed(0),322 secMax = (o.secondMax - ((o.secondMax - o.secondMin) % o.stepSecond)).toFixed(0),323 millisecMax = (o.millisecMax - ((o.millisecMax - o.millisecMin) % o.stepMillisec)).toFixed(0),324 dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, '');325 // Prevent displaying twice326 //if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) {327 if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0 && o.showTimepicker) {328 var noDisplay = ' style="display:none;"',329 html = '<div class="ui-timepicker-div" id="ui-timepicker-div-' + dp_id + '"><dl>' +330 '<dt class="ui_tpicker_time_label" id="ui_tpicker_time_label_' + dp_id + '"' +331 ((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' +332 '<dd class="ui_tpicker_time" id="ui_tpicker_time_' + dp_id + '"' +333 ((o.showTime) ? '' : noDisplay) + '></dd>' +334 '<dt class="ui_tpicker_hour_label" id="ui_tpicker_hour_label_' + dp_id + '"' +335 ((o.showHour) ? '' : noDisplay) + '>' + o.hourText + '</dt>',336 hourGridSize = 0,337 minuteGridSize = 0,338 secondGridSize = 0,339 millisecGridSize = 0,340 size;341 // Hours342 if (o.showHour && o.hourGrid > 0) {343 html += '<dd class="ui_tpicker_hour">' +344 '<div id="ui_tpicker_hour_' + dp_id + '"' + ((o.showHour) ? '' : noDisplay) + '></div>' +345 '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';346 for (var h = o.hourMin; h <= hourMax; h += parseInt(o.hourGrid,10)) {347 hourGridSize++;348 var tmph = (o.ampm && h > 12) ? h-12 : h;349 if (tmph < 10) tmph = '0' + tmph;350 if (o.ampm) {351 if (h == 0) tmph = 12 +'a';352 else if (h < 12) tmph += 'a';353 else tmph += 'p';354 }355 html += '<td>' + tmph + '</td>';356 }357 html += '</tr></table></div>' +358 '</dd>';359 } else html += '<dd class="ui_tpicker_hour" id="ui_tpicker_hour_' + dp_id + '"' +360 ((o.showHour) ? '' : noDisplay) + '></dd>';361 html += '<dt class="ui_tpicker_minute_label" id="ui_tpicker_minute_label_' + dp_id + '"' +362 ((o.showMinute) ? '' : noDisplay) + '>' + o.minuteText + '</dt>';363 // Minutes364 if (o.showMinute && o.minuteGrid > 0) {365 html += '<dd class="ui_tpicker_minute ui_tpicker_minute_' + o.minuteGrid + '">' +366 '<div id="ui_tpicker_minute_' + dp_id + '"' +367 ((o.showMinute) ? '' : noDisplay) + '></div>' +368 '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';369 for (var m = o.minuteMin; m <= minMax; m += parseInt(o.minuteGrid,10)) {370 minuteGridSize++;371 html += '<td>' + ((m < 10) ? '0' : '') + m + '</td>';372 }373 html += '</tr></table></div>' +374 '</dd>';375 } else html += '<dd class="ui_tpicker_minute" id="ui_tpicker_minute_' + dp_id + '"' +376 ((o.showMinute) ? '' : noDisplay) + '></dd>';377 // Seconds378 html += '<dt class="ui_tpicker_second_label" id="ui_tpicker_second_label_' + dp_id + '"' +379 ((o.showSecond) ? '' : noDisplay) + '>' + o.secondText + '</dt>';380 if (o.showSecond && o.secondGrid > 0) {381 html += '<dd class="ui_tpicker_second ui_tpicker_second_' + o.secondGrid + '">' +382 '<div id="ui_tpicker_second_' + dp_id + '"' +383 ((o.showSecond) ? '' : noDisplay) + '></div>' +384 '<div style="padding-left: 1px"><table><tr>';385 for (var s = o.secondMin; s <= secMax; s += parseInt(o.secondGrid,10)) {386 secondGridSize++;387 html += '<td>' + ((s < 10) ? '0' : '') + s + '</td>';388 }389 html += '</tr></table></div>' +390 '</dd>';391 } else html += '<dd class="ui_tpicker_second" id="ui_tpicker_second_' + dp_id + '"' +392 ((o.showSecond) ? '' : noDisplay) + '></dd>';393 // Milliseconds394 html += '<dt class="ui_tpicker_millisec_label" id="ui_tpicker_millisec_label_' + dp_id + '"' +395 ((o.showMillisec) ? '' : noDisplay) + '>' + o.millisecText + '</dt>';396 if (o.showMillisec && o.millisecGrid > 0) {397 html += '<dd class="ui_tpicker_millisec ui_tpicker_millisec_' + o.millisecGrid + '">' +398 '<div id="ui_tpicker_millisec_' + dp_id + '"' +399 ((o.showMillisec) ? '' : noDisplay) + '></div>' +400 '<div style="padding-left: 1px"><table><tr>';401 for (var l = o.millisecMin; l <= millisecMax; l += parseInt(o.millisecGrid,10)) {402 millisecGridSize++;403 html += '<td>' + ((l < 10) ? '0' : '') + s + '</td>';404 }405 html += '</tr></table></div>' +406 '</dd>';407 } else html += '<dd class="ui_tpicker_millisec" id="ui_tpicker_millisec_' + dp_id + '"' +408 ((o.showMillisec) ? '' : noDisplay) + '></dd>';409 // Timezone410 html += '<dt class="ui_tpicker_timezone_label" id="ui_tpicker_timezone_label_' + dp_id + '"' +411 ((o.showTimezone) ? '' : noDisplay) + '>' + o.timezoneText + '</dt>';412 html += '<dd class="ui_tpicker_timezone" id="ui_tpicker_timezone_' + dp_id + '"' +413 ((o.showTimezone) ? '' : noDisplay) + '></dd>';414 html += '</dl></div>';415 $tp = $(html);416 // if we only want time picker...417 if (o.timeOnly === true) {418 $tp.prepend(419 '<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' +420 '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' +421 '</div>');422 $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();423 }424 this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({425 orientation: "horizontal",426 value: this.hour,427 min: o.hourMin,428 max: hourMax,429 step: o.stepHour,430 slide: function(event, ui) {431 tp_inst.hour_slider.slider( "option", "value", ui.value);432 tp_inst._onTimeChange();433 }434 });435 // Updated by Peter Medeiros:436 // - Pass in Event and UI instance into slide function437 this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({438 orientation: "horizontal",439 value: this.minute,440 min: o.minuteMin,441 max: minMax,442 step: o.stepMinute,443 slide: function(event, ui) {444 // update the global minute slider instance value with the current slider value445 tp_inst.minute_slider.slider( "option", "value", ui.value);446 tp_inst._onTimeChange();447 }448 });449 this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({450 orientation: "horizontal",451 value: this.second,452 min: o.secondMin,453 max: secMax,454 step: o.stepSecond,455 slide: function(event, ui) {456 tp_inst.second_slider.slider( "option", "value", ui.value);457 tp_inst._onTimeChange();458 }459 });460 this.millisec_slider = $tp.find('#ui_tpicker_millisec_'+ dp_id).slider({461 orientation: "horizontal",462 value: this.millisec,463 min: o.millisecMin,464 max: millisecMax,465 step: o.stepMillisec,466 slide: function(event, ui) {467 tp_inst.millisec_slider.slider( "option", "value", ui.value);468 tp_inst._onTimeChange();469 }470 });471 this.timezone_select = $tp.find('#ui_tpicker_timezone_'+ dp_id).append('<select></select>').find("select");472 $.fn.append.apply(this.timezone_select,473 $.map(o.timezoneList, function(val, idx) {474 return $("<option />")475 .val(typeof val == "object" ? val.value : val)476 .text(typeof val == "object" ? val.label : val);477 })478 );479 this.timezone_select.val((typeof this.timezone != "undefined" && this.timezone != null && this.timezone != "") ? this.timezone : o.timezone);480 this.timezone_select.change(function() {481 tp_inst._onTimeChange();482 });483 // Add grid functionality484 if (o.showHour && o.hourGrid > 0) {485 size = 100 * hourGridSize * o.hourGrid / (hourMax - o.hourMin);486 $tp.find(".ui_tpicker_hour table").css({487 width: size + "%",488 marginLeft: (size / (-2 * hourGridSize)) + "%",489 borderCollapse: 'collapse'490 }).find("td").each( function(index) {491 $(this).click(function() {492 var h = $(this).html();493 if(o.ampm) {494 var ap = h.substring(2).toLowerCase(),495 aph = parseInt(h.substring(0,2), 10);496 if (ap == 'a') {497 if (aph == 12) h = 0;498 else h = aph;499 } else if (aph == 12) h = 12;500 else h = aph + 12;501 }502 tp_inst.hour_slider.slider("option", "value", h);503 tp_inst._onTimeChange();504 tp_inst._onSelectHandler();505 }).css({506 cursor: 'pointer',507 width: (100 / hourGridSize) + '%',508 textAlign: 'center',509 overflow: 'hidden'510 });511 });512 }513 if (o.showMinute && o.minuteGrid > 0) {514 size = 100 * minuteGridSize * o.minuteGrid / (minMax - o.minuteMin);515 $tp.find(".ui_tpicker_minute table").css({516 width: size + "%",517 marginLeft: (size / (-2 * minuteGridSize)) + "%",518 borderCollapse: 'collapse'519 }).find("td").each(function(index) {520 $(this).click(function() {521 tp_inst.minute_slider.slider("option", "value", $(this).html());522 tp_inst._onTimeChange();523 tp_inst._onSelectHandler();524 }).css({525 cursor: 'pointer',526 width: (100 / minuteGridSize) + '%',527 textAlign: 'center',528 overflow: 'hidden'529 });530 });531 }532 if (o.showSecond && o.secondGrid > 0) {533 $tp.find(".ui_tpicker_second table").css({534 width: size + "%",535 marginLeft: (size / (-2 * secondGridSize)) + "%",536 borderCollapse: 'collapse'537 }).find("td").each(function(index) {538 $(this).click(function() {539 tp_inst.second_slider.slider("option", "value", $(this).html());540 tp_inst._onTimeChange();541 tp_inst._onSelectHandler();542 }).css({543 cursor: 'pointer',544 width: (100 / secondGridSize) + '%',545 textAlign: 'center',546 overflow: 'hidden'547 });548 });549 }550 if (o.showMillisec && o.millisecGrid > 0) {551 $tp.find(".ui_tpicker_millisec table").css({552 width: size + "%",553 marginLeft: (size / (-2 * millisecGridSize)) + "%",554 borderCollapse: 'collapse'555 }).find("td").each(function(index) {556 $(this).click(function() {557 tp_inst.millisec_slider.slider("option", "value", $(this).html());558 tp_inst._onTimeChange();559 tp_inst._onSelectHandler();560 }).css({561 cursor: 'pointer',562 width: (100 / millisecGridSize) + '%',563 textAlign: 'center',564 overflow: 'hidden'565 });566 });567 }568 var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');569 if ($buttonPanel.length) $buttonPanel.before($tp);570 else $dp.append($tp);571 this.$timeObj = $tp.find('#ui_tpicker_time_'+ dp_id);572 if (this.inst !== null) {573 var timeDefined = this.timeDefined;574 this._onTimeChange();575 this.timeDefined = timeDefined;576 }577 //Emulate datepicker onSelect behavior. Call on slidestop.578 var onSelectDelegate = function() {579 tp_inst._onSelectHandler();580 };581 this.hour_slider.bind('slidestop',onSelectDelegate);582 this.minute_slider.bind('slidestop',onSelectDelegate);583 this.second_slider.bind('slidestop',onSelectDelegate);584 this.millisec_slider.bind('slidestop',onSelectDelegate);585 }586 },587 //########################################################################588 // This function tries to limit the ability to go outside the589 // min/max date range590 //########################################################################591 _limitMinMaxDateTime: function(dp_inst, adjustSliders){592 var o = this._defaults,593 dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);594 if(!this._defaults.showTimepicker) return; // No time so nothing to check here595 if($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date){596 var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),597 minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);598 if(this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null){599 this.hourMinOriginal = o.hourMin;600 this.minuteMinOriginal = o.minuteMin;601 this.secondMinOriginal = o.secondMin;602 this.millisecMinOriginal = o.millisecMin;603 }604 if(dp_inst.settings.timeOnly || minDateTimeDate.getTime() == dp_date.getTime()) {605 this._defaults.hourMin = minDateTime.getHours();606 if (this.hour <= this._defaults.hourMin) {607 this.hour = this._defaults.hourMin;608 this._defaults.minuteMin = minDateTime.getMinutes();609 if (this.minute <= this._defaults.minuteMin) {610 this.minute = this._defaults.minuteMin;611 this._defaults.secondMin = minDateTime.getSeconds();612 } else if (this.second <= this._defaults.secondMin){613 this.second = this._defaults.secondMin;614 this._defaults.millisecMin = minDateTime.getMilliseconds();615 } else {616 if(this.millisec < this._defaults.millisecMin)617 this.millisec = this._defaults.millisecMin;618 this._defaults.millisecMin = this.millisecMinOriginal;619 }620 } else {621 this._defaults.minuteMin = this.minuteMinOriginal;622 this._defaults.secondMin = this.secondMinOriginal;623 this._defaults.millisecMin = this.millisecMinOriginal;624 }625 }else{626 this._defaults.hourMin = this.hourMinOriginal;627 this._defaults.minuteMin = this.minuteMinOriginal;628 this._defaults.secondMin = this.secondMinOriginal;629 this._defaults.millisecMin = this.millisecMinOriginal;630 }631 }632 if($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date){633 var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),634 maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);635 if(this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null){636 this.hourMaxOriginal = o.hourMax;637 this.minuteMaxOriginal = o.minuteMax;638 this.secondMaxOriginal = o.secondMax;639 this.millisecMaxOriginal = o.millisecMax;640 }641 if(dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()){642 this._defaults.hourMax = maxDateTime.getHours();643 if (this.hour >= this._defaults.hourMax) {644 this.hour = this._defaults.hourMax;645 this._defaults.minuteMax = maxDateTime.getMinutes();646 if (this.minute >= this._defaults.minuteMax) {647 this.minute = this._defaults.minuteMax;648 this._defaults.secondMax = maxDateTime.getSeconds();649 } else if (this.second >= this._defaults.secondMax) {650 this.second = this._defaults.secondMax;651 this._defaults.millisecMax = maxDateTime.getMilliseconds();652 } else {653 if(this.millisec > this._defaults.millisecMax) this.millisec = this._defaults.millisecMax;654 this._defaults.millisecMax = this.millisecMaxOriginal;655 }656 } else {657 this._defaults.minuteMax = this.minuteMaxOriginal;658 this._defaults.secondMax = this.secondMaxOriginal;659 this._defaults.millisecMax = this.millisecMaxOriginal;660 }661 }else{662 this._defaults.hourMax = this.hourMaxOriginal;663 this._defaults.minuteMax = this.minuteMaxOriginal;664 this._defaults.secondMax = this.secondMaxOriginal;665 this._defaults.millisecMax = this.millisecMaxOriginal;666 }667 }668 if(adjustSliders !== undefined && adjustSliders === true){669 var hourMax = (this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)).toFixed(0),670 minMax = (this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)).toFixed(0),671 secMax = (this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)).toFixed(0),672 millisecMax = (this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)).toFixed(0);673 if(this.hour_slider)674 this.hour_slider.slider("option", { min: this._defaults.hourMin, max: hourMax }).slider('value', this.hour);675 if(this.minute_slider)676 this.minute_slider.slider("option", { min: this._defaults.minuteMin, max: minMax }).slider('value', this.minute);677 if(this.second_slider)678 this.second_slider.slider("option", { min: this._defaults.secondMin, max: secMax }).slider('value', this.second);679 if(this.millisec_slider)680 this.millisec_slider.slider("option", { min: this._defaults.millisecMin, max: millisecMax }).slider('value', this.millisec);681 }682 },683 684 //########################################################################685 // when a slider moves, set the internal time...686 // on time change is also called when the time is updated in the text field687 //########################################################################688 _onTimeChange: function() {689 var hour = (this.hour_slider) ? this.hour_slider.slider('value') : false,690 minute = (this.minute_slider) ? this.minute_slider.slider('value') : false,691 second = (this.second_slider) ? this.second_slider.slider('value') : false,692 millisec = (this.millisec_slider) ? this.millisec_slider.slider('value') : false,693 timezone = (this.timezone_select) ? this.timezone_select.val() : false,694 o = this._defaults;695 if (typeof(hour) == 'object') hour = false;696 if (typeof(minute) == 'object') minute = false;697 if (typeof(second) == 'object') second = false;698 if (typeof(millisec) == 'object') millisec = false;699 if (typeof(timezone) == 'object') timezone = false;700 if (hour !== false) hour = parseInt(hour,10);701 if (minute !== false) minute = parseInt(minute,10);702 if (second !== false) second = parseInt(second,10);703 if (millisec !== false) millisec = parseInt(millisec,10);704 var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];705 // If the update was done in the input field, the input field should not be updated.706 // If the update was done using the sliders, update the input field.707 var hasChanged = (hour != this.hour || minute != this.minute708 || second != this.second || millisec != this.millisec709 || (this.ampm.length > 0710 && (hour < 12) != ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1))711 || timezone != this.timezone);712 713 if (hasChanged) {714 if (hour !== false)this.hour = hour;715 if (minute !== false) this.minute = minute;716 if (second !== false) this.second = second;717 if (millisec !== false) this.millisec = millisec;718 if (timezone !== false) this.timezone = timezone;719 720 if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);721 722 this._limitMinMaxDateTime(this.inst, true);723 }724 if (o.ampm) this.ampm = ampm;725 726 this._formatTime();727 if (this.$timeObj) this.$timeObj.text(this.formattedTime + o.timeSuffix);728 this.timeDefined = true;729 if (hasChanged) this._updateDateTime();730 },731 732 //########################################################################733 // call custom onSelect. 734 // bind to sliders slidestop, and grid click.735 //########################################################################736 _onSelectHandler: function() {737 var onSelect = this._defaults.onSelect;738 var inputEl = this.$input ? this.$input[0] : null;739 if (onSelect && inputEl) {740 onSelect.apply(inputEl, [this.formattedDateTime, this]);741 }742 },743 //########################################################################744 // format the time all pretty...745 //########################################################################746 _formatTime: function(time, format, ampm) {747 if (ampm == undefined) ampm = this._defaults.ampm;748 time = time || { hour: this.hour, minute: this.minute, second: this.second, millisec: this.millisec, ampm: this.ampm, timezone: this.timezone };749 var tmptime = (format || this._defaults.timeFormat).toString();750 var hour = parseInt(time.hour, 10);751 if (ampm) {752 if (!$.inArray(time.ampm.toUpperCase(), this.amNames) !== -1)753 hour = hour % 12;754 if (hour === 0)755 hour = 12;756 }757 tmptime = tmptime.replace(/(?:hh?|mm?|ss?|[tT]{1,2}|[lz])/g, function(match) {758 switch (match.toLowerCase()) {759 case 'hh': return ('0' + hour).slice(-2);760 case 'h': return hour;761 case 'mm': return ('0' + time.minute).slice(-2);762 case 'm': return time.minute;763 case 'ss': return ('0' + time.second).slice(-2);764 case 's': return time.second;765 case 'l': return ('00' + time.millisec).slice(-3);766 case 'z': return time.timezone;767 case 't': case 'tt':768 if (ampm) {769 var _ampm = time.ampm;770 if (match.length == 1)771 _ampm = _ampm.charAt(0);772 return match.charAt(0) == 'T' ? _ampm.toUpperCase() : _ampm.toLowerCase();773 }774 return '';775 }776 });777 if (arguments.length) return tmptime;778 else this.formattedTime = tmptime;779 },780 //########################################################################781 // update our input with the new date time..782 //########################################################################783 _updateDateTime: function(dp_inst) {784 dp_inst = this.inst || dp_inst,785 dt = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay),786 dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),787 formatCfg = $.datepicker._getFormatConfig(dp_inst),788 timeAvailable = dt !== null && this.timeDefined;789 this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);790 var formattedDateTime = this.formattedDate;791 if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0))792 return;793 if (this._defaults.timeOnly === true) {794 formattedDateTime = this.formattedTime;795 } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) {796 formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;797 }798 this.formattedDateTime = formattedDateTime;799 if(!this._defaults.showTimepicker) {800 this.$input.val(this.formattedDate);801 } else if (this.$altInput && this._defaults.altFieldTimeOnly === true) {802 this.$altInput.val(this.formattedTime);803 this.$input.val(this.formattedDate);804 } else if(this.$altInput) {805 this.$altInput.val(formattedDateTime);806 this.$input.val(formattedDateTime);807 } else {808 this.$input.val(formattedDateTime);809 }810 811 this.$input.trigger("change");812 }813});814$.fn.extend({815 //########################################################################816 // shorthand just to use timepicker..817 //########################################################################818 timepicker: function(o) {819 o = o || {};820 var tmp_args = arguments;821 if (typeof o == 'object') tmp_args[0] = $.extend(o, { timeOnly: true });822 return $(this).each(function() {823 $.fn.datetimepicker.apply($(this), tmp_args);824 });825 },826 //########################################################################827 // extend timepicker to datepicker828 //########################################################################829 datetimepicker: function(o) {830 o = o || {};831 var $input = this,832 tmp_args = arguments;833 if (typeof(o) == 'string'){834 if(o == 'getDate') 835 return $.fn.datepicker.apply($(this[0]), tmp_args);836 else 837 return this.each(function() {838 var $t = $(this);839 $t.datepicker.apply($t, tmp_args);840 });841 }842 else843 return this.each(function() {844 var $t = $(this);845 $t.datepicker($.timepicker._newInst($t, o)._defaults);846 });847 }848});849//########################################################################850// the bad hack :/ override datepicker so it doesnt close on select851// inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378852//########################################################################853$.datepicker._base_selectDate = $.datepicker._selectDate;854$.datepicker._selectDate = function (id, dateStr) {855 var inst = this._getInst($(id)[0]),856 tp_inst = this._get(inst, 'timepicker');857 if (tp_inst) {858 tp_inst._limitMinMaxDateTime(inst, true);859 inst.inline = inst.stay_open = true;860 //This way the onSelect handler called from calendarpicker get the full dateTime861 this._base_selectDate(id, dateStr);862 inst.inline = inst.stay_open = false;863 this._notifyChange(inst);864 this._updateDatepicker(inst);865 }866 else this._base_selectDate(id, dateStr);867};868//#############################################################################################869// second bad hack :/ override datepicker so it triggers an event when changing the input field870// and does not redraw the datepicker on every selectDate event871//#############################################################################################872$.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;873$.datepicker._updateDatepicker = function(inst) {874 // don't popup the datepicker if there is another instance already opened875 var input = inst.input[0];876 if($.datepicker._curInst &&877 $.datepicker._curInst != inst &&878 $.datepicker._datepickerShowing &&879 $.datepicker._lastInput != input) {880 return;881 }882 if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {883 884 this._base_updateDatepicker(inst);885 886 // Reload the time control when changing something in the input text field.887 var tp_inst = this._get(inst, 'timepicker');888 if(tp_inst) tp_inst._addTimePicker(inst);889 }890};891//#######################################################################################892// third bad hack :/ override datepicker so it allows spaces and colon in the input field893//#######################################################################################894$.datepicker._base_doKeyPress = $.datepicker._doKeyPress;895$.datepicker._doKeyPress = function(event) {896 var inst = $.datepicker._getInst(event.target),897 tp_inst = $.datepicker._get(inst, 'timepicker');898 if (tp_inst) {899 if ($.datepicker._get(inst, 'constrainInput')) {900 var ampm = tp_inst._defaults.ampm,901 dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),902 datetimeChars = tp_inst._defaults.timeFormat.toString()903 .replace(/[hms]/g, '')904 .replace(/TT/g, ampm ? 'APM' : '')905 .replace(/Tt/g, ampm ? 'AaPpMm' : '')906 .replace(/tT/g, ampm ? 'AaPpMm' : '')907 .replace(/T/g, ampm ? 'AP' : '')908 .replace(/tt/g, ampm ? 'apm' : '')909 .replace(/t/g, ampm ? 'ap' : '') +910 " " +911 tp_inst._defaults.separator +912 tp_inst._defaults.timeSuffix +913 (tp_inst._defaults.showTimezone ? tp_inst._defaults.timezoneList.join('') : '') +914 (tp_inst._defaults.amNames.join('')) +915 (tp_inst._defaults.pmNames.join('')) +916 dateChars,917 chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);918 return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);919 }920 }921 922 return $.datepicker._base_doKeyPress(event);923};924//#######################################################################################925// Override key up event to sync manual input changes.926//#######################################################################################927$.datepicker._base_doKeyUp = $.datepicker._doKeyUp;928$.datepicker._doKeyUp = function (event) {929 var inst = $.datepicker._getInst(event.target),930 tp_inst = $.datepicker._get(inst, 'timepicker');931 if (tp_inst) {932 if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) {933 try {934 $.datepicker._updateDatepicker(inst);935 }936 catch (err) {937 $.datepicker.log(err);938 }939 }940 }941 return $.datepicker._base_doKeyUp(event);942};943//#######################################################################################944// override "Today" button to also grab the time.945//#######################################################################################946$.datepicker._base_gotoToday = $.datepicker._gotoToday;947$.datepicker._gotoToday = function(id) {948 var inst = this._getInst($(id)[0]),949 $dp = inst.dpDiv;950 this._base_gotoToday(id);951 var now = new Date();952 var tp_inst = this._get(inst, 'timepicker');953 if (tp_inst._defaults.showTimezone && tp_inst.timezone_select) {954 var tzoffset = now.getTimezoneOffset(); // If +0100, returns -60955 var tzsign = tzoffset > 0 ? '-' : '+';956 tzoffset = Math.abs(tzoffset);957 var tzmin = tzoffset % 60958 tzoffset = tzsign + ('0' + (tzoffset - tzmin) / 60).slice(-2) + ('0' + tzmin).slice(-2);959 if (tp_inst._defaults.timezoneIso8609)960 tzoffset = tzoffset.substring(0, 3) + ':' + tzoffset.substring(3);961 tp_inst.timezone_select.val(tzoffset);962 }963 this._setTime(inst, now);964 $( '.ui-datepicker-today', $dp).click(); 965};966//#######################################################################################967// Disable & enable the Time in the datetimepicker968//#######################################################################################969$.datepicker._disableTimepickerDatepicker = function(target, date, withDate) {970 var inst = this._getInst(target),971 tp_inst = this._get(inst, 'timepicker');972 $(target).datepicker('getDate'); // Init selected[Year|Month|Day]973 if (tp_inst) {974 tp_inst._defaults.showTimepicker = false;975 tp_inst._updateDateTime(inst);976 }977};978$.datepicker._enableTimepickerDatepicker = function(target, date, withDate) {979 var inst = this._getInst(target),980 tp_inst = this._get(inst, 'timepicker');981 $(target).datepicker('getDate'); // Init selected[Year|Month|Day]982 if (tp_inst) {983 tp_inst._defaults.showTimepicker = true;984 tp_inst._addTimePicker(inst); // Could be disabled on page load985 tp_inst._updateDateTime(inst);986 }987};988//#######################################################################################989// Create our own set time function990//#######################################################################################991$.datepicker._setTime = function(inst, date) {992 var tp_inst = this._get(inst, 'timepicker');993 if (tp_inst) {994 var defaults = tp_inst._defaults,995 // calling _setTime with no date sets time to defaults996 hour = date ? date.getHours() : defaults.hour,997 minute = date ? date.getMinutes() : defaults.minute,998 second = date ? date.getSeconds() : defaults.second,999 millisec = date ? date.getMilliseconds() : defaults.millisec;1000 //check if within min/max times..1001 if ((hour < defaults.hourMin || hour > defaults.hourMax) || (minute < defaults.minuteMin || minute > defaults.minuteMax) || (second < defaults.secondMin || second > defaults.secondMax) || (millisec < defaults.millisecMin || millisec > defaults.millisecMax)) {1002 hour = defaults.hourMin;1003 minute = defaults.minuteMin;1004 second = defaults.secondMin;1005 millisec = defaults.millisecMin;1006 }1007 tp_inst.hour = hour;1008 tp_inst.minute = minute;1009 tp_inst.second = second;1010 tp_inst.millisec = millisec;1011 if (tp_inst.hour_slider) tp_inst.hour_slider.slider('value', hour);1012 if (tp_inst.minute_slider) tp_inst.minute_slider.slider('value', minute);1013 if (tp_inst.second_slider) tp_inst.second_slider.slider('value', second);1014 if (tp_inst.millisec_slider) tp_inst.millisec_slider.slider('value', millisec);1015 tp_inst._onTimeChange();1016 tp_inst._updateDateTime(inst);1017 }1018};1019//#######################################################################################1020// Create new public method to set only time, callable as $().datepicker('setTime', date)1021//#######################################################################################1022$.datepicker._setTimeDatepicker = function(target, date, withDate) {1023 var inst = this._getInst(target),1024 tp_inst = this._get(inst, 'timepicker');1025 if (tp_inst) {1026 this._setDateFromField(inst);1027 var tp_date;1028 if (date) {1029 if (typeof date == "string") {1030 tp_inst._parseTime(date, withDate);1031 tp_date = new Date();1032 tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);1033 }1034 else tp_date = new Date(date.getTime());1035 if (tp_date.toString() == 'Invalid Date') tp_date = undefined;1036 this._setTime(inst, tp_date);1037 }1038 }1039};1040//#######################################################################################1041// override setDate() to allow setting time too within Date object1042//#######################################################################################1043$.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;1044$.datepicker._setDateDatepicker = function(target, date) {1045 var inst = this._getInst(target),1046 tp_date = (date instanceof Date) ? new Date(date.getTime()) : date;1047 this._updateDatepicker(inst);1048 this._base_setDateDatepicker.apply(this, arguments);1049 this._setTimeDatepicker(target, tp_date, true);1050};1051//#######################################################################################1052// override getDate() to allow getting time too within Date object1053//#######################################################################################1054$.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;1055$.datepicker._getDateDatepicker = function(target, noDefault) {1056 var inst = this._getInst(target),1057 tp_inst = this._get(inst, 'timepicker');1058 if (tp_inst) {1059 this._setDateFromField(inst, noDefault);1060 var date = this._getDate(inst);1061 if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);1062 return date;1063 }1064 return this._base_getDateDatepicker(target, noDefault);1065};1066//#######################################################################################1067// override parseDate() because UI 1.8.14 throws an error about "Extra characters"1068// An option in datapicker to ignore extra format characters would be nicer.1069//#######################################################################################1070$.datepicker._base_parseDate = $.datepicker.parseDate;1071$.datepicker.parseDate = function(format, value, settings) {1072 var date;1073 try {1074 date = this._base_parseDate(format, value, settings);1075 } catch (err) {1076 // Hack! The error message ends with a colon, a space, and1077 // the "extra" characters. We rely on that instead of1078 // attempting to perfectly reproduce the parsing algorithm.1079 date = this._base_parseDate(format, value.substring(0,value.length-(err.length-err.indexOf(':')-2)), settings);1080 }1081 return date;1082};1083//#######################################################################################1084// override formatDate to set date with time to the input1085//#######################################################################################1086$.datepicker._base_formatDate=$.datepicker._formatDate;1087$.datepicker._formatDate = function(inst, day, month, year){1088 var tp_inst = this._get(inst, 'timepicker');1089 if(tp_inst)1090 {1091 if(day)1092 var b = this._base_formatDate(inst, day, month, year);1093 tp_inst._updateDateTime(); 1094 return tp_inst.$input.val();1095 }1096 return this._base_formatDate(inst);1097}1098//#######################################################################################1099// override options setter to add time to maxDate(Time) and minDate(Time). MaxDate1100//#######################################################################################1101$.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;1102$.datepicker._optionDatepicker = function(target, name, value) {1103 var inst = this._getInst(target),1104 tp_inst = this._get(inst, 'timepicker');1105 if (tp_inst) {1106 var min,max,onselect;1107 if (typeof name == 'string') { // if min/max was set with the string1108 if (name==='minDate' || name==='minDateTime' )1109 min = value;1110 else if (name==='maxDate' || name==='maxDateTime')1111 max = value;1112 else if (name==='onSelect')1113 onselect=value;1114 } else if (typeof name == 'object') { //if min/max was set with the JSON1115 if(name.minDate)1116 min = name.minDate;1117 else if (name.minDateTime)1118 min = name.minDateTime;1119 else if (name.maxDate)1120 max = name.maxDate;1121 else if (name.maxDateTime)1122 max = name.maxDateTime;1123 }1124 if(min){ //if min was set1125 if(min==0)1126 min=new Date();1127 else1128 min= new Date(min);1129 1130 tp_inst._defaults.minDate = min;1131 tp_inst._defaults.minDateTime = min;1132 } else if (max){ //if max was set1133 if(max==0)1134 max=new Date();1135 else1136 max= new Date(max);1137 tp_inst._defaults.maxDate = max;1138 tp_inst._defaults.maxDateTime = max;1139 }1140 else if (onselect)1141 tp_inst._defaults.onSelect=onselect;1142 }1143 this._base_optionDatepicker(target, name, value);1144};1145//#######################################################################################1146// jQuery extend now ignores nulls!1147//#######################################################################################1148function extendRemove(target, props) {1149 $.extend(target, props);1150 for (var name in props)1151 if (props[name] === null || props[name] === undefined)1152 target[name] = props[name];1153 return target;1154}1155$.timepicker = new Timepicker(); // singleton instance1156$.timepicker.version = "0.9.7";...
jquery.mcworkform.js
Source:jquery.mcworkform.js
12(function( factory ) {3 if ( typeof define === "function" && define.amd ) {4 define( ["jquery"], factory );5 } else {6 factory( jQuery );7 }8}(function( $ ) {9 10 $.extend($.fn, {11 12 defaults : {13 async : true,14 formIdent : false,15 formAction : false,16 formMethod : 'POST',17 warnColor : 'alizarin-color',18 successColor : 'emerald-color',19 iconSuccess : 'fa fa-check-circle',20 iconWarn : 'fa fa-exclamation-triangle',21 iconSpinner : 'fa fa-spinner fa-spin',22 icon2x : 'fa-2x',23 formProcessSelector : '.server-process',24 formResultSelector : '#form-container',25 panel : 'panel',26 panelWarn : 'panel alert',27 panelSucess : 'panel success',28 panelTag : 'div',29 panelBootstrap : false,30 31 },32 33 setDefaults: function( options ) {34 $.extend( this.defaults, options );35 }, 36 37 getDefaults: function(prop){38 return this.defaults[prop];39 },40 41 FormValidation : function (form){42 var formFieldError = false; 43 $.each($(':input:visible:not(:button, :submit, :radio, :checkbox)', form), function(i) {44 $().UnmarkErrorFields($(this).attr('name'));45 if(this.getAttribute('required') != null) {46 if(($(this).val() == $(this).attr('placeholder')) || ($(this).val() == '')) {47 formFieldError = true;48 $().MarkErrorField($(this).attr('name'), 'Das Feld muss einen Wert enthalten');49 } 50 }51 if(this.getAttribute('pattern') != null) {52 if(($(this).val() == $(this).attr('placeholder')) || ($(this).val() == '')) {53 return true;54 } 55 if($(this).val().search($(this).attr('pattern'))) {56 formFieldError = true;57 $().MarkErrorField($(this).attr('name'), 'Der Wert ist im falschen Format: ' + $(this).attr('title'));58 } 59 }60 if(this.getAttribute('type') == 'email') {61 if(($(this).val() == $(this).attr('placeholder')) || ($(this).val() == '')) {62 return true;63 } 64 if($(this).val().search( /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ )) {65 formFieldError = true;66 $().MarkErrorField($(this).attr('name'), 'Die E-Mail Adresse ist im falschen Format');67 } 68 }69 });70 71 if (false === formFieldError){72 if (true === this.defaults.async){73 $().FormHandler(form);74 } else {75 $(form).submit();76 }77 } 78 }, 79 80 FormHandler : function (form){81 this.defaults.formAction = $(form).attr('action');82 var formData = $(form).serialize(); 83 if (false !== this.defaults.formIdent){84 formData += '&' + this.defaults.formIdent + '=' + $(form).attr('data-' + this.defaults.formIdent);85 }86 if (false !== this.defaults.formAction){87 $.ajax({88 url : this.defaults.formAction,89 type : this.defaults.formMethod,90 data : formData, 91 beforeSend : function(){92 $().BeforeSendPanel(); 93 }, 94 error : function (argument) {95 $().FormErrorPanel();96 },97 success : function(data) {98 var obj = jQuery.parseJSON(data);99 if (obj.success){100 $( '.server-process' ).html('');101 $().FormSuccessPanel(obj.success);102 } else if (obj.error) { 103 $().FieldErrorPanel();104 $.each(obj.error.fields, function(index, messages) {105 $.each(messages, function(mIndex, message) {106 $().MarkErrorField(index, message);107 });108 }); 109 } else {110 $().FormErrorPanel();111 } 112 }, 113 });114 } 115 },116 117 IsBootstrapPanel : function(content) {118 if ( true === this.defaults.panelBootstrap ){119 return '<div class="panel-body">' + content + '</div>';120 } else {121 return content;122 }123 }, 124 125 BuildPanel : function ( type, content ) {126 var panelHtml = '<'+ this.defaults.panelTag +' class="';127 switch(type){128 case 'warn':129 panelHtml += this.defaults.panelWarn;130 break;131 case 'success':132 panelHtml += this.defaults.panelSuccess;133 break; 134 default:135 panelHtml += this.defaults.panel;136 break; 137 }138 return panelHtml + '">' + this.IsBootstrapPanel(content) + '</'+ this.defaults.panelTag +'>';139 },140 141142 143 BeforeSendPanel : function (){144 $(this.defaults.formProcessSelector).html( this.BuildPanel('warn', '<p class="text-center">' + this.FontAwesomeIcon('spinner','2x') + '</p>' ) );145 },146 147 FieldErrorPanel : function(){148 $(this.defaults.formProcessSelector).html('<div class="'+ this.defaults.panelWarn +'">' + this.IsBootstrapPanel('<p class="text-center"><i class="fa fa-exclamation-triangle fa-2x alizarin-color"> </i></p>') + '</div>');149 },150 /*151 FormErrorPanel : function(){152 var str = '<div class="panel alert">';153 str += '<h2>Ihr Formular wurde erfolgreich übermittelt<h2>';154 str += '<p>Vielen Dank für Ihre Nachricht.</p>';155 str += '</div>';156 $(this.defaults.formResultSelector).html(str);157 }, */ 158 159 FormErrorPanel : function(){160 var str = '<div class="panel alert">';161 str += '<h2>Fehler beim versenden des Formulars<h2>';162 str += '<p>Das Formular konnte nicht versandt werden, versuchen Sie es später Bitte noch einmal.<br />';163 str += 'oder wenden Sie sich Bitte direkt an uns.</p>';164 str += '</div>';165 $(this.defaults.formResultSelector).html(str);166 },167 168 FormSuccessPanel : function(messages){169 var html = '<div class="panel success">';170 html += '<p class="text-center"><i class="fa fa-check-circle emerald-color fa-2x"> </i></p>';171 html += messages;172 html += '</div>'; 173 $(this.defaults.formResultSelector).html(html); 174 },175 176 MarkErrorField : function(fieldname, messages) {177 $('#field' + fieldname).addClass("error");178 $('#field' + fieldname).append('<span role="alert" id="err' + fieldname + '" class="validation-error">' + messages + '</span>');179 },180 181 UnmarkErrorFields : function(fieldname) {182 $("#field" + fieldname).removeClass("error");183 $("#err" + fieldname).remove();184 }, 185 186 FontAwesomeIcon : function(type, size){187 var fontIcon = '<i class="';188 switch(type){189 case 'warn':190 fontIcon += this.defaults.iconWarn;191 break;192 case 'success':193 fontIcon += this.defaults.iconSuccess;194 break;195 case 'spinner':196 fontIcon += this.defaults.iconSpinner;197 break; 198 default:199 return '';200 break;201 }202 switch(size){203 case '2x':204 fontIcon += ' ' + this.defaults.icon2x;205 break;206 default:207 break;208 } 209 switch(type){210 case 'spinner':211 case 'warn':212 fontIcon += ' ' + this.defaults.warnColor;213 break;214 case 'sucess':215 fontIcon += ' ' + this.defaults.successColor;216 break; 217 default:218 break;219 } 220 return fontIcon + '"> </i>';221 },222 223 224 });225
...
yetii.js
Source:yetii.js
1/*2Yetii - Yet (E)Another Tab Interface Implementation3version 1.64http://www.kminek.pl/lab/yetii/5Copyright (c) Grzegorz Wojcik6Code licensed under the BSD License:7http://www.kminek.pl/bsdlicense.txt8*/9function Yetii() {10 this.defaults = {11 12 id: null,13 active: 1,14 interval: null,15 wait: null,16 persist: null,17 tabclass: 'tab',18 activeclass: 'active',19 callback: null,20 leavecallback: null21 22 };23 24 this.activebackup = null;25 26 for (var n in arguments[0]) { this.defaults[n]=arguments[0][n]; }; 27 28 this.getTabs = function() {29 30 var retnode = [];31 var elem = document.getElementById(this.defaults.id).getElementsByTagName('*');32 33 var regexp = new RegExp("(^|\\s)" + this.defaults.tabclass.replace(/\-/g, "\\-") + "(\\s|$)");34 35 for (var i = 0; i < elem.length; i++) {36 if (regexp.test(elem[i].className)) retnode.push(elem[i]);37 }38 39 return retnode;40 41 };42 43 this.links = document.getElementById(this.defaults.id + '-nav').getElementsByTagName('a');44 this.listitems = document.getElementById(this.defaults.id + '-nav').getElementsByTagName('li');45 46 this.show = function(number) {47 48 for (var i = 0; i < this.tabs.length; i++) {49 50 this.tabs[i].style.display = ((i+1)==number) ? 'block' : 'none';51 52 if ((i+1)==number) {53 this.addClass(this.links[i], this.defaults.activeclass);54 this.addClass(this.listitems[i], this.defaults.activeclass + 'li');55 } else {56 this.removeClass(this.links[i], this.defaults.activeclass);57 this.removeClass(this.listitems[i], this.defaults.activeclass + 'li');58 }59 60 }61 62 63 if (this.defaults.leavecallback && (number != this.activebackup)) this.defaults.leavecallback(this.defaults.active);64 65 this.activebackup = number;66 67 68 this.defaults.active = number;69 70 if (this.defaults.callback) this.defaults.callback(number);71 72 73 };74 75 this.rotate = function(interval) {76 77 this.show(this.defaults.active);78 this.defaults.active++;79 80 if (this.defaults.active > this.tabs.length) this.defaults.active = 1;81 82 83 var self = this;84 85 if (this.defaults.wait) clearTimeout(this.timer2);86 87 this.timer1 = setTimeout(function(){self.rotate(interval);}, interval*1000);88 89 };90 91 this.next = function() {92 var _target = (this.defaults.active + 1 > this.tabs.length) ? 1 : this.defaults.active + 1;93 this.show(_target);94 this.defaults.active = _target;95 };96 97 this.previous = function() {98 var _target = ((this.defaults.active - 1) == 0) ? this.tabs.length : this.defaults.active - 1;99 this.show(_target);100 this.defaults.active = _target; 101 };102 103 this.previous = function() {104 105 this.defaults.active--;106 if(!this.defaults.active) this.defaults.active = this.tabs.length;107 this.show(this.defaults.active);108 109 };110 111 this.gup = function(name) {112 name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");113 var regexS = "[\\?&]"+name+"=([^&#]*)";114 var regex = new RegExp( regexS );115 var results = regex.exec( window.location.href );116 if (results == null) return null;117 else return results[1];118 };119 120 this.parseurl = function(tabinterfaceid) {121 122 var result = this.gup(tabinterfaceid);123 124 if (result==null) return null;125 if (parseInt(result)) return parseInt(result); 126 if (document.getElementById(result)) { 127 for (var i=0;i<this.tabs.length;i++) {128 if (this.tabs[i].id == result) return (i+1);129 }130 }131 132 return null;133 134 };135 this.createCookie = function(name,value,days) {136 if (days) {137 var date = new Date();138 date.setTime(date.getTime()+(days*24*60*60*1000));139 var expires = "; expires="+date.toGMTString();140 }141 else var expires = "";142 document.cookie = name+"="+value+expires+"; path=/";143 };144 145 this.readCookie = function(name) {146 var nameEQ = name + "=";147 var ca = document.cookie.split(';');148 for(var i=0;i < ca.length;i++) {149 var c = ca[i];150 while (c.charAt(0)==' ') c = c.substring(1,c.length);151 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);152 }153 return null;154 };155 156 this.contains = function(el, item, from) {157 return el.indexOf(item, from) != -1;158 };159 160 this.hasClass = function(el, className){161 return this.contains(el.className, className, ' ');162 };163 164 this.addClass = function(el, className){165 if (!this.hasClass(el, className)) el.className = (el.className + ' ' + className).replace(/\s{2,}/g, ' ').replace(/^\s+|\s+$/g, '');166 };167 168 this.removeClass = function(el, className){169 el.className = el.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1');170 el.className.replace(/\s{2,}/g, ' ').replace(/^\s+|\s+$/g, '');171 };172 this.tabs = this.getTabs();173 this.defaults.active = (this.parseurl(this.defaults.id)) ? this.parseurl(this.defaults.id) : this.defaults.active;174 if (this.defaults.persist && this.readCookie(this.defaults.id)) this.defaults.active = this.readCookie(this.defaults.id); 175 this.activebackup = this.defaults.active;176 this.show(this.defaults.active);177 178 var self = this;179 for (var i = 0; i < this.links.length; i++) {180 this.links[i].customindex = i+1;181 this.links[i].onclick = function(){ 182 183 if (self.timer1) clearTimeout(self.timer1);184 if (self.timer2) clearTimeout(self.timer2); 185 186 self.show(this.customindex);187 if (self.defaults.persist) self.createCookie(self.defaults.id, this.customindex, 0);188 189 if (self.defaults.wait) self.timer2 = setTimeout(function(){self.rotate(self.defaults.interval);}, self.defaults.wait*1000);190 191 return false;192 };193 }194 195 if (this.defaults.interval) this.rotate(this.defaults.interval);196 ...
java.js
Source:java.js
1/*2Yetii - Yet (E)Another Tab Interface Implementation3http://www.kminek.pl/lab/yetii/4Copyright (c) 2007 Grzegorz Wojcik5Code licensed under the BSD License:6http://www.kminek.pl/bsdlicense.txt7*/89function Yetii() {1011 this.defaults = {12 13 id: null,14 active: 1,15 timeout: null,16 interval: null,17 tabclass: 'tab',18 activeclass: 'active'19 20 };21 22 for (var n in arguments[0]) { this.defaults[n]=arguments[0][n]; }; 23 24 this.getTabs = function() {25 26 27 var retnode = [];28 var elem = document.getElementById(this.defaults.id).getElementsByTagName('*');29 30 var regexp = new RegExp("(^|\\s)" + this.defaults.tabclass.replace(/\-/g, "\\-") + "(\\s|$)");31 32 for (var i = 0; i < elem.length; i++) {33 if (regexp.test(elem[i].className)) retnode.push(elem[i]);34 }35 36 return retnode;37 38 };39 40 this.links = document.getElementById(this.defaults.id + '-nav').getElementsByTagName('a');41 42 this.show = function(number){43 44 for (var i = 0; i < this.tabs.length; i++) {45 this.tabs[i].style.display = ((i+1)==number) ? 'block' : 'none';46 this.links[i].className = ((i+1)==number) ? this.defaults.activeclass : '';47 }48 49 };50 51 this.rotate = function(interval){52 53 this.show(this.defaults.active);54 this.defaults.active++;55 56 if(this.defaults.active > this.tabs.length) this.defaults.active = 1;57 58 var self = this;59 this.defaults.timeout = setTimeout(function(){self.rotate(interval);}, interval*1000);60 61 };62 63 this.tabs = this.getTabs();64 this.show(this.defaults.active);65 66 var self = this;67 for (var i = 0; i < this.links.length; i++) {68 this.links[i].customindex = i+1;69 this.links[i].onclick = function(){ if (self.defaults.timeout) clearTimeout(self.defaults.timeout); self.show(this.customindex); return false; };70 }71 72 if (this.defaults.interval) this.rotate(this.defaults.interval);73
...
parametroOperacao.js
Source:parametroOperacao.js
1define(['configuracoes'], 2function(config){3 4 var _this = null;5 var ComboLocal = Backbone.Model.extend({6 7 urlRoot: config['urlBaseRest'] + 'Administracao/parametroOperacao/',8 defaults: {9 numero: 0,10 descricao: '',11 grupoTaxaPadrao: undefined,12 indicadorTaxaPadrao: undefined,13 idadeMinima: 0,14 idadeMaxima: 0,15 exigeAutorizacao: '',16 valorMinimoExigencia: 0,17 maximoDiasSimulacaoFutura: 018 },19 20 initialize: function initialize() {21 this.set({22 numero: this.defaults.numero,23 descricao: this.defaults.descricao,24 grupoTaxaPadrao: this.defaults.grupoTaxaPadrao,25 indicadorTaxaPadrao: this.defaults.indicadorTaxaPadrao,26 idadeMinima: this.defaults.idadeMinima,27 idadeMaxima: this.defaults.idadeMaxima,28 exigeAutorizacao: this.defaults.exigeAutorizacao,29 valorMinimoExigencia: this.defaults.valorMinimoExigencia,30 maximoDiasSimulacaoFutura: this.defaults.maximoDiasSimulacaoFutura31 });32 },33 34 consultar: function () {35 _this = this;36 _this.url = _this.urlRoot + "consultar";37 38 return _this.fetch({39 type: "GET",40 contentType: "application/json"41 });42 }43 44 });45 46 return ComboLocal;47 ...
Using AI Code Generation
1describe('My First Test', function() {2 it('Does not do much!', function() {3 cy.pause()4 cy.contains('type').click()5 cy.url().should('include', '/commands/actions')6 cy.get('.action-email')7 .type('
Using AI Code Generation
1describe('My First Test', function() {2 it('Visits the Kitchen Sink', function() {3 cy.pause()4 cy.contains('type').click()5 cy.url().should('include', '/commands/actions')6 cy.get('.action-email')7 .type('
Using AI Code Generation
1describe('My First Test', function() {2 it('Does not do much!', function() {3 cy.contains('type').click()4 cy.url().should('include', '/commands/actions')5 cy.get('.action-email')6 .type('
Using AI Code Generation
1describe('My First Test', function() {2 it('Does not do much!', function() {3 cy.pause()4 cy.contains('type').click()5 cy.url().should('include', '/commands/actions')6 cy.get('.action-email')7 .type('
Using AI Code Generation
1Cypress.Commands.add("defaults", () => {2 Cypress.Cookies.defaults({3 });4});5Cypress.Commands.add("login", (username, password) => {6 cy.get("#username").type(username);7 cy.get("#password").type(password);8 cy.get("#login").click();9});10Cypress.Commands.add("logout", () => {11 cy.get("#logout").click();12});13Cypress.Commands.add("loginAs", (username, password) => {14 cy.get("#user_login").type(username);15 cy.get("#user_password").type(password);16 cy.get("#user_remember_me").click();17 cy.contains("Sign in").click();18});19Cypress.Commands.add("loginAsAdmin", () => {20 cy.fixture("user").then((user) => {21 const username = user.id;22 const password = user.pwd;23 cy.get("#user_login").type(username);24 cy.get("#user_password").type(password);25 cy.contains("Sign in").click();26 });27});
Using AI Code Generation
1Cypress.Commands.add("defaults", function (options) {2 Cypress._.defaults(options, {3 headers: {4 },5 });6});7Cypress.Commands.add("defaults", function (options) {8 Cypress._.defaults(options, {9 headers: {10 },11 });12});13Cypress.Commands.add("defaults", function (options) {14 Cypress._.defaults(options, {15 headers: {16 },17 });18});19Cypress.Commands.add("defaults", function (options) {20 Cypress._.defaults(options, {21 headers: {22 },23 });24});25Cypress.Commands.add("defaults", function (options) {26 Cypress._.defaults(options, {27 headers: {28 },29 });30});31Cypress.Commands.add("defaults", function (options) {32 Cypress._.defaults(options, {33 headers: {34 },35 });36});37Cypress.Commands.add("defaults", function (options) {38 Cypress._.defaults(options, {39 headers: {40 },41 });42});43Cypress.Commands.add("defaults", function (options) {44 Cypress._.defaults(options, {45 headers: {46 },47 });48});49Cypress.Commands.add("defaults", function (options) {50 Cypress._.defaults(options, {51 headers: {52 },53 });54});
Using AI Code Generation
1const defaults = require('lodash/defaults');2const defaultsDeep = require('lodash/defaultsDeep');3Cypress.Commands.add('defaults', { prevSubject: true }, (subject, ...args) => {4 return defaults(subject, ...args);5});6Cypress.Commands.add('defaultsDeep', { prevSubject: true }, (subject, ...args) => {7 return defaultsDeep(subject, ...args);8});9const defaults = require('lodash/defaults');10const defaultsDeep = require('lodash/defaultsDeep');11Cypress.Commands.add('defaults', { prevSubject: true }, (subject, ...args) => {12 return defaults(subject, ...args);13});14Cypress.Commands.add('defaultsDeep', { prevSubject: true }, (subject, ...args) => {15 return defaultsDeep(subject, ...args);16});17const defaults = require('lodash/defaults');18const defaultsDeep = require('lodash/defaultsDeep');19Cypress.Commands.add('defaults', { prevSubject: true }, (subject, ...args) => {20 return defaults(subject, ...args);21});22Cypress.Commands.add('defaultsDeep', { prevSubject: true }, (subject, ...args) => {23 return defaultsDeep(subject, ...args);24});25const defaults = require('lodash/defaults');26const defaultsDeep = require('lodash/defaultsDeep');27Cypress.Commands.add('defaults', { prevSubject: true }, (subject, ...args) => {28 return defaults(subject, ...args);29});30Cypress.Commands.add('defaultsDeep', { prevSubject: true }, (subject, ...args) => {31 return defaultsDeep(subject, ...args);32});33const defaults = require('lodash/defaults');34const defaultsDeep = require('lodash/defaultsDeep');35Cypress.Commands.add('defaults', { prevSubject: true }, (subject, ...args) => {36 return defaults(subject, ...args);37});38Cypress.Commands.add('defaultsDeep', { prevSubject: true }, (subject, ...args) => {39 return defaultsDeep(subject, ...args);40});41const defaults = require('lodash/defaults');
Using AI Code Generation
1describe('Test Suite', function () {2 before(function () {3 cy.fixture('testdata').then(function (data) {4 })5 })6 it('Test Case', function () {7 cy.get('.search-keyword').type(this.data.productName)8 cy.wait(2000)9 cy.get('.product:visible').should('have.length', 4)10 cy.get('.products').as('productLocator')11 cy.get('@productLocator').find('.product').should('have.length', 4)12 cy.get(':nth-child(3) > .product-action > button').click()13 cy.get(':nth-child(4) > .product-action > button').click()14 cy.get('.brand').then(function (logoElement) {15 cy.log(logoElement.text())16 })17 cy.get('@productLocator').find('.product').eq(2).contains('ADD TO CART').click()18 cy.get('@productLocator').find('.product').each(($el, index, $list) => {19 const textVeg = $el.find('h4.product-name').text()20 if (textVeg.includes('Cashews')) {21 $el.find('button').click()22 }23 })24 cy.get('.brand').should('have.text', 'GREENKART')25 cy.get('.brand').then(function (logoElement) {26 cy.log(logoElement.text())27 expect(logoElement.text()).to.equal('GREENKART')28 })29 cy.get('.brand').then(function (logoElement) {30 cy.log(logoElement.text())31 expect(logoElement.text()).to.equal('GREENKART')32 })33 })34})
Cypress is a renowned Javascript-based open-source, easy-to-use end-to-end testing framework primarily used for testing web applications. Cypress is a relatively new player in the automation testing space and has been gaining much traction lately, as evidenced by the number of Forks (2.7K) and Stars (42.1K) for the project. LambdaTest’s Cypress Tutorial covers step-by-step guides that will help you learn from the basics till you run automation tests on LambdaTest.
You can elevate your expertise with end-to-end testing using the Cypress automation framework and stay one step ahead in your career by earning a Cypress certification. Check out our Cypress 101 Certification.
Watch this 3 hours of complete tutorial to learn the basics of Cypress and various Cypress commands with the Cypress testing at LambdaTest.
Get 100 minutes of automation test minutes FREE!!