2 * jQuery UI Timepicker 0.2.1
4 * Copyright (c) 2009 Martin Milesich (http://milesich.com/)
7 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
9 * $Id: timepicker.js 28 2009-08-11 20:31:23Z majlo $
19 * Extending default values
21 $.extend($.datepicker._defaults, {
22 'dateFormat': 'yy-mm-dd',
25 'stepSeconds': 1, // Number of seconds to step up/down
26 'stepMinutes': 1, // Number of minutes to step up/down
27 'stepHours': 1, // Number of hours to step up/down
28 'time24h': false, // True if 24h time
29 'showTime': false, // Show timepicker with datepicker
30 'altTimeField': '', // Selector for an alternate field to store time into
32 'minuteText': 'Minute',
33 'secondText': 'Second'
35 $.extend($.datepicker.regional[''], {
37 'minuteText': 'Minute',
38 'secondText': 'Second'
42 * _hideDatepicker must be called with null
44 $.datepicker._connectDatepickerOverride = $.datepicker._connectDatepicker;
45 $.datepicker._connectDatepicker = function(target, inst) {
46 $.datepicker._connectDatepickerOverride(target, inst);
48 // showButtonPanel is required with timepicker
49 if (this._get(inst, 'showTime')) {
50 inst.settings['showButtonPanel'] = true;
53 var showOn = this._get(inst, 'showOn');
55 if (showOn == 'button' || showOn == 'both') {
56 // Unbind all click events
57 inst.trigger.unbind('click');
59 // Bind new click event
60 inst.trigger.click(function() {
61 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == target)
62 $.datepicker._hideDatepicker(null); // This override is all about the "null"
64 $.datepicker._showDatepicker(target);
71 * Datepicker does not have an onShow event so I need to create it.
72 * What I actually doing here is copying original _showDatepicker
73 * method to _showDatepickerOverload method.
75 $.datepicker._showDatepickerOverride = $.datepicker._showDatepicker;
76 $.datepicker._showDatepicker = function (input) {
77 // Call the original method which will show the datepicker
78 $.datepicker._showDatepickerOverride(input);
80 input = input.target || input;
82 // find from button/image trigger
83 if (input.nodeName.toLowerCase() != 'input') input = $('input', input.parentNode)[0];
85 // Do not show timepicker if datepicker is disabled
86 if ($.datepicker._isDisabledDatepicker(input)) return;
88 // Get instance to datepicker
89 var inst = $.datepicker._getInst(input);
91 var showTime = $.datepicker._get(inst, 'showTime');
93 // If showTime = True show the timepicker
94 if (showTime) $.timepicker.show(input);
98 * Same as above. Here I need to extend the _checkExternalClick method
99 * because I don't want to close the datepicker when the sliders get focus.
101 $.datepicker._checkExternalClickOverride = $.datepicker._checkExternalClick;
102 $.datepicker._checkExternalClick = function (event) {
103 if (!$.datepicker._curInst) return;
104 var $target = $(event.target);
106 if (($target.parents('#' + $.timepicker._mainDivId).length == 0)) {
107 $.datepicker._checkExternalClickOverride(event);
112 * Datepicker has onHide event but I just want to make it simple for you
113 * so I hide the timepicker when datepicker hides.
115 $.datepicker._hideDatepickerOverride = $.datepicker._hideDatepicker;
116 $.datepicker._hideDatepicker = function(input, duration) {
117 // Some lines from the original method
118 var inst = this._curInst;
120 if (!inst || (input && inst != $.data(input, PROP_NAME))) return;
122 // Get the value of showTime property
123 var showTime = this._get(inst, 'showTime');
125 if (input === undefined && showTime) {
127 inst.input.val(this._formatDate(inst));
128 inst.input.trigger('change'); // fire the change event
131 this._updateAlternate(inst);
133 if (showTime) $.timepicker.update(this._formatDate(inst));
137 $.datepicker._hideDatepickerOverride(input, duration);
139 // Hide the timepicker if enabled
146 * This is a complete replacement of the _selectDate method.
147 * If showed with timepicker do not close when date is selected.
149 $.datepicker._selectDate = function(id, dateStr) {
151 var inst = this._getInst(target[0]);
152 var showTime = this._get(inst, 'showTime');
153 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
156 inst.input.val(dateStr);
157 this._updateAlternate(inst);
159 var onSelect = this._get(inst, 'onSelect');
161 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
162 else if (inst.input && !showTime)
163 inst.input.trigger('change'); // fire the change event
165 this._updateDatepicker(inst);
166 else if (!inst.stayOpen) {
168 this._updateDatepicker(inst);
170 this._hideDatepicker(null, this._get(inst, 'duration'));
171 this._lastInput = inst.input[0];
172 if (typeof(inst.input[0]) != 'object')
173 inst.input[0].focus(); // restore focus
174 this._lastInput = null;
180 * We need to resize the timepicker when the datepicker has been changed.
182 $.datepicker._updateDatepickerOverride = $.datepicker._updateDatepicker;
183 $.datepicker._updateDatepicker = function(inst) {
184 $.datepicker._updateDatepickerOverride(inst);
185 $.timepicker.resize();
188 function Timepicker() {}
190 Timepicker.prototype = {
193 this._mainDivId = 'ui-timepicker-div';
194 this._inputId = null;
195 this._orgValue = null;
196 this._orgHour = null;
197 this._orgMinute = null;
198 this._orgSecond = null;
200 this._scolonPos = -1;
201 this._visible = false;
202 this.tpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible" style="width: 170px; display: none; position: absolute;"></div>');
203 this._generateHtml();
206 show: function (input)
208 // Get instance to datepicker
209 var inst = $.datepicker._getInst(input);
211 this._time24h = $.datepicker._get(inst, 'time24h');
212 this._altTimeField = $.datepicker._get(inst, 'altTimeField');
214 var stepSeconds = parseInt($.datepicker._get(inst, 'stepSeconds'), 10) || 1;
215 var stepMinutes = parseInt($.datepicker._get(inst, 'stepMinutes'), 10) || 1;
216 var stepHours = parseInt($.datepicker._get(inst, 'stepHours'), 10) || 1;
218 if (60 % stepSeconds != 0) { stepSeconds = 1; }
219 if (60 % stepMinutes != 0) { stepMinutes = 1; }
220 if (24 % stepHours != 0) { stepHours = 1; }
222 $('#hourSlider').slider('option', 'max', 24 - stepHours);
223 $('#hourSlider').slider('option', 'step', stepHours);
225 $('#minuteSlider').slider('option', 'max', 60 - stepMinutes);
226 $('#minuteSlider').slider('option', 'step', stepMinutes);
228 $('#secondSlider').slider('option', 'max', 60 - stepSeconds);
229 $('#secondSlider').slider('option', 'step', stepSeconds);
231 $('.hour_text').html($.datepicker._get(inst, 'hourText'));
232 $('.minute_text').html($.datepicker._get(inst, 'minuteText'));
233 $('.second_text').html($.datepicker._get(inst, 'secondText'));
235 this._inputId = input.id;
237 if (!this._visible) {
239 this._orgValue = $('#' + this._inputId).val();
244 $('#' + this._mainDivId).show();
246 this._visible = true;
248 var dpDiv = $('#' + $.datepicker._mainDivId);
249 var dpDivPos = dpDiv.position();
251 var viewWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) + $(document).scrollLeft();
252 var tpRight = this.tpDiv.offset().left + this.tpDiv.outerWidth();
254 if (tpRight > viewWidth) {
255 dpDiv.css('left', dpDivPos.left - (tpRight - viewWidth) - 5);
256 this.tpDiv.css('left', dpDiv.offset().left + dpDiv.outerWidth() + 'px');
260 update: function (fd)
262 var curTime = $('#' + this._mainDivId + ' span.fragHours').text()
264 + $('#' + this._mainDivId + ' span.fragMinutes').text()
266 + $('#' + this._mainDivId + ' span.fragSeconds').text()
269 if (!this._time24h) {
270 curTime += ' ' + $('#' + this._mainDivId + ' span.fragAmpm').text();
273 var curDate = $('#' + this._inputId).val();
275 $('#' + this._inputId).val(fd + ' ' + curTime);
277 if (this._altTimeField) {
278 $(this._altTimeField).each(function() { $(this).val(curTime); });
284 this._visible = false;
285 $('#' + this._mainDivId).hide();
290 var dpDiv = $('#' + $.datepicker._mainDivId);
291 var dpDivPos = dpDiv.position();
293 var hdrHeight = $('#' + $.datepicker._mainDivId + ' > div.ui-datepicker-header:first-child').height();
295 $('#' + this._mainDivId + ' > div.ui-datepicker-header:first-child').css('height', hdrHeight);
298 'height': dpDiv.height(),
299 'top' : dpDivPos.top,
300 'left' : dpDivPos.left + dpDiv.outerWidth() + 'px'
303 $('#hourSlider').css('height', this.tpDiv.height() - (3.5 * hdrHeight));
304 $('#minuteSlider').css('height', this.tpDiv.height() - (3.5 * hdrHeight));
305 $('#secondSlider').css('height', this.tpDiv.height() - (3.5 * hdrHeight));
308 _generateHtml: function ()
312 html += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix ui-corner-all">';
313 html += '<div class="ui-datepicker-title" style="margin:0">';
314 html += '<span class="fragHours">08</span><span class="delim">:</span><span class="fragMinutes">45</span>:</span><span class="fragSeconds">45</span> <span class="fragAmpm"></span></div></div><table>';
316 html += '<span class="hour_text">Hour</span>';
318 html += '<span class="minute_text">Minute</span>';
320 html += '<span class="second_text">Second</span>';
321 html += '</th></tr>';
322 html += '<tr><td align="center"><div id="hourSlider" class="slider"></div></td><td align="center"><div id="minuteSlider" class="slider"></div></td><td align="center"><div id="secondSlider" class="slider"></div></td></tr>';
325 this.tpDiv.empty().append(html);
326 $('body').append(this.tpDiv);
330 $('#hourSlider').slider({
331 orientation: "vertical",
336 slide: function(event, ui) {
337 self._writeTime('hour', ui.value);
339 stop: function(event, ui) {
340 $('#' + self._inputId).focus();
344 $('#minuteSlider').slider({
345 orientation: "vertical",
350 slide: function(event, ui) {
351 self._writeTime('minute', ui.value);
353 stop: function(event, ui) {
354 $('#' + self._inputId).focus();
358 $('#secondSlider').slider({
359 orientation: "vertical",
364 slide: function(event, ui) {
365 self._writeTime('second', ui.value);
367 stop: function(event, ui) {
368 $('#' + self._inputId).focus();
372 $('#hourSlider > a').css('padding', 0);
373 $('#minuteSlider > a').css('padding', 0);
374 $('#secondSlider > a').css('padding', 0);
377 _writeTime: function (type, value)
379 if (type == 'hour') {
380 if (!this._time24h) {
382 $('#' + this._mainDivId + ' span.fragAmpm').text('am');
384 $('#' + this._mainDivId + ' span.fragAmpm').text('pm');
388 if (value == 0) value = 12;
390 $('#' + this._mainDivId + ' span.fragAmpm').text('');
393 if (value < 10) value = '0' + value;
394 $('#' + this._mainDivId + ' span.fragHours').text(value);
397 if (type == 'minute') {
398 if (value < 10) value = '0' + value;
399 $('#' + this._mainDivId + ' span.fragMinutes').text(value);
402 if (type == 'second') {
403 if (value < 10) value = '0' + value;
404 $('#' + this._mainDivId + ' span.fragSeconds').text(value);
408 _parseTime: function ()
410 var dt = $('#' + this._inputId).val();
412 this._colonPos = dt.search(':');
414 var m = 0, h = 0, s = 0, a = '';
416 if (this._colonPos != -1) {
417 this._scolonPos = dt.substring(this._colonPos + 1).search(':');
418 h = parseInt(dt.substr(this._colonPos - 2, 2), 10);
419 m = parseInt(dt.substr(this._colonPos + 1, 2), 10);
420 if (this._scolonPos != -1) {
421 this._scolonPos += this._colonPos + 1;
422 s = parseInt(dt.substr(this._scolonPos + 1, 2), 10);
423 a = jQuery.trim(dt.substr(this._scolonPos + 3, 3));
425 a = jQuery.trim(dt.substr(this._colonPos + 3, 3));
431 if (a != 'am' && a != 'pm') {
441 if (a == 'pm' && h < 12) h += 12;
442 if (a == 'am' && h == 12) h = 0;
444 this._setTime('hour', h);
445 this._setTime('minute', m);
446 this._setTime('second', s);
453 _setTime: function (type, value)
455 if (isNaN(value)) value = 0;
456 if (value < 0) value = 0;
457 if (value > 23 && type == 'hour') value = 23;
458 if (value > 59 && type == 'minute') value = 59;
459 if (value > 59 && type == 'second') value = 59;
461 if (type == 'hour') {
462 $('#hourSlider').slider('value', value);
465 if (type == 'minute') {
466 $('#minuteSlider').slider('value', value);
469 if (type == 'second') {
470 $('#secondSlider').slider('value', value);
473 this._writeTime(type, value);
477 $.timepicker = new Timepicker();
478 $('document').ready(function () {$.timepicker.init();});