Datepickers for Django Sites that Work on the Desktop and Mobile

As of April 2017, HTML datepickers are still a mess. Here’s how it should be; all browsers should support the <input> attribute “type”. And when the browser sees <input type=”date” …. > the browser should offer up an awesome builtin date picker. Unfortunately we are far from that world.

My work around starts with using a javascript datepicker plugin. There are lots of choices and I have not tried them all. The one I am using is Bootstrap Datetime Picker. When using this picker, make sure to set <input type=”text” …. >, by doing this you prevent the browser from simultaneously providing a native date picker. For example, when you are running in “no icon” mode, with type=text this is what you get in Chrome:

but when type=”date” you get this:

Pretty ugly. It’s even worse in IE. This works pretty well on big screens, but not as well on small screens (e.g. phones).

On the small screen, it’s best to use the native datepicker. To make that happen you need not initialize the datepicker widget and you need to change the type attribute to “date”. Here is one way to do that that uses the Responsive Bootstrap Toolkit:

(function($, viewport){
    $(document).ready(function() {
        var datepickers = $(".bootstrapdatepickerwidget3");

        // Executes in XS and SM breakpoints
        if(viewport.is('>=md')) {
            datepickers.each(function(index, el) {
                $(el).datetimepicker({format: 'YYYY-MM-DD'});
            })
        } else {
            datepickers.each(function(index, el) {
                $(el).attr('type','date');
            })
        }
    });
})(jQuery, ResponsiveBootstrapToolkit);

Add a custom Django form field widget and you can make all these steps automatically:

from django import forms

class BootstrapDatePickerWidget(forms.DateInput):
    # noinspection PyClassHasNoInit
    class Media:
        css = {'all': [
            '3s_hts/js/bootstrap-datetimepicker-master/bootstrap-datetimepicker.min.css'
        ]}

        js = ('3s_hts/js/bootstrap-datetimepicker-master/moment.js',
              '3s_hts/js/bootstrap-datetimepicker-master/bootstrap-datetimepicker.min.js',
              '3s_hts/js/responsive-toolkit/dist/bootstrap-toolkit.min.js',
              '3s_hts/js/setup_bootstrap_datepicker.js')

class BootstrapDatePickerField(forms.DateField):
    widget = BootstrapDatePickerWidget3
Advertisements