JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
<div class="instructions"><span>If the user has a datepicker open when knockout's model changes, the datepicker stops working correctly. In this example, a 5-second timer is adding and removing objects to the model. To view the issue, open the left datepicker while there is 1 object, and select a date once there are 2 objects.</span>
<br/><br/>
<span>Expected: the left datepicker changes. Actual: the new (right) datepicker changes.</span>
<br/><br/>
<span data-bind="visible: dateBoxes().length === 1">Open the left datepicker now.</span>
<span data-bind="visible: dateBoxes().length === 2">Select a date now.</span>
</div>
<ul data-bind="foreach: dateBoxes">
<li>
<span data-bind="text: index"></span>
<input type="text" data-bind="datepicker: date"/>
</li>
</ul>
CSS
div.instructions { font-family:arial; }
li { display: inline-block; border: 1px solid lightgray; padding: 5px; }
JavaScript
ko.bindingHandlers.datepicker = {
init: function(element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options);
//handle the field changing
ko.utils.registerEventHandler(element, "change", function() {
var observable = valueAccessor();
observable($(element).datepicker("getDate"));
});
//handle disposal (if KO removes by the template binding)
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).datepicker("destroy");
});
element.isFirstRun = true;
},
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
//handle date data coming via json from Microsoft
if (String(value).indexOf('/Date(') == 0) {
value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
}
if (element.isFirstRun) {
var format = $(element).datepicker('option','dateFormat');
$(element).val($.datepicker.formatDate(format, value));
element.IsFirstRun = false;
return;
}
var current = $(element).datepicker("getDate");
if (value - current !== 0) {
$(element).datepicker("setDate", value);
}
}
};
var model;
var id = 0;
function DateBox(d) {
var self = this;
self._date = ko.observable(d);
self.date = ko.computed({
read: self._date,
write: function(v) {
self._date(new Date(v));
}
});
self.index = ko.observable(id++);
}
function Model() {
var self = this;
self.dateBoxes = ko.observableArray([]);
self.changeCount = function() {
if (self.dateBoxes().length < 2) {
...