Search code examples
javascriptjquerywebjquery-ui-timepicker

jQuery Timepicker onChange update same field


I am using this jQuery timepicker:

http://jonthornton.github.io/jquery-timepicker/

I want to show the list in human readable times, but need the form to submit the time as HH:MM:SS. It does not look like this plugin allows the user to have two different formats like the datepicker does.

Unfortunately, I am stuck with this system to maintain so I can't change plugins or server code. I am trying to do a work around by using the onChange (also the plugin's own changeTime) event of the input field to convert the time into the proper format and write it back to itself.

The problem is that it seems the onChange event is getting triggered before the timepicker's value is actually being put into the element. I see the correct converted time for a split second before it gets overwritten with the timepicker's value.

It works if I use a delay to update the field, but it doesn't look very nice from the user side.

Any thoughts? Thanks!

Please see the code below:

This works (with the delay, it seems it needs to be at least 150ms for it to work)

$("#" + elementId).on('change', function() {
    var m = new moment($(this).val(), 'hh:mm a');
    setTimeout(function(){ $($this).val(m.format('HH:mm:ss')); }, 150);
});

This does not - I see it for a split second before it gets overwritten.

$("#" + elementId).on('change', function() {
    var m = new moment($(this).val(), 'hh:mm a');
    $(this).val(m.format('HH:mm:ss'));
});

Solution

  • Seems that the main issue has something to do with the timepicker version used and the timeFormat set in timepicker. I've changed timeFormat: 'g:i A' to timeFormat: 'h:mm:ss p', because moment.js does not seem to be able to convert the first format, also as I said, I've changed the timepicker library. See a working snippet below:

    $(document).ready(function() {
      enableTimePicker('test');
    });
    
    function enableTimePicker(elementId) {
      $("#" + elementId).timepicker({
        timeFormat: 'h:mm:ss p',
        disableTextInput: true,
        disableTouchKeyboard: true,
        minTime: '00:30:00',
        'noneOption': [{
          'label': 'Midnight',
          'value': '23:59:59'
        }]
      });
    
      $("#" + elementId).on('change', function() {
        if ($(this).val() != '23:59:59') {
          var m = new moment($(this).val(), 'hh:mm a');
          // setTimeout(function(){ $("#" + elementId).val(m.format('HH:mm:ss')); }, 150);
          $("#" + elementId).val(m.format('HH:mm:ss'));
        }
      });
    }
    .ui-timepicker-wrapper {
      overflow-y: auto;
      max-height: 150px;
      width: 6.5em;
      background: #fff;
      border: 1px solid #ddd;
      -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
      -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
      box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
      outline: none;
      z-index: 10001;
      margin: 0;
    }
    
    .ui-timepicker-wrapper.ui-timepicker-with-duration {
      width: 13em;
    }
    
    .ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-30,
    .ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-60 {
      width: 11em;
    }
    
    .ui-timepicker-list {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    
    .ui-timepicker-duration {
      margin-left: 5px;
      color: #888;
    }
    
    .ui-timepicker-list:hover .ui-timepicker-duration {
      color: #888;
    }
    
    .ui-timepicker-list li {
      padding: 3px 0 3px 5px;
      cursor: pointer;
      white-space: nowrap;
      color: #000;
      list-style: none;
      margin: 0;
    }
    
    .ui-timepicker-list:hover .ui-timepicker-selected {
      background: #fff;
      color: #000;
    }
    
    li.ui-timepicker-selected,
    .ui-timepicker-list li:hover,
    .ui-timepicker-list .ui-timepicker-selected:hover {
      background: #1980EC;
      color: #fff;
    }
    
    li.ui-timepicker-selected .ui-timepicker-duration,
    .ui-timepicker-list li:hover .ui-timepicker-duration {
      color: #ccc;
    }
    
    .ui-timepicker-list li.ui-timepicker-disabled,
    .ui-timepicker-list li.ui-timepicker-disabled:hover,
    .ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
      color: #888;
      cursor: default;
    }
    
    .ui-timepicker-list li.ui-timepicker-disabled:hover,
    .ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
      background: #f2f2f2;
    }
    <link href="/libs/jquery-timepicker-1.11.13/jquery.timepicker.min.css" rel="stylesheet" />
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.10.0/jquery.timepicker.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.min.js"></script>
    
    <form>
      <div class="form-group">
        <label class="col-md-4 control-label" for="test">Test Input</label>
        <div class="col-md-4">
          <input id="test" name="test" type="text" placeholder="" class="form-control input-md" data-input_type="4">
        </div>
      </div>
    </form>