Tiffany B. Brown

Date input in HTML5: Restricting dates, and a thought for working around limitations

You probably know that HTML5 introduced a date input type, which constrains the value to a valid date string.

<input type=”date”> largely eliminates the need for JavaScript-based date pickers such as the one found in jQuery UI. In browsers that support the type, we can pick a date using the browser’s native widget. Below is an example of this widget in Chrome.

Native date widget in Chrome

Restricting input with min and max

We can restrict date input in a few ways. The easiest is by using the min and max attributes. Set the value to a valid date string using the YYYY-MM-DD pattern defined in RFC3339.

<input type="date" min="2013-10-01" max="2013-10-20">

In Chrome and iOS Safari, this will keep the user from selecting dates that are earlier than 1 October 2013 or later than 20 October 2013.

Date picker in Chrome with mininmum and maximum dates.

Using <datalist>

The datalist element is another way we can shape date input. Using datalist presents the user with a pre-selected list of dates, and the option to choose another, at least in Chrome, Opera, and Safari for iOS.

Date picker in Chrome with datalist.

We can even add a label attribute if, for example, we wanted to feature a list of holidays.

<input type="date" id="date" name="date" list="thesedates">

<datalist id="thesedates">

    <option label="Groundhog Day">2014-02-02</option>

    <option label="Valentine's Day">2014-02-14</option>

    <option label="Flag Day">2014-06-14</option>

</datalist>

Date picker with datalist and labels.

Can’t eliminate days, but here’s a suggested workaround

What we can’t do yet, however, is eliminate classes of days from our input. We can’t, for example, prevent selection of weekends or disallow Mondays purely through markup. Instead, we’ll need to do a little more work, using the HTML5 validation API, and the native JavaScript Date object.

Let’s take a look at some code that will display an error if the date selected is a Monday.

var date = document.querySelector('[type=date]');

function noMondays(e){

    var day = new Date( e.target.value ).getUTCDay();

    // Days in JS range from 0-6 where 0 is Sunday and 6 is Saturday

    if( day == 1 ){

        e.target.setCustomValidity('OH NOES! We hate Mondays! Please pick any day but Monday.');

    } else {

        e.target.setCustomValidity('');

    }

}

date.addEventListener('input',noMondays);

When our form is submitted, our user will be notified that they haven’t picked a date that we like. You should probably tell your user that X days are not permitted before they submit a date, of course. Just include some explanatory text near the field.

For weekends, you’ll need to test whether new Date( e.target.value ).getUTCDay(); equals 0 or 6, but the general principle is the same.

Then we can use the :invalid psuedo-class to highlight that this form data is invalid.

Why not just stick to JavaScript-based date pickers, then?

Since the date type has this limit, you may ask why we should use it and not stick to existing widget scripts. The best answer I have is: touch and scripting overhead. JavaScript-based date pickers are usually prone to fat-finger input issues. Both iOS and Android (Google’s version, at least) have tap-optimized date input controls used by browsers on those platforms. It’s a bit more seamless for the user.

And by using a native type where possible, we eliminate the JavaScript code, CSS, and DOM operations that go with it. That’s particularly important on smartphones where network capacity is more of a concern.

Comments are closed.