Code Play a software blog by tim benke

Prettifying forms with jQuery UI

I’m still adding little features and working on the design of my lunch organizer app. I’ve added nice javascript widgets for handling the input of dates and times. jQuery UI is a nice library that is the UI extension of the excellent jQuery library. Among many other things it features a very nice widget for picking dates:

</a>

Although the HTML5 input type “date” hopefully brings us the functionality with simple HTML, we have to settle for this version for now (only Opera displays a special widget for the “date”-type). Unfortunately there’s no default widget for time fields in jQuery UI. I’m not sure why that is so. Maybe it’s selection process is a bit slow? I’ve looked at a number of widgets for choosing time and it’s very refreshing to see how many interesting approaches have been invented for this:

</a>

In the end I chose the excellent widget by François Gélinas.

When you download jQuery UI, you can pick and choose which functionality you need. There’s a simple form, so you can minimize the size of the scripts each user has to download. The full package is over 1MB, thus this is really necessary. The simple selection with the datepicker and the position library is only 75KB (+25 KB for the images). The timepicker weighs in at an additional 60KB, which should still be tolerable.

The default size of the datepicker is much too big and it’s not very obvious how you can reduce it. Fortunately the always helpful stackoverflow comes to the rescue. Add this simple style to your stylesheet and you will get nicely size date widgets:

div.ui-datepicker {
    font-size: 75%;
}

The same technique works for the timepicker:

div.ui-timepicker {
    font-size: 75%;
}

The next problem I had with these widgets were their default positions. Their default is just below the input field at its lower left corner. That way the datepicker covers the rest of the form and lowers the user experience. Of course there’s a stackoverflow page that helps with that, too:

$("#id_date").datepicker({ 
    dateFormat: "yy-mm-dd", 
    beforeShow: function(input, inst) {
        inst.dpDiv.css({marginTop: - input.offsetHeight + 'px', marginLeft: input.offsetWidth + 2 + 'px'});
    } 
});

For the timepicker there’s not such an easy way, but it has two position attributes that let me achieve the same effect (at least in Chrome):

    $("#id_time").timepicker({ 
    showPeriodLabels : false, 
    myPosition: 'right bottom', 
    atPosition: 'left bottom', 
    hours: { starts: 11, ends: 14 }
});

When using the datepicker with Django, I had to make use Django’s id format. It’s always “id_". Thus it was id_time for the field time. Of course I also had to add the stylesheets and the css elements to the head element:

    <link type="text/css" href="/media/css/ui-lightness/jquery-ui-1.8.20.custom.css" rel="stylesheet" />	
    <script type="text/javascript" src="/media/js/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="/media/js/jquery-ui-1.8.20.custom.min.js"></script>
    <link type="text/css" href="/media/css/jquery.ui.timepicker.css" rel="stylesheet" />
    <script type="text/javascript" src="/media/js/jquery.ui.timepicker.js"></script>

UPDATE: The new code is available at github. I’ve also added the ability to delete entries and I am preparing to add permissions and user management soon.