Knockout Buttonset Binding
Allows radio buttons & checkboxs that are being displayed with using jQueryUi's buttonset.
HTML
<link rel="stylesheet" href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.10/themes/ui-darkness/jquery-ui.css">
<script src="http://knockoutjs.com/js/knockout-1.2.1.js"></script>
<form>
<p>Using "checked" binding</p>
<div class="buttonSetTest">
<input type="radio" id="radio1a" name="radioChk" value='y' data-bind='checked: radio'/>
<label for="radio1a">Yes</label>
<input type="radio" id="radio2a" name="radioChk" checked="checked" value='n' data-bind='checked: radio'/>
<label for="radio2a">No</label>
<input type="radio" id="radio3a" name="radioChk" value='M' data-bind='checked: radio'/>
<label for="radio3a">Maybe</label>
</div>
<p>Using "buttonset" binding</p>
<div class="buttonSetTest">
<input type="radio" id="radio1" name="radio" value='y' data-bind='buttonset: radio'/>
<label for="radio1">Yes</label>
<input type="radio" id="radio2" name="radio" checked="checked" value='n' data-bind='buttonset: radio'/>
<label for="radio2">No</label>
<input type="radio" id="radio3" name="radio" value='M' data-bind='buttonset: radio'/><label for="radio3">Maybe</label>
</div>
<p>Let's try normal buttons bound to same value</p>
<div id="normalButtons">
<input type="radio" id="normalRb1" name="radio1" value='y' data-bind='checked: radio'/><label for="normalRb1">Yes</label>
<input type="radio" id="normalRb2" name="radio1" checked="checked" value='n' data-bind='checked: radio'/>
<label for="normalRb2">No</label>
<input type="radio" id="normalRb3" name="radio1" value='M' data-bind='checked: radio' />
<label for="normalRb3">Maybe</label>
</div>
<p> Current Radiobutton Value = <span data-bind='text: radio' ></span></p>
<p>Do checkboxes</p>
<p><input type='checkbox' id='cbStyled' name='cbStyled' data-bind='buttonset: cb'><label for='cbStyled' data-bind>Styled Cb </label></p>
<p> <input...
JavaScript
$('.buttonSetTest').buttonset();
$('#cbStyled').button();
ko.bindingHandlers['buttonset'] = {
'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();
if ((element.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), element.value);
if (element.checked && (existingEntryIndex < 0)) modelValue.push(element.value);
else if ((!element.checked) && (existingEntryIndex >= 0)) modelValue.splice(existingEntryIndex, 1);
} else if (ko.isWriteableObservable(modelValue)) {
if (modelValue() !== valueToWrite) { // Suppress repeated events when there's nothing new to notify (some browsers raise them)
modelValue(valueToWrite);
}
} else {
var allBindings = allBindingsAccessor();
if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['checked']) {
allBindings['_ko_property_writers']['checked'](valueToWrite);
}
}
};
ko.utils.registerEventHandler(element, "click", updateHandler);
// IE 6 won't allow radio buttons to be selected unless they have a name
if...