HTML5 date input type on mobile

Whilst developing a new mobile only website, the UX team specified in the wireframes that a datepicker was needed for an input field; but nowhere else on the site was a datepicker used, so I really wanted to avoid using a JavaScript heavy solution. I couldn’t justify including so much extra JavaScript, CSS and images for so little usage. So what other options do we have?

Well there is a jQuery plug-in called Mobiscroll which is around 16KB is size and works on iOS and Android devices. Unfortunately there’s no mention of Windows-based mobiles which is a real shame, as it’s almost a perfect solution. The other option we have is to take advantage of some cutting edge HTML5 form input types; the date input type. Support is nowhere near 100% yet, but if you approach its usage from a progressive enhancement standpoint, it works well. On mobile browsers that support it, the user gets a fancy datepicker that’s very intuitive; browsers that don’t simply drop back to a standard text input. It’s worth noting that Modernizr can’t detect that date inputs create a datepicker, since Modernizr can’t do it I assume it isn’t possible. Damn!

An example of the date input type on iPhone, iPad and iPods.
The date input type as displayed on iOS mobile Webkit devices.

Once I’d decided on how the date picker was going to work (HTML5) it was time to implement it and test it across my available mobile browsers. Implementation was dead simple:

1
2
<!-- Fancy datepicker on supported devices, standard text input on unsupported -->
<input type="date" name="fancyDate" id="fancyDate">

Where things got a little tricky (and annoying) was the client-side validation of the input. Since the wireframes contained lots of forms with a varying range of input types and requirements, I decided to go with quite a heavyweight validation script (around 21KB minified). This turned out to be a very good decision in the end, as there are a few quirks to the date input element.

First thing I had to consider was how were users going to input the date when they don’t have the fancy datepicker? The most intuitive way (at least for me) is they simply enter in the format dd/mm/yyyy. Great, that’s sorted! And guess what, when a user uses the fancy datepicker it also returns a value of dd/mm/yyyy…. no, no it doesn’t! It looks like that’s the value that will be returned as that’s how it is displayed, but no, it’s never that easy. Webkit actually returns the date in the format yyyy-mm-dd, not quite what I was expecting! Unfortunately this breaks our validation as it is looking for a format of dd/mm/yyyy!

So what’s the fix? Well you could take the easy route and make your non-fancy datepicker users enter the date in the yyyy-mm-dd format; but that just feels wrong. No user is going to expect to enter a date like that, it’s completely unintuitive! No I’m afraid it’s going to take a little hack to fix this issue. The hack involves using a second input field of type “text”; when a user interacts with the fancy datepicker or enters in the date manually, the date is “cleaned up” and passed along to the second input field. You then do your form validation against this second field. You can see an example of this working here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
 * iOS input type="date" returns a value of yyyy-mm-dd even when
 * it displays dd/mm/yyyy. This breaks validation. Fix for this using a second input.
 * Keyup event for testing in a browser, not needed for mobile.
 */
$("input[type='date']").on("blur keyup", function(e){
    var $this = $(this),
        value = $this.val();

    //Does the input have "-", if so it is from the webkit datepicker, fix it
    if(value.indexOf("-") !== -1){
        var cleanDateArray = value.split('-');
        value = cleanDateArray[2] + "/" + cleanDateArray[1] + "/" + cleanDateArray[0];
    }

    //Set the hidden value to validate on, trigger the blur and keyup event for validation as you type
    $("#hiddenDateField").val(value).trigger("blur").trigger("keyup");
});

A couple of points to note about using this method. Even though we aren’t validating the datepicker input, we still have to set “date: false” in the validation rules. This is because the validation plug-in automatically tries to validate date inputs. Validation fails because it doesn’t like the dd/mm/yyyy format. I’ve also used the dateITA method to validate the date on the “hidden” input (you can find this in the additional-methods.min.js file). This additional method is more robust than the plug-ins standard date validation. A minor pitfall with this hack is that setting the second input to type “hidden” will stop its validation; this is due to the validation plug-in ignoring hidden inputs. So to hide the input you can set “display: none” in the CSS (urghh I know, I feel dirty too!).

So there you have it, that’s how I solved validating a date input on mobile with fancy datepicker and standard text fallback. It’s not ideal by any means, but it works. Another solution would be writing a validator Regex that accepts both dd/mm/yyyy and yyyy-mm-dd date formats, but this means returning both types of dates to the server on submit. Due to server-side constraints with the project, this isn’t an option (boo!). Is there a much simpler method that I’m completely missing? If so please leave a comment! :)