Using jQuery's inline Datepicker within a form

When you use the inline version of jQuery UI's Datepicker within a form, it doesn't submit its value back to the server, since there's no form element in it.

And that's a pity, because I find the inline mode way more comfortable for users: rather than having to click a button in order to open an overlay with the calendar and then finally select the date, they can simply select the date in the calendar, without worrying about anything else.

So I devised this simple function that when run over DIV elements attaches the corresponding inline d date picker to them, and also creates a hidden input element for each DIV, which will hold the selected associated date.

This value will be updated automatically whenever a new date is selected in the calendar (because we bind to the select event). When the form is submitted, the value for the inline date picker is submitted too, thanks to the hidden input element :)


function htmlDatePickerize(selector) {
    $(selector).each(function(e) {
        var dateValue = $(this).attr('value');
        var formName = $(this).attr('name');
        var hiddenInput = document.createElement('input');
        hiddenInput.name = formName;
        hiddenInput.value = dateValue;
        hiddenInput.type = 'hidden';
        $(this).after(hiddenInput);
        $(this).datepicker({
            onSelect : function(dateText, inst) {
                hiddenInput.value = dateText;
            }
        }).datepicker("setDate", dateValue);
    });
}

You would use it like this:


$(document).ready(function()
{
    htmlDatePickerize('.calendar');
}

It then would use '.calendar' as the selector, and jQuery to look for matching elements, creating the inputs and binding to the select events.

For this to work properly, you need to specify two attributes in each DIV element:

  • name
  • value

Therefore, a proper DIV, apt for being datePickerized, would be the following one:


<div class="calendar" name="startDate" value="2006-03-02"></div>

and the form field would obviously be startDate.

I'm uncertain about the validity of these two 'new' attributes in DIV elements. The W3 validator is definitely not happy about them, and spits two unmerciful there is no attribute "name" and there is no attribute "value" errors, yet it works with Firefox and Chrome, both allowing me to manipulate object attributes at will.

HTML5 makes room for custom attributes, but their names should be prefixed with "data". So these attributes should be renamed to "data-name" and "data-value" respectively if I wanted them to be valid HTML5 (although I'm still using a transitional XHTML doctype for this project).

All in all, a tremendous hack, but very practical. Hopefully HTML5 support for time/month/datetime/date inputs will get better in the future (currently only Opera supports them, as Mark Pilgrim dutifully points out).

Meanwhile, transgression is a must.