Twitter bootstrap ko checkedButtons
HTML
<script src="http://twitter.github.com/bootstrap/assets/js/bootstrap-button.js?"></script>
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<div class="btn-group">
<button data-value="0" data-bind="checkedButtons: radioValue" class="btn btn-small">radio 0</button>
<button data-value="1" data-bind="checkedButtons: radioValue" class="btn btn-small">radio 1</button>
</div>
<br>
<div class="btn-group">
<button data-value="true" data-toggle="checkbox" data-bind="checkedButtons: checkboxValue" class="btn btn-small">true/false</button>
</div>
<br>
<div class="btn-group">
<button data-value="a" data-toggle="checkbox" data-bind="checkedButtons: checkboxArray" class="btn btn-small">select a</button>
<button data-value="b" data-toggle="checkbox" data-bind="checkedButtons: checkboxArray" class="btn btn-small">select b</button>
</div>
<br>
<pre data-bind="text: ko.toJSON($root, null, 3)"></pre>
CSS
body { margin: 10px;}
JavaScript
ko.bindingHandlers['checkedButtons'] = {
'init': function (element, valueAccessor, allBindingsAccessor) {
var type = element.getAttribute('data-toggle') || 'radio';
var updateHandler = function () {
var valueToWrite;
var isActive = !!~element.className.indexOf('active');
var dataValue = element.getAttribute('data-value');
if (type == "checkbox") {
valueToWrite = !isActive;
} else if (type == "radio" && !isActive) {
valueToWrite = dataValue;
} else {
return; // "checkedButtons" binding only responds to checkbox and radio data-toggle attribute
}
var modelValue = valueAccessor();
if ((type == "checkbox") && (ko.utils.unwrapObservable(modelValue) 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 existingEntryIndex = ko.utils.arrayIndexOf(ko.utils.unwrapObservable(modelValue), dataValue);
if (!isActive && (existingEntryIndex < 0))
modelValue.push(dataValue);
else if (isActive && (existingEntryIndex >= 0))
modelValue.splice(existingEntryIndex, 1);
} else {
if (modelValue() !== valueToWrite) {
modelValue(valueToWrite);
}
}
};
ko.utils.registerEventHandler(element, "click", updateHandler);
},
'update': function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var type = element.getAttribute('data-toggle') || 'radio';
if (type == "checkbox") {
if (value instanceof Array) {
// When bound to an array, the...