Forked from anonymous/knockout.extendedCheckedBinding.js
Last active
December 10, 2015 10:08
-
-
Save kamranayub/4418574 to your computer and use it in GitHub Desktop.
A smarter `checked` and `value` binding that play nice together.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Now you can bind your checkbox selection to an observable array of model | |
// properties, instead of having to bind it to a property on the item | |
// itself (e.g. `isSelected`). | |
// For more information, see: | |
// http://kamranicus.com/Blog/Posts/61/a-smarter-checked-binding-for-knockoutjs | |
// For a demo, see: | |
// http://jsfiddle.net/kamranayub/G8YZU | |
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); | |
} | |
}; | |
var oldCheckedBinding = ko.bindingHandlers['checked']; | |
ko.bindingHandlers['checked'] = { | |
'init': function (element, valueAccessor, allBindingsAccessor) { | |
var allBindingsValue = allBindingsAccessor(), | |
modelValue = valueAccessor(), unwrappedValue = ko.utils.unwrapObservable(modelValue); | |
if (allBindingsValue.hasOwnProperty("value") && (element.type == "checkbox") && (unwrappedValue instanceof Array)) { | |
var updateHandler = function () { | |
// 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 = ko.utils.unwrapObservable(allBindingsValue.value); | |
// Update values | |
modelValue = valueAccessor(); | |
unwrappedValue = ko.utils.unwrapObservable(modelValue); | |
var existingEntryIndex = ko.utils.arrayIndexOf(unwrappedValue, boundValue); | |
if (element.checked && (existingEntryIndex < 0)) | |
modelValue.push(boundValue); | |
else if ((!element.checked) && (existingEntryIndex >= 0)) | |
modelValue.splice(existingEntryIndex, 1); | |
}; | |
ko.utils.registerEventHandler(element, "click", updateHandler); | |
// IE 6 won't allow radio buttons to be selected unless they have a name | |
if ((element.type == "radio") && !element.name) | |
ko.bindingHandlers['uniqueName']['init'](element, function () { return true }); | |
} else { | |
oldCheckedBinding['init'].apply(this, arguments); | |
} | |
}, | |
'update': function (element, valueAccessor, allBindingsAccessor) { | |
var value = ko.utils.unwrapObservable(valueAccessor()), | |
allBindingsValue = allBindingsAccessor(); | |
if (allBindingsValue.hasOwnProperty("value") && element.type == "checkbox" && value instanceof Array) { | |
var boundValue = ko.utils.unwrapObservable(allBindingsValue.value); | |
// When bound to an array, the checkbox being checked represents its value being present in that array | |
element.checked = ko.utils.arrayIndexOf(value, boundValue) >= 0; | |
} else { | |
oldCheckedBinding['update'].apply(this, arguments); | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment