knockout radio button binding
by photo_tom
HTML
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b1/jquery.mobile-1.0b1.min.css">
<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-1.2.1.js"></script>
<script src="http://code.jquery.com/mobile/1.0b1/jquery.mobile-1.0b1.min.js"></script>
<!DOCTYPE html>
<html>
<body>
<div data-role="page" data-theme="b" id="pageOne">
<div data-role="header">
<h4>Test</h4>
</div>
<div data-role="content">
<fieldset data-role="controlgroup">
<legend>Disable Radios:</legend>
<div class="mycheckradio" data-role="button" data-icon="myCheckRadioOff" data-bind="jqmChecked: bigCheck">Yes</div>
</fieldset>
<fieldset data-role="controlgroup">
<legend><b>Radio One:</b></legend>
<div class="mycheckradio" data-role="button" data-value="1" data-icon="myCheckRadioOff" data-bind="myDisable: bigCheck, jqmRadio: radioOne">Choice 1</div>
<div class="mycheckradio" data-role="button" data-value="0" data-icon="myCheckRadioOff" data-bind="myDisable: bigCheck, jqmRadio: radioOne">Choice 2</div>
</fieldset>
<fieldset data-role="controlgroup">
<legend><b>Radio Two:</b></legend>
<div class="mycheckradio" data-role="button" data-value="1" data-icon="myCheckRadioOff" data-bind="myDisable: bigCheck, jqmRadio: radioTwo">Choice 1</div>
<div class="mycheckradio" data-role="button" data-value="0" data-icon="myCheckRadioOff" data-bind="myDisable: bigCheck, jqmRadio: radioTwo">Choice 2</div>
</fieldset>
<div>bigCheck = <span data-bind="text: bigCheck"></span></div>
<div>radioOne = <span data-bind="text: radioOne"></span></div>
<div>radioTwo = <span data-bind="text: radioTwo"></span></div>
</div>
</div>
</body>
</html>
CSS
div.mycheckradio { text-align: left; }
.mycheckradio span { padding-left: 43px; white-space: nowrap; display: inline-block; }
.disabled { background: gray; color: darkgray; }
.ui-icon-myCheckRadioOn {
background: url(images/vac-check-on.png) no-repeat center;
/* for testing on jsfiddle only as images cannot be uploaded - this also messes up width as images are only 25x25px */
background-color: green;
}
.ui-icon-myCheckRadioOff {
background: url(images/vac-check-off.png) no-repeat center;
/* for testing on jsfiddle only as images cannot be uploaded - this also messes up width as images are only 25x25px */
background-color: darkblue;
}
JavaScript
var viewModel = {
bigCheck: ko.observable(false),
radioOne: ko.observable(""),
radioTwo: ko.observable("1")
};
// my checkboxes handler
ko.bindingHandlers.jqmChecked = {
init: function(element, valueAccessor) {
// Get the observable we are bound to
var modelValue = valueAccessor();
// register handler for changes
$(element).click(function() {
// update model data
if(ko.utils.unwrapObservable(modelValue)) { modelValue(false); }
else { modelValue(true); }
});
},
update: function(element, valueAccessor) {
// First get the latest data that we're bound to
var value = valueAccessor();
// Next, whether or not the supplied model property is observable, get its current value
var valueUnwrapped = ko.utils.unwrapObservable(value);
// Now manipulate the DOM element to toggle check mark
if(valueUnwrapped) {
$(element).find('.ui-icon').addClass('ui-icon-myCheckRadioOn').removeClass('ui-icon-myCheckRadioOff');
}
else {
$(element).find('.ui-icon').addClass('ui-icon-myCheckRadioOff').removeClass('ui-icon-myCheckRadioOn');
}
}
};
// my radio buttons handler
ko.bindingHandlers.jqmRadio = {
init: function(element, valueAccessor) {
// Get the observable we are bound to
var modelValue = valueAccessor();
// register handler for changes
$(element).click(function() {
if(! $(this).hasClass("disabled")) {
// Set model to data value of element
modelValue(''+$(this).data("value"));
}
});
},
update: function(element, valueAccessor) {
// First get the latest data that we're bound to
var value = valueAccessor();
// Next, whether or not the supplied model property is observable, get its current value
var valueUnwrapped = ko.utils.unwrapObservable(value);
...