Better looking settings tabs in pmahomme
[phpmyadmin.git] / js / jquery / timepicker.js
blob41e3ea005d7ab22035137cdf845fc3ec055075ff
1 /*\r
2 * jQuery timepicker addon\r
3 * By: Trent Richardson [http://trentrichardson.com]\r
4 * Version 0.9.6\r
5 * Last Modified: 07/20/2011\r
6 \r
7 * Copyright 2011 Trent Richardson\r
8 * Dual licensed under the MIT and GPL licenses.\r
9 * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt\r
10 * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt\r
11 \r
12 * HERES THE CSS:\r
13 * .ui-timepicker-div .ui-widget-header{ margin-bottom: 8px; }\r
14 * .ui-timepicker-div dl{ text-align: left; }\r
15 * .ui-timepicker-div dl dt{ height: 25px; }\r
16 * .ui-timepicker-div dl dd{ margin: -25px 10px 10px 65px; }\r
17 * .ui-timepicker-div td { font-size: 90%; }\r
18 */\r
20 (function($) {\r
22 $.extend($.ui, { timepicker: { version: "0.9.6" } });\r
24 /* Time picker manager.\r
25    Use the singleton instance of this class, $.timepicker, to interact with the time picker.\r
26    Settings for (groups of) time pickers are maintained in an instance object,\r
27    allowing multiple different settings on the same page. */\r
29 function Timepicker() {\r
30         this.regional = []; // Available regional settings, indexed by language code\r
31         this.regional[''] = { // Default regional settings\r
32                 currentText: 'Now',\r
33                 closeText: 'Done',\r
34                 ampm: false,\r
35                 timeFormat: 'hh:mm tt',\r
36                 timeSuffix: '',\r
37                 timeOnlyTitle: 'Choose Time',\r
38                 timeText: 'Time',\r
39                 hourText: 'Hour',\r
40                 minuteText: 'Minute',\r
41                 secondText: 'Second',\r
42                 timezoneText: 'Time Zone'\r
43         };\r
44         this._defaults = { // Global defaults for all the datetime picker instances\r
45                 showButtonPanel: true,\r
46                 timeOnly: false,\r
47                 showHour: true,\r
48                 showMinute: true,\r
49                 showSecond: false,\r
50                 showTimezone: false,\r
51                 showTime: true,\r
52                 stepHour: 0.05,\r
53                 stepMinute: 0.05,\r
54                 stepSecond: 0.05,\r
55                 hour: 0,\r
56                 minute: 0,\r
57                 second: 0,\r
58                 timezone: '+0000',\r
59                 hourMin: 0,\r
60                 minuteMin: 0,\r
61                 secondMin: 0,\r
62                 hourMax: 23,\r
63                 minuteMax: 59,\r
64                 secondMax: 59,\r
65                 minDateTime: null,\r
66                 maxDateTime: null,\r
67                 hourGrid: 0,\r
68                 minuteGrid: 0,\r
69                 secondGrid: 0,\r
70                 alwaysSetTime: true,\r
71                 separator: ' ',\r
72                 altFieldTimeOnly: true,\r
73                 showTimepicker: true,\r
74                 timezoneList: ["-1100", "-1000", "-0900", "-0800", "-0700", "-0600",\r
75                                "-0500", "-0400", "-0300", "-0200", "-0100", "+0000",\r
76                                "+0100", "+0200", "+0300", "+0400", "+0500", "+0600",\r
77                                "+0700", "+0800", "+0900", "+1000", "+1100", "+1200"]\r
78         };\r
79         $.extend(this._defaults, this.regional['']);\r
80 }\r
82 $.extend(Timepicker.prototype, {\r
83         $input: null,\r
84         $altInput: null,\r
85         $timeObj: null,\r
86         inst: null,\r
87         hour_slider: null,\r
88         minute_slider: null,\r
89         second_slider: null,\r
90         timezone_select: null,\r
91         hour: 0,\r
92         minute: 0,\r
93         second: 0,\r
94         timezone: '+0000',\r
95         hourMinOriginal: null,\r
96         minuteMinOriginal: null,\r
97         secondMinOriginal: null,\r
98         hourMaxOriginal: null,\r
99         minuteMaxOriginal: null,\r
100         secondMaxOriginal: null,\r
101         ampm: '',\r
102         formattedDate: '',\r
103         formattedTime: '',\r
104         formattedDateTime: '',\r
105         timezoneList: ["-1100", "-1000", "-0900", "-0800", "-0700", "-0600",\r
106                         "-0500", "-0400", "-0300", "-0200", "-0100", "+0000",\r
107                         "+0100", "+0200", "+0300", "+0400", "+0500", "+0600",\r
108                         "+0700", "+0800", "+0900", "+1000", "+1100", "+1200"],\r
110         /* Override the default settings for all instances of the time picker.\r
111            @param  settings  object - the new settings to use as defaults (anonymous object)\r
112            @return the manager object */\r
113         setDefaults: function(settings) {\r
114                 extendRemove(this._defaults, settings || {});\r
115                 return this;\r
116         },\r
118         //########################################################################\r
119         // Create a new Timepicker instance\r
120         //########################################################################\r
121         _newInst: function($input, o) {\r
122                 var tp_inst = new Timepicker(),\r
123                         inlineSettings = {};\r
124                         \r
125                 for (var attrName in this._defaults) {\r
126                         var attrValue = $input.attr('time:' + attrName);\r
127                         if (attrValue) {\r
128                                 try {\r
129                                         inlineSettings[attrName] = eval(attrValue);\r
130                                 } catch (err) {\r
131                                         inlineSettings[attrName] = attrValue;\r
132                                 }\r
133                         }\r
134                 }\r
135                 tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, {\r
136                         beforeShow: function(input, dp_inst) {\r
137                                 if ($.isFunction(o.beforeShow))\r
138                                         o.beforeShow(input, dp_inst, tp_inst);\r
139                         },\r
140                         onChangeMonthYear: function(year, month, dp_inst) {\r
141                                 // Update the time as well : this prevents the time from disappearing from the $input field.\r
142                                 tp_inst._updateDateTime(dp_inst);\r
143                                 if ($.isFunction(o.onChangeMonthYear))\r
144                                         o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);\r
145                         },\r
146                         onClose: function(dateText, dp_inst) {\r
147                                 if (tp_inst.timeDefined === true && $input.val() != '')\r
148                                         tp_inst._updateDateTime(dp_inst);\r
149                                 if ($.isFunction(o.onClose))\r
150                                         o.onClose.call($input[0], dateText, dp_inst, tp_inst);\r
151                         },\r
152                         timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');\r
153                 });\r
155                 tp_inst.hour = tp_inst._defaults.hour;\r
156                 tp_inst.minute = tp_inst._defaults.minute;\r
157                 tp_inst.second = tp_inst._defaults.second;\r
158                 tp_inst.ampm = '';\r
159                 tp_inst.$input = $input;\r
161                 if (o.altField)\r
162                         tp_inst.$altInput = $(o.altField)\r
163                                 .css({ cursor: 'pointer' })\r
164                                 .focus(function(){ $input.trigger("focus"); });\r
165                                         \r
166                 // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..\r
167                 if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date)\r
168                         tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());\r
169                 if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date)\r
170                         tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());\r
171                 if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date)\r
172                         tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());\r
173                 if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date)\r
174                         tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());\r
175                 \r
176                 return tp_inst;\r
177         },\r
179         //########################################################################\r
180         // add our sliders to the calendar\r
181         //########################################################################\r
182         _addTimePicker: function(dp_inst) {\r
183                 var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ?\r
184                                 this.$input.val() + ' ' + this.$altInput.val() : \r
185                                 this.$input.val();\r
187                 this.timeDefined = this._parseTime(currDT);\r
188                 this._limitMinMaxDateTime(dp_inst, false);\r
189                 this._injectTimePicker();\r
190         },\r
192         //########################################################################\r
193         // parse the time string from input value or _setTime\r
194         //########################################################################\r
195         _parseTime: function(timeString, withDate) {\r
196                 var regstr = this._defaults.timeFormat.toString()\r
197                                 .replace(/h{1,2}/ig, '(\\d?\\d)')\r
198                                 .replace(/m{1,2}/ig, '(\\d?\\d)')\r
199                                 .replace(/s{1,2}/ig, '(\\d?\\d)')\r
200                                 .replace(/t{1,2}/ig, '(am|pm|a|p)?')\r
201                                 .replace(/z{1}/ig, '((\\+|-)\\d\\d\\d\\d)?')\r
202                                 .replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$',\r
203                         order = this._getFormatPositions(),\r
204                         treg;\r
206                 if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);\r
208                 if (withDate || !this._defaults.timeOnly) {\r
209                         // the time should come after x number of characters and a space.\r
210                         // x = at least the length of text specified by the date format\r
211                         var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');\r
212                         // escape special regex characters in the seperator\r
213                         var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g");\r
214                         regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator.replace(specials, "\\$&") + regstr;\r
215                 }\r
216                 \r
217                 treg = timeString.match(new RegExp(regstr, 'i'));\r
219                 if (treg) {\r
220                         if (order.t !== -1)\r
221                                 this.ampm = ((treg[order.t] === undefined || treg[order.t].length === 0) ?\r
222                                         '' :\r
223                                         (treg[order.t].charAt(0).toUpperCase() == 'A') ? 'AM' : 'PM').toUpperCase();\r
225                         if (order.h !== -1) {\r
226                                 if (this.ampm == 'AM' && treg[order.h] == '12') \r
227                                         this.hour = 0; // 12am = 0 hour\r
228                                 else if (this.ampm == 'PM' && treg[order.h] != '12') \r
229                                         this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12\r
230                                 else this.hour = Number(treg[order.h]);\r
231                         }\r
233                         if (order.m !== -1) this.minute = Number(treg[order.m]);\r
234                         if (order.s !== -1) this.second = Number(treg[order.s]);\r
235                         if (order.z !== -1) this.timezone = treg[order.z];\r
236                         \r
237                         return true;\r
239                 }\r
240                 return false;\r
241         },\r
243         //########################################################################\r
244         // figure out position of time elements.. cause js cant do named captures\r
245         //########################################################################\r
246         _getFormatPositions: function() {\r
247                 var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|t{1,2}|z)/g),\r
248                         orders = { h: -1, m: -1, s: -1, t: -1, z: -1 };\r
250                 if (finds)\r
251                         for (var i = 0; i < finds.length; i++)\r
252                                 if (orders[finds[i].toString().charAt(0)] == -1)\r
253                                         orders[finds[i].toString().charAt(0)] = i + 1;\r
255                 return orders;\r
256         },\r
258         //########################################################################\r
259         // generate and inject html for timepicker into ui datepicker\r
260         //########################################################################\r
261         _injectTimePicker: function() {\r
262                 var $dp = this.inst.dpDiv,\r
263                         o = this._defaults,\r
264                         tp_inst = this,\r
265                         // Added by Peter Medeiros:\r
266                         // - Figure out what the hour/minute/second max should be based on the step values.\r
267                         // - Example: if stepMinute is 15, then minMax is 45.\r
268                         hourMax = (o.hourMax - (o.hourMax % o.stepHour)).toFixed(0),\r
269                         minMax  = (o.minuteMax - (o.minuteMax % o.stepMinute)).toFixed(0),\r
270                         secMax  = (o.secondMax - (o.secondMax % o.stepSecond)).toFixed(0),\r
271                         dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, '');\r
273                 // Prevent displaying twice\r
274                 //if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) {\r
275                 if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0 && o.showTimepicker) {\r
276                         var noDisplay = ' style="display:none;"',\r
277                                 html =  '<div class="ui-timepicker-div" id="ui-timepicker-div-' + dp_id + '"><dl>' +\r
278                                                 '<dt class="ui_tpicker_time_label" id="ui_tpicker_time_label_' + dp_id + '"' +\r
279                                                 ((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' +\r
280                                                 '<dd class="ui_tpicker_time" id="ui_tpicker_time_' + dp_id + '"' +\r
281                                                 ((o.showTime) ? '' : noDisplay) + '></dd>' +\r
282                                                 '<dt class="ui_tpicker_hour_label" id="ui_tpicker_hour_label_' + dp_id + '"' +\r
283                                                 ((o.showHour) ? '' : noDisplay) + '>' + o.hourText + '</dt>',\r
284                                 hourGridSize = 0,\r
285                                 minuteGridSize = 0,\r
286                                 secondGridSize = 0,\r
287                                 size;\r
288  \r
289                         if (o.showHour && o.hourGrid > 0) {\r
290                                 html += '<dd class="ui_tpicker_hour">' +\r
291                                                 '<div id="ui_tpicker_hour_' + dp_id + '"' + ((o.showHour)   ? '' : noDisplay) + '></div>' +\r
292                                                 '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';\r
294                                 for (var h = o.hourMin; h <= hourMax; h += o.hourGrid) {\r
295                                         hourGridSize++;\r
296                                         var tmph = (o.ampm && h > 12) ? h-12 : h;\r
297                                         if (tmph < 10) tmph = '0' + tmph;\r
298                                         if (o.ampm) {\r
299                                                 if (h == 0) tmph = 12 +'a';\r
300                                                 else if (h < 12) tmph += 'a';\r
301                                                 else tmph += 'p';\r
302                                         }\r
303                                         html += '<td>' + tmph + '</td>';\r
304                                 }\r
306                                 html += '</tr></table></div>' +\r
307                                                 '</dd>';\r
308                         } else html += '<dd class="ui_tpicker_hour" id="ui_tpicker_hour_' + dp_id + '"' +\r
309                                                         ((o.showHour) ? '' : noDisplay) + '></dd>';\r
311                         html += '<dt class="ui_tpicker_minute_label" id="ui_tpicker_minute_label_' + dp_id + '"' +\r
312                                         ((o.showMinute) ? '' : noDisplay) + '>' + o.minuteText + '</dt>';\r
314                         if (o.showMinute && o.minuteGrid > 0) {\r
315                                 html += '<dd class="ui_tpicker_minute ui_tpicker_minute_' + o.minuteGrid + '">' +\r
316                                                 '<div id="ui_tpicker_minute_' + dp_id + '"' +\r
317                                                 ((o.showMinute) ? '' : noDisplay) + '></div>' +\r
318                                                 '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';\r
320                                 for (var m = o.minuteMin; m <= minMax; m += o.minuteGrid) {\r
321                                         minuteGridSize++;\r
322                                         html += '<td>' + ((m < 10) ? '0' : '') + m + '</td>';\r
323                                 }\r
325                                 html += '</tr></table></div>' +\r
326                                                 '</dd>';\r
327                         } else html += '<dd class="ui_tpicker_minute" id="ui_tpicker_minute_' + dp_id + '"' +\r
328                                                         ((o.showMinute) ? '' : noDisplay) + '></dd>';\r
330                         html += '<dt class="ui_tpicker_second_label" id="ui_tpicker_second_label_' + dp_id + '"' +\r
331                                         ((o.showSecond) ? '' : noDisplay) + '>' + o.secondText + '</dt>';\r
333                         if (o.showSecond && o.secondGrid > 0) {\r
334                                 html += '<dd class="ui_tpicker_second ui_tpicker_second_' + o.secondGrid + '">' +\r
335                                                 '<div id="ui_tpicker_second_' + dp_id + '"' +\r
336                                                 ((o.showSecond) ? '' : noDisplay) + '></div>' +\r
337                                                 '<div style="padding-left: 1px"><table><tr>';\r
339                                 for (var s = o.secondMin; s <= secMax; s += o.secondGrid) {\r
340                                         secondGridSize++;\r
341                                         html += '<td>' + ((s < 10) ? '0' : '') + s + '</td>';\r
342                                 }\r
344                                 html += '</tr></table></div>' +\r
345                                                 '</dd>';\r
346                         } else html += '<dd class="ui_tpicker_second" id="ui_tpicker_second_' + dp_id + '"'     +\r
347                                                         ((o.showSecond) ? '' : noDisplay) + '></dd>';\r
348                                                         \r
349                         html += '<dt class="ui_tpicker_timezone_label" id="ui_tpicker_timezone_label_' + dp_id + '"' +\r
350                                         ((o.showTimezone) ? '' : noDisplay) + '>' + o.timezoneText + '</dt>';\r
351                         html += '<dd class="ui_tpicker_timezone" id="ui_tpicker_timezone_' + dp_id + '"'        +\r
352                                                         ((o.showTimezone) ? '' : noDisplay) + '></dd>';\r
354                         html += '</dl></div>';\r
355                         $tp = $(html);\r
357                                 // if we only want time picker...\r
358                         if (o.timeOnly === true) {\r
359                                 $tp.prepend(\r
360                                         '<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' +\r
361                                                 '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' +\r
362                                         '</div>');\r
363                                 $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();\r
364                         }\r
366                         this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({\r
367                                 orientation: "horizontal",\r
368                                 value: this.hour,\r
369                                 min: o.hourMin,\r
370                                 max: hourMax,\r
371                                 step: o.stepHour,\r
372                                 slide: function(event, ui) {\r
373                                         tp_inst.hour_slider.slider( "option", "value", ui.value);\r
374                                         tp_inst._onTimeChange();\r
375                                 }\r
376                         });\r
378                         // Updated by Peter Medeiros:\r
379                         // - Pass in Event and UI instance into slide function\r
380                         this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({\r
381                                 orientation: "horizontal",\r
382                                 value: this.minute,\r
383                                 min: o.minuteMin,\r
384                                 max: minMax,\r
385                                 step: o.stepMinute,\r
386                                 slide: function(event, ui) {\r
387                                         // update the global minute slider instance value with the current slider value\r
388                                         tp_inst.minute_slider.slider( "option", "value", ui.value);\r
389                                         tp_inst._onTimeChange();\r
390                                 }\r
391                         });\r
393                         this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({\r
394                                 orientation: "horizontal",\r
395                                 value: this.second,\r
396                                 min: o.secondMin,\r
397                                 max: secMax,\r
398                                 step: o.stepSecond,\r
399                                 slide: function(event, ui) {\r
400                                         tp_inst.second_slider.slider( "option", "value", ui.value);\r
401                                         tp_inst._onTimeChange();\r
402                                 }\r
403                         });\r
404                         \r
405                         \r
406                         this.timezone_select = $tp.find('#ui_tpicker_timezone_'+ dp_id).append('<select></select>').find("select");\r
407                         $.fn.append.apply(this.timezone_select,\r
408                                 $.map(o.timezoneList, function(val, idx) {\r
409                                         return $("<option />")\r
410                                                 .val(typeof val == "object" ? val.value : val)\r
411                                                 .text(typeof val == "object" ? val.label : val);\r
412                                 })\r
413                         );\r
414                         this.timezone_select.val((typeof this.timezone != "undefined" && this.timezone != null && this.timezone != "") ? this.timezone : o.timezone);\r
415                         this.timezone_select.change(function() {\r
416                                 tp_inst._onTimeChange();\r
417                         });\r
419                         // Add grid functionality\r
420                         if (o.showHour && o.hourGrid > 0) {\r
421                                 size = 100 * hourGridSize * o.hourGrid / (hourMax - o.hourMin);\r
423                                 $tp.find(".ui_tpicker_hour table").css({\r
424                                         width: size + "%",\r
425                                         marginLeft: (size / (-2 * hourGridSize)) + "%",\r
426                                         borderCollapse: 'collapse'\r
427                                 }).find("td").each( function(index) {\r
428                                         $(this).click(function() {\r
429                                                 var h = $(this).html();\r
430                                                 if(o.ampm)      {\r
431                                                         var ap = h.substring(2).toLowerCase(),\r
432                                                                 aph = parseInt(h.substring(0,2), 10);\r
433                                                         if (ap == 'a') {\r
434                                                                 if (aph == 12) h = 0;\r
435                                                                 else h = aph;\r
436                                                         } else if (aph == 12) h = 12;\r
437                                                         else h = aph + 12;\r
438                                                 }\r
439                                                 tp_inst.hour_slider.slider("option", "value", h);\r
440                                                 tp_inst._onTimeChange();\r
441                                                 tp_inst._onSelectHandler();\r
442                                         }).css({\r
443                                                 cursor: 'pointer',\r
444                                                 width: (100 / hourGridSize) + '%',\r
445                                                 textAlign: 'center',\r
446                                                 overflow: 'hidden'\r
447                                         });\r
448                                 });\r
449                         }\r
451                         if (o.showMinute && o.minuteGrid > 0) {\r
452                                 size = 100 * minuteGridSize * o.minuteGrid / (minMax - o.minuteMin);\r
453                                 $tp.find(".ui_tpicker_minute table").css({\r
454                                         width: size + "%",\r
455                                         marginLeft: (size / (-2 * minuteGridSize)) + "%",\r
456                                         borderCollapse: 'collapse'\r
457                                 }).find("td").each(function(index) {\r
458                                         $(this).click(function() {\r
459                                                 tp_inst.minute_slider.slider("option", "value", $(this).html());\r
460                                                 tp_inst._onTimeChange();\r
461                                                 tp_inst._onSelectHandler();\r
462                                         }).css({\r
463                                                 cursor: 'pointer',\r
464                                                 width: (100 / minuteGridSize) + '%',\r
465                                                 textAlign: 'center',\r
466                                                 overflow: 'hidden'\r
467                                         });\r
468                                 });\r
469                         }\r
471                         if (o.showSecond && o.secondGrid > 0) {\r
472                                 $tp.find(".ui_tpicker_second table").css({\r
473                                         width: size + "%",\r
474                                         marginLeft: (size / (-2 * secondGridSize)) + "%",\r
475                                         borderCollapse: 'collapse'\r
476                                 }).find("td").each(function(index) {\r
477                                         $(this).click(function() {\r
478                                                 tp_inst.second_slider.slider("option", "value", $(this).html());\r
479                                                 tp_inst._onTimeChange();\r
480                                                 tp_inst._onSelectHandler();\r
481                                         }).css({\r
482                                                 cursor: 'pointer',\r
483                                                 width: (100 / secondGridSize) + '%',\r
484                                                 textAlign: 'center',\r
485                                                 overflow: 'hidden'\r
486                                         });\r
487                                 });\r
488                         }\r
490                         var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');\r
491                         if ($buttonPanel.length) $buttonPanel.before($tp);\r
492                         else $dp.append($tp);\r
494                         this.$timeObj = $tp.find('#ui_tpicker_time_'+ dp_id);\r
496                         if (this.inst !== null) {\r
497                                 var timeDefined = this.timeDefined;\r
498                                 this._onTimeChange();\r
499                                 this.timeDefined = timeDefined;\r
500                         }\r
502                         //Emulate datepicker onSelect behavior. Call on slidestop.\r
503                         var onSelectDelegate = function() {\r
504                                 tp_inst._onSelectHandler();\r
505                         };\r
506                         this.hour_slider.bind('slidestop',onSelectDelegate);\r
507                         this.minute_slider.bind('slidestop',onSelectDelegate);\r
508                         this.second_slider.bind('slidestop',onSelectDelegate);\r
509                 }\r
510         },\r
512         //########################################################################\r
513         // This function tries to limit the ability to go outside the \r
514         // min/max date range\r
515         //########################################################################\r
516         _limitMinMaxDateTime: function(dp_inst, adjustSliders){\r
517                 var o = this._defaults,\r
518                         dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);\r
520                 if(!this._defaults.showTimepicker) return; // No time so nothing to check here\r
522                 if($.datepicker._get(dp_inst, 'minDateTime') !== null && dp_date){\r
523                         var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),\r
524                                 minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);\r
526                         if(this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null){\r
527                                 this.hourMinOriginal = o.hourMin;\r
528                                 this.minuteMinOriginal = o.minuteMin;\r
529                                 this.secondMinOriginal = o.secondMin;\r
530                         }\r
532                         if(dp_inst.settings.timeOnly || minDateTimeDate.getTime() == dp_date.getTime()) {\r
533                                 this._defaults.hourMin = minDateTime.getHours();\r
534                                 if (this.hour <= this._defaults.hourMin) {\r
535                                         this.hour = this._defaults.hourMin;\r
536                                         this._defaults.minuteMin = minDateTime.getMinutes();\r
537                                         if (this.minute <= this._defaults.minuteMin) {\r
538                                                 this.minute = this._defaults.minuteMin;\r
539                                                 this._defaults.secondMin = minDateTime.getSeconds();\r
540                                         } else {\r
541                                                 if(this.second < this._defaults.secondMin) this.second = this._defaults.secondMin;\r
542                                                 this._defaults.secondMin = this.secondMinOriginal;\r
543                                         }\r
544                                 } else {\r
545                                         this._defaults.minuteMin = this.minuteMinOriginal;\r
546                                         this._defaults.secondMin = this.secondMinOriginal;\r
547                                 }\r
548                         }else{\r
549                                 this._defaults.hourMin = this.hourMinOriginal;\r
550                                 this._defaults.minuteMin = this.minuteMinOriginal;\r
551                                 this._defaults.secondMin = this.secondMinOriginal;\r
552                         }\r
553                 }\r
555                 if($.datepicker._get(dp_inst, 'maxDateTime') !== null && dp_date){\r
556                         var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),\r
557                                 maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);\r
558         \r
559                         if(this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null){\r
560                                 this.hourMaxOriginal = o.hourMax;\r
561                                 this.minuteMaxOriginal = o.minuteMax;\r
562                                 this.secondMaxOriginal = o.secondMax;\r
563                         }\r
565                         if(dp_inst.settings.timeOnly || maxDateTimeDate.getTime() == dp_date.getTime()){\r
566                                 this._defaults.hourMax = maxDateTime.getHours();\r
567                                 if (this.hour >= this._defaults.hourMax) {\r
568                                         this.hour = this._defaults.hourMax;\r
569                                         this._defaults.minuteMax = maxDateTime.getMinutes();\r
570                                         if (this.minute >= this._defaults.minuteMax) {\r
571                                                 this.minute = this._defaults.minuteMax;\r
572                                                 this._defaults.secondMax = maxDateTime.getSeconds();\r
573                                         } else {\r
574                                                 if(this.second > this._defaults.secondMax) this.second = this._defaults.secondMax;\r
575                                                 this._defaults.secondMax = this.secondMaxOriginal;\r
576                                         }\r
577                                 } else {\r
578                                         this._defaults.minuteMax = this.minuteMaxOriginal;\r
579                                         this._defaults.secondMax = this.secondMaxOriginal;\r
580                                 }\r
581                         }else{\r
582                                 this._defaults.hourMax = this.hourMaxOriginal;\r
583                                 this._defaults.minuteMax = this.minuteMaxOriginal;\r
584                                 this._defaults.secondMax = this.secondMaxOriginal;\r
585                         }\r
586                 }\r
588                 if(adjustSliders !== undefined && adjustSliders === true){\r
589                         var hourMax = (this._defaults.hourMax - (this._defaults.hourMax % this._defaults.stepHour)).toFixed(0),\r
590                                 minMax  = (this._defaults.minuteMax - (this._defaults.minuteMax % this._defaults.stepMinute)).toFixed(0),\r
591                                 secMax  = (this._defaults.secondMax - (this._defaults.secondMax % this._defaults.stepSecond)).toFixed(0);\r
593                         if(this.hour_slider)\r
594                                 this.hour_slider.slider("option", { min: this._defaults.hourMin, max: hourMax }).slider('value', this.hour);\r
595                         if(this.minute_slider)\r
596                                 this.minute_slider.slider("option", { min: this._defaults.minuteMin, max: minMax }).slider('value', this.minute);\r
597                         if(this.second_slider)\r
598                                 this.second_slider.slider("option", { min: this._defaults.secondMin, max: secMax }).slider('value', this.second);\r
599                 }\r
601         },\r
603         \r
604         //########################################################################\r
605         // when a slider moves, set the internal time...\r
606         // on time change is also called when the time is updated in the text field\r
607         //########################################################################\r
608         _onTimeChange: function() {\r
609                 var hour   = (this.hour_slider) ? this.hour_slider.slider('value') : false,\r
610                         minute = (this.minute_slider) ? this.minute_slider.slider('value') : false,\r
611                         second = (this.second_slider) ? this.second_slider.slider('value') : false,\r
612                         timezone = (this.timezone_select) ? this.timezone_select.val() : false;\r
614                 if (typeof(hour) == 'object') hour = false;\r
615                 if (typeof(minute) == 'object') minute = false;\r
616                 if (typeof(second) == 'object') second = false;\r
617                 if (typeof(timezone) == 'object') timezone = false;\r
619                 if (hour !== false) hour = parseInt(hour,10);\r
620                 if (minute !== false) minute = parseInt(minute,10);\r
621                 if (second !== false) second = parseInt(second,10);\r
623                 var ampm = (hour < 12) ? 'AM' : 'PM';\r
625                 // If the update was done in the input field, the input field should not be updated.\r
626                 // If the update was done using the sliders, update the input field.\r
627                 var hasChanged = (hour != this.hour || minute != this.minute || second != this.second || (this.ampm.length > 0 && this.ampm != ampm) || timezone != this.timezone);\r
628                 \r
629                 if (hasChanged) {\r
631                         if (hour !== false)this.hour = hour;\r
632                         if (minute !== false) this.minute = minute;\r
633                         if (second !== false) this.second = second;\r
634                         if (timezone !== false) this.timezone = timezone;\r
635                         \r
636                         if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);\r
637                         \r
638                         this._limitMinMaxDateTime(this.inst, true);\r
639                 }\r
640                 if (this._defaults.ampm) this.ampm = ampm;\r
641                 \r
642                 this._formatTime();\r
643                 if (this.$timeObj) this.$timeObj.text(this.formattedTime + this._defaults.timeSuffix);\r
644                 this.timeDefined = true;\r
645                 if (hasChanged) this._updateDateTime();\r
646         },\r
647     \r
648         //########################################################################\r
649         // call custom onSelect. \r
650         // bind to sliders slidestop, and grid click.\r
651         //########################################################################\r
652         _onSelectHandler: function() {\r
653                 var onSelect = this._defaults['onSelect'];\r
654                 var inputEl = this.$input ? this.$input[0] : null;\r
655                 if (onSelect && inputEl) {\r
656                         onSelect.apply(inputEl, [this.formattedDateTime, this]);\r
657                 }\r
658         },\r
660         //########################################################################\r
661         // format the time all pretty...\r
662         //########################################################################\r
663         _formatTime: function(time, format, ampm) {\r
664                 if (ampm == undefined) ampm = this._defaults.ampm;\r
665                 time = time || { hour: this.hour, minute: this.minute, second: this.second, ampm: this.ampm, timezone: this.timezone };\r
666                 var tmptime = format || this._defaults.timeFormat.toString();\r
668                 if (ampm) {\r
669                         var hour12 = ((time.ampm == 'AM') ? (time.hour) : (time.hour % 12));\r
670                         hour12 = (Number(hour12) === 0) ? 12 : hour12;\r
671                         tmptime = tmptime.toString()\r
672                                 .replace(/hh/g, ((hour12 < 10) ? '0' : '') + hour12)\r
673                                 .replace(/h/g, hour12)\r
674                                 .replace(/mm/g, ((time.minute < 10) ? '0' : '') + time.minute)\r
675                                 .replace(/m/g, time.minute)\r
676                                 .replace(/ss/g, ((time.second < 10) ? '0' : '') + time.second)\r
677                                 .replace(/s/g, time.second)\r
678                                 .replace(/TT/g, time.ampm.toUpperCase())\r
679                                 .replace(/Tt/g, time.ampm.toUpperCase())\r
680                                 .replace(/tT/g, time.ampm.toLowerCase())\r
681                                 .replace(/tt/g, time.ampm.toLowerCase())\r
682                                 .replace(/T/g, time.ampm.charAt(0).toUpperCase())\r
683                                 .replace(/t/g, time.ampm.charAt(0).toLowerCase())\r
684                                 .replace(/z/g, time.timezone);\r
685                 } else {\r
686                         tmptime = tmptime.toString()\r
687                                 .replace(/hh/g, ((time.hour < 10) ? '0' : '') + time.hour)\r
688                                 .replace(/h/g, time.hour)\r
689                                 .replace(/mm/g, ((time.minute < 10) ? '0' : '') + time.minute)\r
690                                 .replace(/m/g, time.minute)\r
691                                 .replace(/ss/g, ((time.second < 10) ? '0' : '') + time.second)\r
692                                 .replace(/s/g, time.second)\r
693                                 .replace(/z/g, time.timezone);\r
694                         tmptime = $.trim(tmptime.replace(/t/gi, ''));\r
695                 }\r
697                 if (arguments.length) return tmptime;\r
698                 else this.formattedTime = tmptime;\r
699         },\r
701         //########################################################################\r
702         // update our input with the new date time..\r
703         //########################################################################\r
704         _updateDateTime: function(dp_inst) {\r
705                 dp_inst = this.inst || dp_inst,\r
706                         dt = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay),\r
707                         dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),\r
708                         formatCfg = $.datepicker._getFormatConfig(dp_inst),\r
709                         timeAvailable = dt !== null && this.timeDefined;\r
710                 this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);\r
711                 var formattedDateTime = this.formattedDate;\r
712                 if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0))\r
713                         return;\r
715                 if (this._defaults.timeOnly === true) {\r
716                         formattedDateTime = this.formattedTime;\r
717                 } else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) {\r
718                         formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;\r
719                 }\r
721                 this.formattedDateTime = formattedDateTime;\r
723                 if(!this._defaults.showTimepicker) {\r
724                         this.$input.val(this.formattedDate);\r
725                 } else if (this.$altInput && this._defaults.altFieldTimeOnly === true) {\r
726                         this.$altInput.val(this.formattedTime);\r
727                         this.$input.val(this.formattedDate);\r
728                 } else if(this.$altInput) {\r
729                         this.$altInput.val(formattedDateTime);\r
730                         this.$input.val(formattedDateTime);\r
731                 } else {\r
732                         this.$input.val(formattedDateTime);\r
733                 }\r
734                 \r
735                 this.$input.trigger("change");\r
736         }\r
738 });\r
740 $.fn.extend({\r
741         //########################################################################\r
742         // shorthand just to use timepicker..\r
743         //########################################################################\r
744         timepicker: function(o) {\r
745                 o = o || {};\r
746                 var tmp_args = arguments;\r
748                 if (typeof o == 'object') tmp_args[0] = $.extend(o, { timeOnly: true });\r
750                 return $(this).each(function() {\r
751                         $.fn.datetimepicker.apply($(this), tmp_args);\r
752                 });\r
753         },\r
755         //########################################################################\r
756         // extend timepicker to datepicker\r
757         //########################################################################\r
758         datetimepicker: function(o) {\r
759                 o = o || {};\r
760                 var $input = this,\r
761                 tmp_args = arguments;\r
763                 if (typeof(o) == 'string'){\r
764                         if(o == 'getDate') \r
765                                 return $.fn.datepicker.apply($(this[0]), tmp_args);\r
766                         else \r
767                                 return this.each(function() {\r
768                                         var $t = $(this);\r
769                                         $t.datepicker.apply($t, tmp_args);\r
770                                 });\r
771                 }\r
772                 else\r
773                         return this.each(function() {\r
774                                 var $t = $(this);\r
775                                 $t.datepicker($.timepicker._newInst($t, o)._defaults);\r
776                         });\r
777         }\r
778 });\r
780 //########################################################################\r
781 // the bad hack :/ override datepicker so it doesnt close on select\r
782 // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378\r
783 //########################################################################\r
784 $.datepicker._base_selectDate = $.datepicker._selectDate;\r
785 $.datepicker._selectDate = function (id, dateStr) {\r
786         var inst = this._getInst($(id)[0]),\r
787                 tp_inst = this._get(inst, 'timepicker');\r
789         if (tp_inst) {\r
790                 tp_inst._limitMinMaxDateTime(inst, true);\r
791                 inst.inline = inst.stay_open = true;\r
792                 //This way the onSelect handler called from calendarpicker get the full dateTime\r
793                 this._base_selectDate(id, dateStr + tp_inst._defaults.separator + tp_inst.formattedTime + tp_inst._defaults.timeSuffix);\r
794                 inst.inline = inst.stay_open = false;\r
795                 this._notifyChange(inst);\r
796                 this._updateDatepicker(inst);\r
797         }\r
798         else this._base_selectDate(id, dateStr);\r
799 };\r
801 //#############################################################################################\r
802 // second bad hack :/ override datepicker so it triggers an event when changing the input field\r
803 // and does not redraw the datepicker on every selectDate event\r
804 //#############################################################################################\r
805 $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;\r
806 $.datepicker._updateDatepicker = function(inst) {\r
808         // don't popup the datepicker if there is another instance already opened\r
809         var input = inst.input[0];\r
810         if($.datepicker._curInst &&\r
811            $.datepicker._curInst != inst &&\r
812            $.datepicker._datepickerShowing &&\r
813            $.datepicker._lastInput != input) {\r
814                 return;\r
815         }\r
817         if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {\r
818                                 \r
819                 this._base_updateDatepicker(inst);\r
820                 \r
821                 // Reload the time control when changing something in the input text field.\r
822                 var tp_inst = this._get(inst, 'timepicker');\r
823                 if(tp_inst) tp_inst._addTimePicker(inst);\r
824         }\r
825 };\r
827 //#######################################################################################\r
828 // third bad hack :/ override datepicker so it allows spaces and colon in the input field\r
829 //#######################################################################################\r
830 $.datepicker._base_doKeyPress = $.datepicker._doKeyPress;\r
831 $.datepicker._doKeyPress = function(event) {\r
832         var inst = $.datepicker._getInst(event.target),\r
833                 tp_inst = $.datepicker._get(inst, 'timepicker');\r
835         if (tp_inst) {\r
836                 if ($.datepicker._get(inst, 'constrainInput')) {\r
837                         var ampm = tp_inst._defaults.ampm,\r
838                                 dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),\r
839                                 datetimeChars = tp_inst._defaults.timeFormat.toString()\r
840                                                                 .replace(/[hms]/g, '')\r
841                                                                 .replace(/TT/g, ampm ? 'APM' : '')\r
842                                                                 .replace(/Tt/g, ampm ? 'AaPpMm' : '')\r
843                                                                 .replace(/tT/g, ampm ? 'AaPpMm' : '')\r
844                                                                 .replace(/T/g, ampm ? 'AP' : '')\r
845                                                                 .replace(/tt/g, ampm ? 'apm' : '')\r
846                                                                 .replace(/t/g, ampm ? 'ap' : '') +\r
847                                                                 " " +\r
848                                                                 tp_inst._defaults.separator +\r
849                                                                 tp_inst._defaults.timeSuffix +\r
850                                                                 (tp_inst._defaults.showTimezone ? tp_inst._defaults.timezoneList.join('') : '') +\r
851                                                                 dateChars,\r
852                                 chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);\r
853                         return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);\r
854                 }\r
855         }\r
856         \r
857         return $.datepicker._base_doKeyPress(event);\r
858 };\r
860 //#######################################################################################\r
861 // Override key up event to sync manual input changes.\r
862 //#######################################################################################\r
863 $.datepicker._base_doKeyUp = $.datepicker._doKeyUp;\r
864 $.datepicker._doKeyUp = function (event) {\r
865         var inst = $.datepicker._getInst(event.target),\r
866                 tp_inst = $.datepicker._get(inst, 'timepicker');\r
868         if (tp_inst) {\r
869                 if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) {\r
870                         try {\r
871                                 $.datepicker._updateDatepicker(inst);\r
872                         }\r
873                         catch (err) {\r
874                                 $.datepicker.log(err);\r
875                         }\r
876                 }\r
877         }\r
879         return $.datepicker._base_doKeyUp(event);\r
880 };\r
882 //#######################################################################################\r
883 // override "Today" button to also grab the time.\r
884 //#######################################################################################\r
885 $.datepicker._base_gotoToday = $.datepicker._gotoToday;\r
886 $.datepicker._gotoToday = function(id) {\r
887         this._base_gotoToday(id);\r
888         this._setTime(this._getInst($(id)[0]), new Date());\r
889 };\r
891 //#######################################################################################\r
892 // Disable & enable the Time in the datetimepicker\r
893 //#######################################################################################\r
894 $.datepicker._disableTimepickerDatepicker = function(target, date, withDate) {\r
895         var inst = this._getInst(target),\r
896         tp_inst = this._get(inst, 'timepicker');\r
897         $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\r
898         if (tp_inst) {\r
899                 tp_inst._defaults.showTimepicker = false;\r
900                 tp_inst._updateDateTime(inst);\r
901         }\r
902 };\r
904 $.datepicker._enableTimepickerDatepicker = function(target, date, withDate) {\r
905         var inst = this._getInst(target),\r
906         tp_inst = this._get(inst, 'timepicker');\r
907         $(target).datepicker('getDate'); // Init selected[Year|Month|Day]\r
908         if (tp_inst) {\r
909                 tp_inst._defaults.showTimepicker = true;\r
910                 tp_inst._addTimePicker(inst); // Could be disabled on page load\r
911                 tp_inst._updateDateTime(inst);\r
912         }\r
913 };\r
915 //#######################################################################################\r
916 // Create our own set time function\r
917 //#######################################################################################\r
918 $.datepicker._setTime = function(inst, date) {\r
919         var tp_inst = this._get(inst, 'timepicker');\r
920         if (tp_inst) {\r
921                 var defaults = tp_inst._defaults,\r
922                         // calling _setTime with no date sets time to defaults\r
923                         hour = date ? date.getHours() : defaults.hour,\r
924                         minute = date ? date.getMinutes() : defaults.minute,\r
925                         second = date ? date.getSeconds() : defaults.second;\r
927                 //check if within min/max times..\r
928                 if ((hour < defaults.hourMin || hour > defaults.hourMax) || (minute < defaults.minuteMin || minute > defaults.minuteMax) || (second < defaults.secondMin || second > defaults.secondMax)) {\r
929                         hour = defaults.hourMin;\r
930                         minute = defaults.minuteMin;\r
931                         second = defaults.secondMin;\r
932                 }\r
934                 tp_inst.hour = hour;\r
935                 tp_inst.minute = minute;\r
936                 tp_inst.second = second;\r
938                 if (tp_inst.hour_slider) tp_inst.hour_slider.slider('value', hour);\r
939                 if (tp_inst.minute_slider) tp_inst.minute_slider.slider('value', minute);\r
940                 if (tp_inst.second_slider) tp_inst.second_slider.slider('value', second);\r
942                 tp_inst._onTimeChange();\r
943                 tp_inst._updateDateTime(inst);\r
944         }\r
945 };\r
947 //#######################################################################################\r
948 // Create new public method to set only time, callable as $().datepicker('setTime', date)\r
949 //#######################################################################################\r
950 $.datepicker._setTimeDatepicker = function(target, date, withDate) {\r
951         var inst = this._getInst(target),\r
952                 tp_inst = this._get(inst, 'timepicker');\r
954         if (tp_inst) {\r
955                 this._setDateFromField(inst);\r
956                 var tp_date;\r
957                 if (date) {\r
958                         if (typeof date == "string") {\r
959                                 tp_inst._parseTime(date, withDate);\r
960                                 tp_date = new Date();\r
961                                 tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second);\r
962                         }\r
963                         else tp_date = new Date(date.getTime());\r
964                         if (tp_date.toString() == 'Invalid Date') tp_date = undefined;\r
965                         this._setTime(inst, tp_date);\r
966                 }\r
967         }\r
969 };\r
971 //#######################################################################################\r
972 // override setDate() to allow setting time too within Date object\r
973 //#######################################################################################\r
974 $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;\r
975 $.datepicker._setDateDatepicker = function(target, date) {\r
976         var inst = this._getInst(target),\r
977         tp_date = (date instanceof Date) ? new Date(date.getTime()) : date;\r
979         this._updateDatepicker(inst);\r
980         this._base_setDateDatepicker.apply(this, arguments);\r
981         this._setTimeDatepicker(target, tp_date, true);\r
982 };\r
984 //#######################################################################################\r
985 // override getDate() to allow getting time too within Date object\r
986 //#######################################################################################\r
987 $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;\r
988 $.datepicker._getDateDatepicker = function(target, noDefault) {\r
989         var inst = this._getInst(target),\r
990                 tp_inst = this._get(inst, 'timepicker');\r
992         if (tp_inst) {\r
993                 this._setDateFromField(inst, noDefault);\r
994                 var date = this._getDate(inst);\r
995                 if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second);\r
996                 return date;\r
997         }\r
998         return this._base_getDateDatepicker(target, noDefault);\r
999 };\r
1001 //#######################################################################################\r
1002 // override parseDate() because UI 1.8.14 throws an error about "Extra characters"\r
1003 // An option in datapicker to ignore extra format characters would be nicer.\r
1004 //#######################################################################################\r
1005 $.datepicker._base_parseDate = $.datepicker.parseDate;\r
1006 $.datepicker.parseDate = function(format, value, settings) {\r
1007         var date;\r
1008         try {\r
1009                 date = this._base_parseDate(format, value, settings);\r
1010         } catch (err) {\r
1011                 // Hack!  The error message ends with a colon, a space, and\r
1012                 // the "extra" characters.  We rely on that instead of\r
1013                 // attempting to perfectly reproduce the parsing algorithm.\r
1014                 date = this._base_parseDate(format, value.substring(0,value.length-(err.length-err.indexOf(':')-2)), settings);\r
1015         }\r
1016         return date;\r
1017 };\r
1019 //#######################################################################################\r
1020 // override options setter to add time to maxDate(Time) and minDate(Time)\r
1021 //#######################################################################################\r
1022 $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;\r
1023 $.datepicker._optionDatepicker = function(target, name, value) {\r
1024         this._base_optionDatepicker(target, name, value);\r
1025         var inst = this._getInst(target),\r
1026                 tp_inst = this._get(inst, 'timepicker');\r
1027         if (tp_inst) {\r
1028                 //Set minimum and maximum date values if we have timepicker\r
1029                 if(name==='minDate') {\r
1030                 if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date)\r
1031                                 tp_inst._defaults.minDateTime = new Date(value);\r
1032                         if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date)\r
1033                                 tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());\r
1034                         tp_inst._limitMinMaxDateTime(inst,true);\r
1035                 }\r
1036                 if(name==='maxDate') {\r
1037                         if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date)\r
1038                                 tp_inst._defaults.maxDateTime = new Date(value);\r
1039                         if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date)\r
1040                                 tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());\r
1041                         tp_inst._limitMinMaxDateTime(inst,true);\r
1042                 }\r
1043         }\r
1044 };\r
1046 //#######################################################################################\r
1047 // jQuery extend now ignores nulls!\r
1048 //#######################################################################################\r
1049 function extendRemove(target, props) {\r
1050         $.extend(target, props);\r
1051         for (var name in props)\r
1052                 if (props[name] === null || props[name] === undefined)\r
1053                         target[name] = props[name];\r
1054         return target;\r
1057 $.timepicker = new Timepicker(); // singleton instance\r
1058 $.timepicker.version = "0.9.6";\r
1060 })(jQuery);\r