JSFiddle - React, Tailwind, and code Playground
HTML
<h1>Better Checked Binding</h1>
<ul data-bind="foreach: items">
<li><input type="checked" data-bind="checked: $parent.selectedItems, value: id"> <input type="text" data-bind="value: name"> <span data-bind="text: name"></span></li>
</ul>
<strong>Item 1 selected? <span data-bind="text: isItem1Selected"></span></strong>
<pre data-bind="text: model"></pre>
JavaScript
var oldValueBinding = ko.bindingHandlers['value'];
ko.bindingHandlers['value'] = {
'init': function (element, valueAccessor, allBindingsAccessor) {
// If `checked` binding is present, ignore this binding because
// user wishes to bind the checked value to the model value
var allBindings = allBindingsAccessor(),
hasChecked = allBindings.hasOwnProperty("checked");
if (hasChecked) {
return;
}
oldValueBinding['init'].apply(this, arguments);
},
'update': function (element, valueAccessor, allBindingsAccessor) {
// If `checked` binding is present, ignore this binding because
// user wishes to bind the checked value to the model value
var allBindings = allBindingsAccessor(),
hasChecked = allBindings.hasOwnProperty("checked");
if (hasChecked) {
return;
}
oldValueBinding['update'].apply(this, arguments);
}
};
ko.bindingHandlers['checked'] = {
'init': function (element, valueAccessor, allBindingsAccessor) {
var updateHandler = function() {
var valueToWrite;
if (element.type == "checkbox") {
valueToWrite = element.checked;
} else if ((element.type == "radio") && (element.checked)) {
valueToWrite = element.value;
} else {
return; // "checked" binding only responds to checkboxes and selected radio buttons
}
var modelValue = valueAccessor(), unwrappedValue = ko.utils.unwrapObservable(modelValue),
allBindingsValue = allBindingsAccessor();
if ((element.type == "checkbox") && (unwrappedValue instanceof Array)) {
// For checkboxes bound to an array, we add/remove the checkbox value to that array
// This works for both observable and non-observable arrays
var boundValue = (allBindingsValue.hasOwnProperty("value")...