Skip to content

Updating timepickr

Updated code 2/14/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'

{ 24 } Comments

  1. pprkut | July 19, 2009 at 9:38 am | Permalink

    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!

  2. Danny | July 20, 2009 at 11:37 am | Permalink

    @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

  3. michael | July 23, 2009 at 5:21 pm | Permalink

    Thanks for this; exactly what I needed.

  4. michael | July 23, 2009 at 5:24 pm | Permalink

    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?

  5. Danny | July 23, 2009 at 6:52 pm | Permalink

    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.

  6. Nathan | July 26, 2009 at 4:11 pm | Permalink

    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.

  7. Erica | August 11, 2009 at 2:59 pm | Permalink

    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/

  8. Danny | August 14, 2009 at 4:09 pm | Permalink

    @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: 9999px to 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

  9. Mario | August 24, 2009 at 1:05 pm | Permalink

    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

  10. Danny | August 27, 2009 at 11:00 am | Permalink

    @Mario:
    You probably need to set the dialog to have overflow: visible to 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

  11. Jonathan | September 24, 2009 at 1:52 am | Permalink

    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?

  12. Danny | September 25, 2009 at 3:33 am | Permalink

    @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

  13. Denis | December 9, 2009 at 6:16 am | Permalink

    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.

  14. Danny | December 12, 2009 at 11:19 pm | Permalink

    @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:

    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/smoothness/jquery-ui.css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" <>/script>

    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

  15. Brian | February 13, 2010 at 12:44 pm | Permalink

    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

  16. Danny | February 13, 2010 at 9:32 pm | Permalink

    @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

  17. Danny | February 14, 2010 at 12:17 am | Permalink

    @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 add method 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 to elem = $('.hour.hover', menu)[0] || $('.hover', menu)[0]; $(elem).text() and it now works.
    –Danny

  18. Brian | February 14, 2010 at 12:31 am | Permalink

    @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

  19. Danny | February 14, 2010 at 12:58 am | Permalink

    @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

  20. Brian | February 14, 2010 at 1:13 am | Permalink

    @Danny

    I have tried MANY variations :(

    please look at my example which seems too simple to fail

  21. Danny | February 14, 2010 at 1:31 am | Permalink

    @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

  22. Brian | February 14, 2010 at 1:45 am | Permalink

    @Danny

    yes, exactly thanks

    good spotting

  23. Brian | February 17, 2010 at 12:57 am | Permalink

    @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

  24. Brian | February 18, 2010 at 1:17 pm | Permalink

    @Danny

    I added an explicit trigger change to the hide function – seems to be working

    great widget!!!
    Brian

Post a Comment

Your email is never published nor shared. Required fields are marked *