Updated for jQuery UI 1.8.5 10/30/2010
I like Maxime Haineault's timepickr. But I found it was written for jQuery 1.2, and didn't trigger events correctly with the current jQuery. It also had more dependencies than I wanted, to the extent that the minified version is 49k large, and had some CSS quirks in Internet Explorer that I couldn't figure out without dissecting the whole thing. So I dissected it and rebuilt it smaller, updated for jQuery 1.3. I didn't put back a lot of the options that I didn't need, so it's not exactly an improvement. But it works for me.
Download the code.
I also added the ability to use hoverIntent so you can roll the mouse over the intervening buttons without triggering them:
Examples
$('.timepickr-example:eq(0)').timepickr();
<input class="timepickr-example" />
$('.timepickr-example:eq(1)').timepickr({
convention: 24,
format: '{h}{m} hours',
hoverIntent: true
});
<input class="timepickr-example" />
$('.timepickr-example:eq(2)').timepickr({
trigger: 'nothing',
handle: $('#clock')
});
<input class="timepickr-example" /> <img id="clock" src="/images/clock.png" />
$('.timepickr-example:eq(3)').timepickr({
select: function(){
alert('Time is '+this.value);
}
});
<input class="timepickr-example" />
Options
- top {Number}
- Pixel offset of the top left button. Default: 6.
- left {Number}
- Pixel offset of the top left button. Default: 0.
- animSpeed {Number|slow|normal|fast}
- Speed to animate showing/hiding the buttons. Default: 0.
- trigger {String}
- Event to trigger showing the buttons. Default: 'click'.
- convention {12|24}
- Whether to use a 12-hour or 24-hour clock. Default: 12.
- format {String}
- String that determines how to display the time. Uses simple formatting: '{h}' is replaced by the hour;
'{m}' is replaced by the minutes; '{suffix}' is replaced by the suffix (used in the 12-hour clock); '{prefix}' is
replaced by the prefix (used in the 24-hour clock). Default: '{h}:{m} {suffix}'
- handle {false|String|jQuery object}
- Other element that will trigger showing the buttons when clicked. If handle is not false, then
$(handle).click() shows the buttons. Default: false.
- prefix {Array(String)}
- Strings to use as labels for the 24-hour clock. Displaying all 24 hours is too long to be usable, so we
split them into two halves. Default: ['00-11', '12-23'].
- suffix {Array(String)}
- Strings to use as AM/PM labels for the 12-hour clock. Default: ['am', 'pm'].
- rangeMin {Array(String)}
- Values to use for the minutes list. Default: ['00', '15', '30', '45'].
- resetOnBlur {Boolean}
- True to reset the element to its original value if nothing is clicked; false to keep the value generated
by the mouseover even if not clicked. Default: true.
- val {false|String}
- If not false, value to assign to the element when the buttons are shown. Default: false.
- hoverIntent {Boolean}
- True to use the hoverIntent plugin if available. Note that timepickr does not provide any way to
adjust the hoverIntent paramenters. Default: false.
- select {undefined|function}
- Callback function, called when the time buttons are clicked. Also available as an event
'timepickrselect'





