8
votes

This is working:

view.html

<div><input type="radio" name="radioPriority" data-bind="checked: priority" value="want" style="margin-top: -3px; margin-right: 3px;" />I want to</div>
<div><input type="radio" name="radioPriority" data-bind="checked: priority" value="need"  style="margin-top: -3px; margin-right: 3px;"/>I need to</div>

controller.js

function feedbackViewModel() {
    var self = this;
    self.priority = ko.observable("want");
    //lots of other stuff
}

As expected, when you select the second radio the priority observable's value changes to "need". However, I'd like to use a Twitter Bootstrap button group as a radio. Here is the HTML I have, but it does not change the observable as expected:

<span class="btn-group" data-toggle="buttons-radio">
    <button data-bind="checked: priority" type="button" class="btn" value="want">I want to</button>
    <button data-bind="checked: priority" type="button" class="btn" value="need">I need to</button>
</span>

update I have a jsfiddle going here: http://jsfiddle.net/a8wa8/6/ "priority1" is the standard radio selects and "priority2" is the bootstrap buttons.

2

2 Answers

9
votes

The issue is that you are using Checked binding with button which is not allowed, instead you can use click binding. check this fiddle:

http://jsfiddle.net/a8wa8/7/

Updated:

Yes you can achieve this by using ko css binding. Check this updated fiddle:

Updated Fiddle

6
votes

The checked binding only works with "checkable" controls like checkbox (<input type='checkbox'>) or a radio button (<input type='radio'>).

But you have button in your second example where bootstrap just emulates the look of the radio button group so the checked binding doesn't work.

However you can use the click binding where you pass the value to your observable:

<span class="btn-group" data-toggle="buttons-radio">
     <button data-bind="click: function() { priority2('want') }" 
             type="button" class="btn" value="want">I want to</button>
     <button data-bind="click: function() { priority2('need') }" 
             type="button" class="btn" value="need">I need to</button>    
</span>

And you can hide this behind a custom binding:

ko.bindingHandlers.valueClick = {
    init: function(element, valueAccessor, allBindingsAccessor, 
                  viewModel, bindingContext) {     
        var value = valueAccessor();
        var newValueAccessor = function() {
            return function() {
                value(element.value); 
            };
        };
        ko.bindingHandlers.click.init(element, newValueAccessor, 
            allBindingsAccessor, viewModel, bindingContext);
    },
}

Then you can use it like:

<span class="btn-group" data-toggle="buttons-radio">
     <button data-bind="valueClick: priority2" 
             type="button" class="btn" value="want">I want to</button>
     <button data-bind="valueClick: priority2" 
             type="button" class="btn" value="need">I need to</button>    
</span>

Demo JSFiddle.