So I am using Knockout Validation to validate my viewmodel and a custom knockout datepicker bindingHandler to attach a jQuery-UI datepicker to dynamically added items in my observableArray.
It seems my bindingHandler is destroying or breaking the validation rules on that field. Neither of the validation rules for the Start or End date seem to be getting enforced.
HTML code:
<form>
<a class="btn btn-default" data-bind="click: function () { $root.addMed(); }">Add New Medication</a>
<h6 data-bind="visible: patientMeds().length < 1">No medications entered.</h6>
<table class="table table-condensed" data-bind="visible: patientMeds().length > 0">
<thead>
<tr>
<th>Med</th>
<th>From</th>
<th>To</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: patientMeds">
<tr>
<td>
<input class="form-control" data-bind="value: MedicationID" />
</td>
<td>
<input class="form-control" data-bind="datepicker: StartDate, datepickerOptions: { changeMonth: true, changeYear: true, showButtonPanel: true }" />
</td>
<td>
<input class="form-control" data-bind="datepicker: DiscontinuedDate, datepickerOptions: { changeMonth: true, changeYear: true, showButtonPanel: true }" />
</td>
<td>
<button class="btn btn-default" data-bind="click: $parent.removeMed">Delete</button>
</td>
</tr>
</tbody>
</table>
</form>
Javascript / ViewModel code:
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
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");
});
}
};
function PatientMedication(p) {
var self = this;
p = p || {};
self.MedicationID = ko.observable(p.MedicationID || 1)
.extend({
required: {
params: true,
message: 'Please enter a medication'
},
number: true
});
self.StartDate = ko.observable(p.StartDate).extend({
required: {
params: true,
message: 'Please enter a date'
},
date: true
});
self.DiscontinuedDate = ko.observable(p.DiscontinuedDate || '').extend({
required: {
params: true,
message: 'Please enter a date'
},
date: true
});
}
function MedicationViewModel() {
var self = this;
self.patientMeds = ko.observableArray([]);
self.addMed = function () {
self.patientMeds.unshift(new PatientMedication());
};
self.removeMed = function (med) {
self.patientMeds.remove(med)
};
};
var medvm = new MedicationViewModel();
ko.applyBindings(medvm);