{ 68 } Comments
Awesome. I just found timepickr a few days ago but this improvement is really impressive.
I tried it and as it is a lot smaller than the original one, I could also much easier add a few changes.
I think they are interesting for others as well, so I’ll post them here:
- if you add “left: this.element.position().left” after “zIndex: 1000″ in “show”, the elements are displayed correctly under the element also at first time. Some browser would initially display it at the very left border.
- in Arora (webkit based browser) all buttons are displayed below each other. To fix this one as to add a width-setting to “.ui-timepickr ol”. I used width:500px, which worked fine in my tests.
Thanks again for this and I hope you like my few suggestions!
@pprkut:
Thanks for your suggestions. I haven’t had the CSS problems you mention, but I’m only testing in the big four (IE, FF, Safari, Chrome). It’s nice to see people looking at this in other browsers!
–Danny
Thanks for this; exactly what I needed.
Found one issue for this plugin. I’m using this with an asp:textbox (as I do with the datepicker), but it doesn’t fire the onchange event in such a way that it causes a partial postback as the datepicker enhanced control does (I’m using this inside an UpdatePanel with AJAX Toolkit). Any idea what might be causing the difference in behavior?
I’ve never used ASP widgets so I really can’t tell what’s going on, but textboxes do not trigger the onchange event until they lose focus. the timepickr may not be doing that the way you expect. It should trigger the custom event “timepickrselect” on the textbox, though.
Thanks for doing this, much smaller and much easier to tweak to my needs. I did have to make both changes pprkut suggested above, but in my case I used “left: this.element.position().left + this.options.left” in the show method so that it would show up at the correct offset position the first time.
Michael – Though I don’t know for sure what the issue is, check and see if the datepicker is manually calling blur() on the textbox where timepickr isn’t.
If the timepickr is inside a table tag with more than one column, the numbers wrap around (how much they wrap around depends on the width/number of columns). Do you have a suggestion as to how to let the column overlap the proceeding columns so that this doesn’t happen?
I thank you for the code and your time.
R/
@Erica:
I use timepickr in a table at bililite.com/bililite (bottom left table), without any wrap around problems. Can you post a link to your page?
Wrap-around happens when the window isn’t wide enough to accomodate the numbers; I want that effect so the user doesn’t need to scroll. If you want to change it, try adding
width: 9999pxto the'.ui-timepickr {position:absolute; text-align: left; } 'line. You may have to play with the width (and make it in em’s rather than px) to avoid a huge scrollbar.–Danny
Hello,
I’m trying to use timepickr inside a jquery ui dialog. However, I’m heving a couple of issues:
First, the number boxes wrap around to the width of the dialog. If I set width: 9999px as described in the comment above, they don’t wrap anymore but the ones that don’t fit the dialog, get hidden instead of showing over the dialog edge.
Any help will be appreciated
@Mario:
You probably need to set the dialog to have
overflow: visibleto make sure it all shows. I think the jQuery UI show/hide effects set overflow to hidden, so you may have to reset it after the dialog is shown. I’ve never played with the dialog widget, so I’m not sure.–Danny
Hi Guys,
I’m having some problems with this control. After getting the original version to work, I simply replaced this new jquery-timepickr.js over the old one and firebug doesn’t like it. It says “$.widget is not a function”. Anybody else getting this?
@Jonathan:
$.widget is part of jQuery UI. You have to include it for this version to work. You could just copy the $.widget code and not include the whole thing.
–Danny
Hello,
thanks to Maxime and you for providing such a nice plugin. But could you precise, for newbies as me, exactly what files (js scripts, css files) we should download, where we should place them and a complete example?
Thanks in advance.
@Denis:
You need to include the jQuery UI code (see jqueryui.com. The easiest way to do that is to include the following in your <head> section:
and copy the timepickr (from http://bililite.com/inc/jquery.timepickr.js to your server and include it. No additional CSS is needed. For complete examples, see this page or http://bililite.com/bililite
–Danny
Greetings,
none of the examples are working for me.
they are upside down (hours, minutes, then am/pm) and do not update the field properly
@Brian:
Hmm. The order is correct (hours, minutes, then AM/PM is what I want), but it’s not working for me either. I’ll try to take a look at it.
–Danny
@Brian:
Solved.
Thanks for picking this up (as a matter of practical advice, there’s nothing better for solving a mysterious bug than a few minutes on the treadmill. Thinking about anything is better than staring at the walls).
Seems that jQuery 1.4 improved the
addmethod to sort the elements:$(selector1).add(selector2)used to return[selector1, selector2]but now the two items are in the order they appear in the DOM.I was doing something like
$('.hour.hover', menu).add('.hour',menu).eq(0).text()to get the hovered-over item, and if nothing was being hovered-over, then the first item in the list. I changed it toelem = $('.hour.hover', menu)[0] || $('.hover', menu)[0]; $(elem).text()and it now works.–Danny
@Danny
Looks good thanks
I swim
I am trying to change the configuration, something like:
12 hour
24 hour
I have tried many combinations: reset, destroy, … once the timepickr is initialized, I cannot change the configuration without a page reload
@Brian:
$(...).timepickr('destroy').timepickr({convention: 12});Basically, destroy the old time picker and create a new one.
Let me know if it doesn’t work.
–Danny
@Danny
I have tried MANY variations
please look at my example which seems too simple to fail
@Brian:
I should hire you for bug testing! (Salary starts at $0 an hour and doubles weekly).
It was a dumb copy/paste error that left two versions of the destroy method, the last of which was wrong. All should be working now.
–Danny
@Danny
yes, exactly thanks
good spotting
@Danny
timepickr seems to be eating the change event. $(aField).change works fine when I also attach timepickr $(aField).timepickt(…) the change event does not trigger
Brian
@Danny
I added an explicit trigger change to the hide function – seems to be working
great widget!!!
Brian
Is it me, or are the defaults not respected? I did something like this:
$(‘.timepicker’).timepickr({convention: 12, rangeMin: ['00', '15', '30', '45', '59'], suffix: ['AM', 'PM'] });
And I noticed that the select was not being respected, after I added that in, the line of code that deals with formats was throwing errors. Everything works if I explicitly specify the defaults for everything.
Also, I noticed that the menu’s don’t follow the mouse as was the previous design. I am assuming this was removed intentionally?
Thanks!
With respect to the above comment, I noticed that another one of the plugins I am using is not respecting defaults either. My guess is that this is related to jquery 1.4.2 (just upgrades), but I have to dig a bit deeper.
@Arash:
I see what you mean by the menu not following the mouse. I wonder what’s going on. I use the most recent jQuery and jQuery UI from google, so if they upgrade, then something might break without me realizing it. I’ll look into it when I get the chance.
–Danny
@Arash:
Now I see it; it’s the same bug as the one I fixed in this comment; jQuery 1.4 changed the way it implements
add. Since this bug was just visual, it didn’t “bug” me and I didn’t notice it. It has been corrected.–Danny
Thanks for the quick fix Danny. Do you have any idea why the defaults are not applied as I mentioned previously?
I was worried that maybe it was a result of some of my code, so I created a simple test case by downloading jquery 1.4.2 and jquery-ui 1.8.3, and I get the same result.
You can see it here: http://test.lambandtunafish.com/timepickr/test.html
If you look at the source, the commented out portion of code works fine, but the one without all the options specified does not.
I still haven’t gotten a chance to debug, but if I get some free time, I will look into it.
Thanks.
@Arash:
I don’t get anything when I click on the input box in your test page. Setting the options works on my demo page; I’m not sure what’s going on in your code. Can you rub it with Firebug on to see if there are any obvious errors?
–Danny
@Danny
Thats the problem, if you look at the source, I specify the timepickr with only a few options, and it doesn’t work, but if I specify with all of the options, everything works.
To be more clear, the script looks as such:
/*
$(‘.timepicker’).timepickr({convention: 12,
top: 6,
left: 0,
animSpeed: 3,
format: ‘{h}:{m} {suffix}’,
handle: false,
prefix: ['00-11', '12-23'],
resetOnBlur: true,
val: false,
hoverIntent: false,
trigger: ‘click’, rangeMin: ['00', '15', '30', '45', '59'], suffix: ['AM', 'PM']
});
*/
$(‘.timepicker’).timepickr({convention: 12, rangeMin: ['00', '15', '30', '45', '59'], suffix: ['AM', 'PM'] });
Note: The commented out portion (when uncommented) works fine, however, the current uncommented portion fails to load the timepickr.
I created this base case so that I was sure no other javascript was messing with it. You can download the full sample here: http://test.lambandtunafish.com/timepickr/timepickr.zip
@Arash:
I’m getting an “illegal character” error in IE, and an “Error in parsing value for ‘left’” error in Firefox. Try using the uncompressed jQuery and jQuery UI and see if you still get the error, and if so, where it is.
–Danny
@Danny
Firefox wasn’t throwing errors for me, but I was able to generate the error in IE8. After walking through the stack, it comes back to the fact that the default options are not applied. in this case, it was trying to access ‘this.options.top’ which I did not set when creating the timepickr, and as a result it threw an error.
If you put a breakpoint at line 28 of jquery.timepickr.js, you will see that not none of the default options are applied.
Everything that I have read indicates that the defaults are being set correctly by specifying them as: ‘$.ui.timepickr.defaults’, so this could be a bug with the latest jquery ui.
@Arash:
Aha! That’s the problem: jQuery UI changed the way it names defaults in 1.8. I’m using the release version as served by Google Ajax Apis, which is 1.7.2. When 1.8 is official, I’ll have to go back and redo all my plugins, but for now, I’m leaving them as they are. I don’t know why they had to change things.
If you go back to 1.7.2, I think everything should work.
–Danny
@Danny
yup…that was it, the following change was needed in the timepickr.js:
$.ui.timepickr.defaults -> $.ui.timepickr.prototype.options
@Arash:
The change has been made. Thanks for following this so closely!
–Danny
Thanks for the simple, but useful widget.
Like post #7, I also see a problem with the numbers wrapping if timepickr is inside a table. This only happens in IE (firefox + chrome are OK).
Example here: http://www.srlee.com/tptest.html
@Stephen:
Life is finite. IE formatting issues with tables are infinite. If you can find a good solutions (I suspect the right CSS magic would do the trick), I would be grateful, but I can’t fix it now.
–Danny
Hey, thanx for updating timepickr to jq.ui 1.8! It’s really great!
But i had problems displaying it when the width of parent container was limited: instead of beautiful row of hours i got a phone keypad, 3×4 =)
So i made a little improvement, which made it work as i desired.
in _init() insert menu not to this.element, but to body:
var menu = this.menu = ui._buildMenu().insertAfter($(document.body));
in _show() use this.element.offset() to determine absolute position:
this.menu.css({
top: this.element.position().top + this.element.height() + this.options.top + this.element.offset().top,
left: this.element.offset().left,
zIndex: 1000
});
and in _redraw do the same:
this.menu.css({
top: this.element.position().top + this.element.height() + this.options.top + this.element.offset().top,
left: this.options.left + this.element.offset().left
});
Hope this helps someone!
Minor bug:
With this setting:
convention: 24,
trigger: ‘focus’,
rangeMin: ['00','05','10','15','20','25','30','35','40','45','50','55']
I get an extra space after: 01:00 <– Extra space.
Problem can be solved with:
format: '{h}:{m}',
@Mike:
Are you using Internet Explorer? That’s the browser that gives problems for some fixed-width parents. I’ll take a look at your code; it would be nice to have a fix.
–Danny
@Jakob:
You are right; I’m not sure if I would call it a bug, since it is the expected behavior (default format is ‘{h}:{m} {suffix}’) and yes, your answer is the correct one: set the format to what you want. Most 24-hour times are written as
format: '{h}{m}'without the colon.–Danny
Hi!
Good job! Cool modification of JQuery plugin.
What is the minimal custom UI config to have it working? It works fine with full UI bundle and does not work with Core only. May be it is possible to have just couple of components selected?
Thanks!
@Alticast:
I don’t know what the minimal UI would be; I load the full jQuery UI in my page. I would have thought that all it needs is the widget code (in jquery.ui.widget.js) though I haven’t tested it.
–Danny
Danny, thanks for updating this plugin. But I can’t get it to work. I’m using jquery 1.3.2 with ui 1.7.2 on firefox. Here is what I have:
$(‘input:last’).timepickr({hoverIntent: true})
In Firebug this gives me: “object is undefined”, in jquery-1.3.2.js on line 672
Any ideas?
Regarding my previous post. Of course html was stripped, here is what I include in the head section (in that order):
jquery-1.3.2.js
jquery-ui-1.7.3.custom.min.js
jquery.timepickr.js
jquery.hoverIntent.js
@Thomas:
I’ve updated the code to use jQuery 1.4 and jQuery UI 1.8; you may want to update as well.
–Danny
Thanks for a wonderful job with this plugin!
I have encountered a problem though, when checking the examples on this page, I’ve noticed that the CSS class “ui-state-hover” doesn’t get removed when you move the mouse outside the element. But when using the same code on my site, the “ui-state-hover” disappears, making the plugin select the value of the first . Do you have any idea how to fix this?
@Peter Nguyen:
I’m not sure. The code only removes the ui-state-hover when hovering over a different element (and applies it to that element immediately), not when moving off the timepickr entirely. Are you manipulating ui-state-hover in any other way?
–Danny
I am trying to use the ‘val’ parameter and passing it a legitimate value (05:30 pm). This is being parsed in the init function but the first time the timepickr is displayed it does not reflect this time.
Subsequent times do reflect whatever time was selected but I assume this is because the ui-state-hover class was set with the hover and not removed. I have not been able to figure out where in the code this class is meant to set on init.
Any ideas?
@Zev:
the code in
_initisif (this.options.val) {
element.val(this.options.val);
}
so it should just set the value of the text box; it does not affect the display of the timepickr itself. Doing that is much more complicated; it would involve parsing the value and figuring out which buttons to hilight. This plugin, while acting sophisticated, is far more simple. Sorry about that, but if you’ve got the time, feel free to implement this improvement!
–Danny
You sir are the bestest ever. I wanted this plugin so much for my project but it was not compatible with any jQuery I had in stalled. Thank you. You are a project saver err… you know what I mean.
Are you planning to push this back to the main timepickr project or continue this as a fork? Has it been saved off into a public repo like github or google code something like that? If not should it be? I’d be happy to facilitate that if needed (github).
Thanks again.
@Sukima:
Thanks for the postive feedback. I don’t have plans to put this on a public repository; I have minimal experience with that. It’s under an MIT open-source license, so feel free to set up a github repository. Please let me know if you do.
–Danny
thanks for this plugin, your the best..
the older version works with jquery-ui-1.7.3 fine but this one dosent work for me.
I have a prob. this version dosn’t work with jquery-ui-1.8.4.. i dont t know why!? i have loaded the folowing scripts and stylsheets.. i’m using the datepicker too but in 2 diffenet input fields.
can anyone help me
which scripts and css do i have to load!??
Thankyou
jquery-ui-1.8.4.custom.css
jquery-1.4.2.js
jquery.ui.widget.js
jquery-ui-1.8.4.custom.js
jquery.timepickr.js
Wonderful! I really liked the inferface of timepickr, but could not get it working for jQuery 1.4/I 1.8. Your rewrite just did the work!!
Hello Danny!
First of all, great job. This plugin is wonderful. thanks a lot for the refactoring.
I have a couple of questions for you.
#1 – I have just included the js file and everything is working perfectly except the fact that when I click on one of the hour/minute boxes they dont disappear. What am I missing?
#2 – Is there a way to restrict the range of selectable hours? let’s say for example from 9:00 to 19:00.
Thanks Again
Does not work with 1.8.5
For all those who can’t get it to work with jQuery UI 1.8.5, I’m not sure what the problem might be. It seems to be working for me, using the most recent version that google is serving, which is 1.8.5.
Does anyone have any more details?
–Danny
@Vincenzo:
There’s no way to limit the range of hours as the plugin is currently written, but you could modify it: change the
_getRanges12or_getRanges24functions to just the hours you want, then change the linesin
_redrawto select the appropriate hours.Hope this helps,
Danny
Hello @Mario / @Danny
I have found some problems combining this with a jQuery dialog. This little change does the work for me:
From:
if (this.options.resetOnBlur) {
menu.find(‘li’).bind(‘mousedown.timepickr’, function() {
element.data(‘timepickr.initialValue’, element.val());
});
}
to:
if (this.options.resetOnBlur) {
menu.find(‘li’).bind(‘mousedown.timepickr’, function() {
element.data(‘timepickr.initialValue’, element.val());
ui.hide(); //Add this line
});
}
Hope this helps to anyone who may need it.
Regards.
@Lucas:
Thanks! I don’t use ui.dialog, but others may find this useful.
Danny
Update the timepickr once again – http://github.com/hasokeric/jquery-timepickr/blob/master/jquery.timepickr.js
@Haso:
I assume you updated the code for jQuery UI 1.8.5, though I can’t see any differences just glancing through the code. What changes did you make?
–Danny
It was minor changes the widget failed to destroy itself and cause a js error because apparently in 1.4.3 they changed the way this should be done… But ill keep improving it of course.. i also moved CSS stuff from .js to .css
keep an eye on it.. and contribute
@Haso Keric:
Ah, got it. They created a real base class called $.Widget, so you had to change $.widget.prototype to $.Widget.prototype.
I updated my code; thanks!
I kept the CSS stuff in the .js file so I could keep it all in one file, though your approach is of course the correct one.
–Danny
Hey Danny, great work here getting this updated for the newest jQuery/UI. I have a patch to your redo I’d like to submit back to you, it fixes some problems binding to blur to close the timepicker if trigger is set to something other than “click”, fixes a problem if the field does not have a value when the timepicker is instantiated but has a value when it is first shown, and finally fixes an issue I was seeing with the minutes row being shifted left in 24 hour mode whenever looking at hours 12-23. Could you get back to me with an address I can mail this to?
Thanks,
Shane
This time picker functionality seems to be exactly what I need.
However, it must be because I’m new to jQuery but I cannot get this to work. It’s so frustrating. I was using the old timepickr but I really want to use this one.
Here is my code:
$(function(){
$(‘#timestart’).timepickr({
trigger: ‘focus’
});
});
Am I referencing the field in the wrong manner? That’s how I call timepickr from the original site and it works. It doesn’t seem to work in this case. I am calling jquery-ui and everything.
Thanks in advance for any tips and/or advice.
@Lucas:
That looks right. Can you put up a page with your code and I’ll try to look at it? Try it without the
triggeroption as well.–Danny
Post a Comment