Knockout Buttonset Binding

Allows radio buttons & checkboxs that are being displayed with using jQueryUi's buttonset.

by photo_tom

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>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0rc1/jquery.mobile-1.0rc1.min.css">
<form>
    <div data-role="fieldcontain">
        <fieldset data-role="controlgroup">
            <legend>Using "checked" binding</legend>
            <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>
        </fieldset>
    </div>
    <div data-role="fieldcontain">
        <fieldset data-role="controlgroup">
            <legend>Using "buttonset" binding</legend>
            <input type="radio" id="radio1" name="radio" value='y' data-bind='jMobileClick: radio'/>
            <label for="radio1">Yes</label>
            <input type="radio" id="radio2" name="radio" checked="checked" value='n'  data-bind='jMobileClick: radio'/>
            <label for="radio2">No</label>
            <input type="radio" id="radio3" name="radio"   value='M'  data-bind='jMobileClick: radio'/>
            <label for="radio3">Maybe</label>
        </fieldset>
    </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='jMobileClick: cb'><label for='cbStyled' data-bind>Styled Cb </label></p>
    <p> <input type='checkbox' id='cbUnStyled' name='cbUnStyled' data-bind='checked: cb'><label for='cbUnStyled' data-bind>Normal CB Binding</label></p>
</form>

CSS

p{padding: 5px}

JavaScript

$('#cbStyled').button();


ko.bindingHandlers['jMobileClick'] = {
    'init': function(element, valueAccessor, allBindingsAccessor) {
        ko.bindingHandlers.checked.init(element, valueAccessor, allBindingsAccessor);
    },

    'update': function(element, valueAccessor) {

        var buttonSet = function(element) {
            // now update the css classes
            // Normally when knockout updates button, there
            // isn't an event to transfer new status
            // to buttonset label
            var buttonId = $(element).attr('id');
            if (buttonId) {
                var buttonSetDiv = $(element).parent('.ui-controlgroup-controls');
                var elementLabel = $(buttonSetDiv).find('label[for="' + buttonId + '"]');
                if (elementLabel.length === 0) {
                    // was just a single button, so look for label
                    elementLabel = $(element).parent('*').find('label[for="' + buttonId + '"]');
                }
                // check to see if element is already configured
                if (element.checked && !$(elementLabel).hasClass('ui-radio-off')) {
                    $(elementLabel).removeClass('ui-radio-off');
                    $(elementLabel).addClass('ui-radio-on');
                }
                if (!element.checked && $(elementLabel).hasClass('ui-state-active')) {
                     $(elementLabel).removeClass('ui-radio-on');
                    $(elementLabel).addClass('ui-radio-off');
                }
            }
        };

        ko.bindingHandlers.checked.update(element, valueAccessor);
        //buttonSet(element);
        $(element).checkboxradio("refresh");
    }
};


var viewModel = {
    radio: ko.observable('M'),
    cb: ko.observable('true')
};

ko.applyBindings(viewModel);