Brian J Brian J - 4 months ago 24
jQuery Question

How to override Bootstrap DatePicker to allow arbitrary hours selection?

I'm using the Bootstrap Date picker control to allow selection of an arbitrary amount of hours. So for example a user could select anywhere between

1 -> 50 hours.


In the current setup I set the format option to allow only hour selection using
format: 'HH'
, but this limits the max hour selection to 23 hours.

Question
Does anyone know how to override the default hour selection values on a Bootstrap Date picker?

In the below date picker selecting an hour greater than 23 resets the picker to 0:

enter image description here

This is the declaration of the Date picker in the script and options:

//Init the Next Update arbitrary hour picker
$(function () {
$('#NextUpdateDisplay').datetimepicker({
ignoreReadonly: true,
allowInputToggle: true,
format: 'HH',
widgetPositioning: {
horizontal: 'right',
vertical: 'bottom'
}
});
});

Answer

In Bootstrap.timepicker.js, find this line:

`this.hour >= 24 ? this.hour = 23`

change it to:

`this.hour >= 51 ? this.hour = 50`

Make sure that when you instantiate your timepicker, you use showMeridian = false as an option:

$(".timepicker").timepicker({
    showMeridian: false
});

EDIT: If you want other DatePickers to be normal:

  • Copy TimePicker to a new object TimePickerEx,
  • Override the functionality you want to (can be done nicely using Object.create(),
  • Yeilding:

    function TimePickerEx() {
      return Object.create(TimePicker(), {
        setTime: function(time, ignoreWidget) {
          if (!time) {
            this.clear();
            return;
          }
    
          var timeArray,
              hour,
              minute,
              second,
              meridian;
    
          if (typeof time === 'object' && time.getMonth){
            // this is a date object
            hour    = time.getHours();
            minute  = time.getMinutes();
            second  = time.getSeconds();
    
            if (this.showMeridian){
              meridian = 'AM';
              if (hour > 12){
                meridian = 'PM';
                hour = hour % 12;
              }
    
              if (hour === 12){
                meridian = 'PM';
              }
            }
          } else {
            if (time.match(/p/i) !== null) {
              meridian = 'PM';
            } else {
              meridian = 'AM';
            }
    
            time = time.replace(/[^0-9\:]/g, '');
    
            timeArray = time.split(':');
    
            hour = timeArray[0] ? timeArray[0].toString() :                 timeArray.toString();
            minute = timeArray[1] ? timeArray[1].toString() : '';
            second = timeArray[2] ? timeArray[2].toString() : '';
    
            // idiot proofing
            if (hour.length > 4) {
              second = hour.substr(4, 2);
            }
            if (hour.length > 2) {
              minute = hour.substr(2, 2);
              hour = hour.substr(0, 2);
            }
            if (minute.length > 2) {
              second = minute.substr(2, 2);
              minute = minute.substr(0, 2);
            }
            if (second.length > 2) {
              second = second.substr(2, 2);
            }
    
            hour = parseInt(hour, 10);
            minute = parseInt(minute, 10);
            second = parseInt(second, 10);
    
            if (isNaN(hour)) {
              hour = 0;
            }
            if (isNaN(minute)) {
              minute = 0;
            }
            if (isNaN(second)) {
              second = 0;
            }
    
            if (this.showMeridian) {
              if (hour < 1) {
                hour = 1;
              } else if (hour > 12) {
                hour = 12;
              }
            } else {
              if (hour >= 51) {
                hour = 50;
              } else if (hour < 0) {
                hour = 0;
              }
              if (hour < 13 && meridian === 'PM') {
                hour = hour + 12;
              }
            }
    
            if (minute < 0) {
              minute = 0;
            } else if (minute >= 60) {
              minute = 59;
            }
    
            if (this.showSeconds) {
              if (isNaN(second)) {
                second = 0;
              } else if (second < 0) {
                second = 0;
              } else if (second >= 60) {
                second = 59;
              }
            }
          }
    
          this.hour = hour;
          this.minute = minute;
          this.second = second;
          this.meridian = meridian;
    
          this.update(ignoreWidget);
        },
      }); 
    }
    

to use:

var timePickerEx = TimePickerEx();

and use a normal TimePicker for the rest.