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();});