0

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'));
});
Jake Haas
  • 73
  • 7
  • I've made a fiddle from your code and it seems to be working fine the second case you provide. Please create a working example that shows the exact problem you have. – Ionut Necula Feb 01 '18 at 14:43
  • @lonut That is very strange. Could it be browser dependent? I have tried Chrome and Firefox. – Jake Haas Feb 01 '18 at 14:48
  • I don't think it's a browser issue, also tested in Firefox and Chrome and works very well. Maybe it's another part from your code that's causing the issue, that's what I asked you to post a working example which shows the problem you have. Based on the code you provided till now I can't replicate the issue. – Ionut Necula Feb 01 '18 at 14:50
  • for the record, have you read the documentation for the picker? you have the getTime() available in the API, lets you get the Date object back after a change. The val() you're using simply returns a string. Not a huge difficulty to convert back and forth, but there's that. Also, you have the changeTime event being emitted, which may be handy to tie into.https://jsfiddle.net/4fgh5aaf/ – Snowmonkey Feb 01 '18 at 15:07
  • Here is a jFiddle with it not working for me: https://jsfiddle.net/q3mw0wbc/6/ – Jake Haas Feb 01 '18 at 15:09
  • include the fiddle... – Snowmonkey Feb 01 '18 at 15:09
  • Also, here is a video of what is happening... https://gfycat.com/ThatPowerlessIberianbarbel – Jake Haas Feb 01 '18 at 15:13
  • I modified your fiddle to use `blur` event instead of `change`. See if you can live with that. [https://jsfiddle.net/q3mw0wbc/7/](https://jsfiddle.net/q3mw0wbc/7/) – Soham Feb 01 '18 at 15:35

2 Answers2

0

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>
Ionut Necula
  • 11,107
  • 4
  • 45
  • 69
0

This should be works:

 $("#" + elementId).on('change', function(element) {
     var m = new moment(element.val(), 'hh:mm a');
     element.val(m.format('HH:mm:ss'));
 });
аlex
  • 5,426
  • 1
  • 29
  • 38