I'm trying to use knockoutjs with the tempusdominus datetimepicker and am having a problem with the custom binding. The binding will work during initialization, but changes made through the datepicker ui or not resulting in update events being handled by the custom binding. Please ignore the missing icons, I don't think that is what is causing the problem.
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
//initialize datepicker with some optional options
var options = allBindings().datepickerOptions || {
format: 'MM/DD/YYYY HH:mm',
defaultDate: valueAccessor()()
};
$(element).datetimepicker(options);
//when a user changes the date, update the view model
ko.utils.registerEventHandler(element, "change.datetimepicker", function(event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
value(event.date);
}
console.log("change.datetimepicker"); //, event.date.format());
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var val = ko.utils.unwrapObservable(valueAccessor());
if ($(element).datetimepicker) {
$(element).datetimepicker("date", val);
}
console.log("update called"); //, $(element).datetimepicker("date").format());
}
};
var viewModel = {};
function QuoteViewModel(data) {
var self = this;
self.dt2 = ko.observable(moment());
};
viewModel = new QuoteViewModel();
ko.applyBindings(viewModel);
/*
$("#datetimepicker1").on("change.datetimepicker", function (e) {
console.log("on change", e.date.format());
});
*/
<link href="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/d004434a5ff76e7b97c8b07c01f34ca69e635d97/build/css/bootstrap-datetimepicker.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment-with-locales.js"></script>
<script src="https://cdn.rawgit.com/Eonasdan/bootstrap-datetimepicker/d004434a5ff76e7b97c8b07c01f34ca69e635d97/src/js/bootstrap-datetimepicker.js"></script>
<div class="col-sm-6">
<div class="form-group">
<div class="input-group date" id="datetimepicker1" data-target-input="nearest">
<input type="text" class="form-control datetimepicker-input" data-target="#datetimepicker1" data-bind="datepicker: dt2" />
<div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div>
</div>
</div>
</div>
</div>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre> SCRIPT
https://jsfiddle.net/mh_surge/7yrze0Lv/6/
If I uncomment the code at the bottom that adds the non-ko change event handler, it always fires as expected. This leads me to believe that there might be a problem with ko.utils.registerEventHandler, but the source code for that function seems fine.
Why is the update and change event only being fired off only once during init and how do I fix it?
The change event that is triggered does not contain an event.date
property. The reason your commented out jQuery version does, is that it targets a different element.
In the knockout code, you're using the element
argument passed to init
and update
. This refers to the element that has the datepicker
data-bind.
In the jQuery code, you're targeting $("#datetimepicker1")
, which is a <div>
that has a custom change
element implemented by the plugin.
To fix this, you'll need to:
datepicker
binding on the element with id datetimepicker1
(i.e. not on the input
element)$(element).on("change.datepicker", ...)
syntax in the init
function