ECie
ECie

Reputation: 1477

Bootstrap date time picker not allowing user to type time

I have a scenario where I use Bootstrap Datetimepicker to select time, but when I manually type the time, even in correct format, it changes to 12:00 AM on date picker close

Here is my datetimepicker:

$('#ShiftStart').datetimepicker({
    minDate: actualDate,
    maxDate: maxDate,
    useCurrent: false,
    format: 'hh:mm A',
    defaultDate:moment(startTime),
    stepping: 15
});

$('#ShiftEnd').datetimepicker({
    minDate: actualDate,
    maxDate: maxDate,
    format: 'hh:mm A',
    defaultDate:moment(startTime),
    stepping: 15
});

Even if I bind an onfocusout event to set the value of the datetimepicker it doesn't change when the picker closed.

$("#ShiftStart").focusout(function (e) {
    //here it is defaulted again to 12:00 AM
    var time = $('#' + e.target.id).val();
    $('#' + e.target.id).attr('data-time', actualDate + ' ' + time);
    $('#' + e.target.id).attr('value', actualDate + ' ' + time);
    $('#' + e.target.id).val(time)
});

Any work around on this.

var actualDate = $('#ActualDate').val();
var maxDate = $('#MaxDate').val();
var startTime = $('#StartTime').val();
$('#ShiftStart')
  .datetimepicker({
    minDate: actualDate,
    maxDate: maxDate,
    useCurrent: false,
    format: 'hh:mm A',
    defaultDate: moment("12/27/2017"),
    stepping: 15
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js"></script>


 <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js"></script>
 
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.min.css" rel="stylesheet" />

<input id="ActualDate" type="hidden" value="12/27/2017">
<input id="MaxDate" type="hidden" value="12/28/2017">
<input id="StartTime" type="hidden" value="12/27/2017 8:00:00 AM">
<input class="form-control timepicker valid" data-val="true" data-val-genericcompare="Start time must be earlier than end time" data-val-genericcompare-comparetopropertyname="ShiftEnd" data-val-genericcompare-operatorname="LessThan" data-val-required="The Start Time field is required."
  id="ShiftStart" name="ShiftStart" style="max-width : none;  border : 1px solid #cccccc;" type="text" value="12/27/2017 12:00 AM" data-time="12/27/2017 12:00 AM" aria-required="true" aria-describedby="ShiftStart-error" aria-invalid="false">

Upvotes: 1

Views: 2216

Answers (2)

VincenzoC
VincenzoC

Reputation: 31502

The datetimepicker defaults back to 12:00 AM even if you select the value from the picker (not only manually type), I think this is a bug of the the lastest versions of the component.

Anyway, there are a couple of things to fix in your code. As the date([newDate]) states :

Takes string, Date, moment, null parameter and sets the components model current moment to it. [...]

Parsing of the newDate parameter is made using moment library with the options.format and options.useStrict components configuration.

So minDate, maxDate and defaultDate are strings parsed using format option (hh:mm A in your case) and this will produce wrong values, use moment(String, String) instead (e.g. defaultDate: moment("12/27/2017", 'MM/DD/YYYY')).

Even the value property in the HTML is parsed using format, 12/27/2017 12:00 AM does not match hh:mm A so I've removed it in my snippet.

Here a working example using version 4.17.37 of the datetimepicker:

var actualDate = $('#ActualDate').val();
var maxDate = $('#MaxDate').val();
var startTime = $('#StartTime').val();
$('#ShiftStart')
  .datetimepicker({
    minDate: moment(actualDate, 'MM/DD/YYYY'),
    maxDate: moment(maxDate, 'MM/DD/YYYY'),
    useCurrent: false,
    format: 'hh:mm A',
    defaultDate: moment("12/27/2017", 'MM/DD/YYYY'),
    stepping: 15
  });
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/css/bootstrap-datetimepicker.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.37/js/bootstrap-datetimepicker.min.js"></script>

<input id="ActualDate" type="hidden" value="12/27/2017">
<input id="MaxDate" type="hidden" value="12/28/2017">
<input id="StartTime" type="hidden" value="12/27/2017 8:00:00 AM">
<div class="row">
  <div class='col-sm-6'>
    <input class="form-control timepicker valid" data-val="true" data-val-genericcompare="Start time must be earlier than end time" data-val-genericcompare-comparetopropertyname="ShiftEnd" data-val-genericcompare-operatorname="LessThan" data-val-required="The Start Time field is required."
  id="ShiftStart" name="ShiftStart" style="max-width : none;  border : 1px solid #cccccc;" type="text"  data-time="12/27/2017 12:00 AM" aria-required="true" aria-describedby="ShiftStart-error" aria-invalid="false">
  </div>
</div>

Side thoughts:

  • Since you are using hh:mm A format, you can probably just manage time and get rid of minDate and maxDate (in your example you are limiting to a single given day)
  • If you want to do something when the components hides use dp.hide event.

Upvotes: 2

Bassie
Bassie

Reputation: 10390

I think this is happening because minDate is reseting the field value to the current date at midnight (probably the default time), and similarly maxdate probably also sets it to midnight by default.

Remove minDate: actualDate and maxDate: maxDate from the initialisation:

<input id="ActualDate" type="hidden" value="12/27/2017">
<input id="MaxDate" type="hidden" value="12/28/2017">
<input class="form-control timepicker valid" data-val="true" data-val-genericcompare="Start time must be earlier than end time" data-val-genericcompare-comparetopropertyname="ShiftEnd" data-val-genericcompare-operatorname="LessThan" data-val-required="The Start Time field is required."
    id="ShiftStart" name="ShiftStart" style="max-width : none;  border : 1px solid #cccccc;" type="text" aria-required="true" aria-describedby="ShiftStart-error" aria-invalid="false">

<script>
    var actualDate = $('#ActualDate').val();
    var maxDate = $('#MaxDate').val();
    $('#ShiftStart').datetimepicker({
        useCurrent: false,
        format: 'hh:mm A',
    });
</script>

In reply to your comment, you can pass in the maxDate parameter like this:

maxDate: new Date('2017', '12', '27', '03', '30', '00', '00')

Which i guess you will need to build from the maxDate string. Note that to get this working I had to remove the defaultDate parameter from the snippet in your question.

Upvotes: 1

Related Questions