logo

Bootstrap Advanced Date Picker Plugin

For some time now I've been creating date fields in Bootstrap-based websites that look like this:

image

Clicking either in the field or on the button next to it launches a date-picker, like this:

image

In the Notes Form the Date Field is configured in such a way that it accepts dates in the format 12-Dec-2009 (while storing them in normal Notes DateTime format of course).

The field properties are like so:

image

 

It all works well and users like them. Not least because there's no confusion over whether it's mm/dd or dd/mm! When the document is viewed in read-mode the dates are displayed in the same format automatically!

The only downside is that the field is marked up as "readonly" to prevent users trying to type in their own dates, which forces them to use the picker. Ok for most, but if you want to pick a date 10 years ago....

I'm assuming you're using Domino, but this is by no means restricted to use only with Domino.

Taking it Further

I was asked recently if a certain date field could be extended to add the ability for a user to choose from a list of predefined date ranges. Such as "A year from now" or "3 months from now".

Such is the beauty of bootstrap that I was soon able to extend my date field by creating a plugin that adds extra button, as below:

image

When clicked on, it looks like this:

image

Happy days!

How Did I Do It?

Creating the basic date picker is a simple case of marking it up like this:

<div class="input-append">
    <input name="DOB" id="DOB" rel="date" type="text" readonly="readonly">
    <button class="btn" onclick="$('#DOB').focus()"><i class="icon icon-calendar"></i></button>
</div>

Then at the bottom of the page (or better still, in an "form.init()" function called on "dom ready") do this:

$(function() {
 $("input[rel='date']").datepicker({dateFormat: "dd-M-yy"});
});

This code looks for all fields where rel="date" and binds the jQuery UI date picker to it.

Hey presto.

Advanced Version

To make the version with the additional dropdown, the HTML markup for the field changes to something like this:

<div class="input-append">
    <input name="DateExpected" value="" id="DateExpected" rel="date" type="text" class="span2" readonly="readonly">
    <div class="btn-group">
        <button class="btn dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>

        <ul class="dropdown-menu month-adder" role="menu">
            <li data-increment="1"><a>In One Month</a></li>
            <li data-increment="3"><a>In 3 Months</a></li>
            <li data-increment="6"><a>Within 6 Months</a></li>
            <li data-increment="12"><a>In a year</a></li>
        </ul>

        <button class="btn"><i class="icon icon-calendar"></i></button>
    </div>
</div>

It should be obvious from that HTML how it all works. Maybe it's obvious to me as I'm au fais with Bootstrap?

Turning It In To A Plugin

While the HTML markup needed to wrap round a field to make it a datepicker isn't complicated you can imagine it's a bit of a pain to markup lots of date fields. What we really need is a plugin.

To create a plugin you'd simply add the following code in to your main "application.js" file:

(function( $ ) {
    $.fn.datePicker2 = function(options){
        var settings = $.extend({
            dateFormat: "dd/mm/yy"
        }, options );
        
        this.datepicker({dateFormat: settings.dateFormat}) //Initiate the datepicker
            .attr("readonly",true) //Make the field itself readonly!
            .wrap('<div class="input-append" />') //wrap it in all a div 
            .after($('<button class="btn"><i class="icon icon-calendar" /></button>') //add a button after the field
            .click(function(){$(this).closest('.input-append').children().first().focus()})); //Bind a click even to it
    };    
}( jQuery ));

Now, you don't need to wrap the date fields in any HTML. You just specify rel="date" and call change the previous "on load" event to this:

$(function() {
 $("input[rel='date']").datePicker2({dateFormat: "dd-M-yy"});
});

We're now using our own new jQuery plugin which does all the HTML markup for us.

Here's the code for the plugin which takes it further and adds the dropdown of "1 month", "1 year" etc.

(function( $ ) {
    $.fn.dateSelector = function(options){
        var settings = $.extend({
            dateFormat: "dd-M-yy"
        }, options );

        this.parent().children().last()
            .wrap($('<div class="btn-group" />'))
            .before('<button class="btn dropdown-toggle" style="border-radius:0 !important;" data-toggle="dropdown"><span class="caret"></span></button>')
            .before(
                    $('<ul class="dropdown-menu month-adder" role="menu"><li data-increment="1"><a>In One Month</a></li><li data-increment="3"><a>In 3 Months</a></li><li data-increment="6"><a>Within 6 Months</a></li><li data-increment="12"><a>In a year</a></li></ul>')
                    .on('click', 'li', function(){$(this).closest('.input-append').children().first().val(new Date((new Date().setMonth(new Date().getMonth()+$(this).data('increment')))).toUTCString().substring(5,16).replace(/ /g,"-"))})
            );
    };
}( jQuery ));

 

A Demo

You can see it in use in this "fiddle".

Taking it further Still

It's far from perfect. For a start the JavaScript is messy and could do with being re-factored. But also, it would be nice to have options like "in 2 days", "in 3 weeks" etc. And to be able to specify different or additional options on a per-field basis.

For now though, it'll do. Hope you like.

Comments

  1. Way back in the beginning of 2006 I created a date input module for the web that allowed you to type in text like "next tue" and it would convert to a date. At the time I was tasked with helping our Notes group make everything web. This was hard for some programmers because at the time Notes web pages didn't have much in the way of validation. A date field in the client had all the attributes of a date field while on the web it was a text field. I started with Simon Willison's "A better way of entering dates", fixed a few bugs and added more date output formats. You can find the instructions here.

    http://tanny.ica.com/ica/tko/tkoblog.nsf/dx/date-input-and-calendar-popup-instructions

    And the code here.

    http://tanny.ica.com/ica/tko/tkoblog.nsf/dx/date-input-and-calendar-popup

    The drop down calendar and date text modules are separate. You are welcome to use the text code to enhance your date code.

  2. Very nice, Jake. I spotted it on your twitter feed at the beginning of the week and shared it around to my colleagues here (to typical silence). Nice usability feature and surprisingly little code in that fiddle - that's what surprised me most.

  3. Very cool Jake. you always have such excellent little tricks that make things just that much better!

    • avatar
    • Ian
    • Mon 16 Sep 2013 11:05 AM

    Here's a nice bootstrap form component that allows the user to select a time as well as a date. It also translates using I18N.

    http://www.malot.fr/bootstrap-datetimepicker/

      • avatar
      • Jake Howlett
      • Mon 16 Sep 2013 11:07 AM

      Brilliant! I love it.

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Fri 6 Sep 2013

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content