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);
...