Related to: Bootstrap Radio Button Group
HTML:
<div class="btn-group" data-toggle="buttons"> <label class="btn btn-primary"> <input type="radio" name="options" id="option1" value="1" data-bind="checked: optionsValue"> Option 1 </label> <label class="btn btn-primary"> <input type="radio" name="options" id="option2" value="2" data-bind="checked: optionsValue"> Option 2 </label> <label class="btn btn-primary"> <input type="radio" name="options" id="option3" value="3" data-bind="checked: optionsValue"> Option 3 </label> </div> <br /> <span data-bind="text: optionsValue"></span>
Javascript:
var ViewModel = function() { this.optionsValue = ko.observable() }; ko.applyBindings(new ViewModel());
JsFiddle:
I have the above code which I'm trying to get working as I expect it to. The problem is that when data-toggle="buttons"
is added to the btn-group div (as in the Bootstrap 3 example) the knockout binding stops working. If I leave the data-toggle off of the buttons group then the binding works as expected but the button group looks awful. I know that this didn't work in Bootstrap 2 because they didn't actually use the radio input for their radio styling. How come it refuses to work now even though they do?
The bootstrap buttons and the knockout checked
binding are still not playing nice:
click
event inside the checked
binding to tigger the underlaying observable to changee.preventDefault()
so KO won't be notified about the click.One possible solution is to create a custom binding handler where you subscribe on the change
event (this is fired by bootstrap on toogle) and set your observables value there:
ko.bindingHandlers.bsChecked = { init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var value = valueAccessor(); var newValueAccessor = function () { return { change: function () { value(element.value); } } }; ko.bindingHandlers.event.init(element, newValueAccessor, allBindingsAccessor, viewModel, bindingContext); }, update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { if ($(element).val() == ko.unwrap(valueAccessor())) { setTimeout(function () { $(element).closest('.btn').button('toggle'); }, 1); } } }
And use it in your view with:
<label class="btn btn-primary"> <input type="radio" name="options" id="option1" value="1" data-bind="bsChecked: optionsValue"> Option 1 </label>
Original demo using Bootstrap 3.0.2 JSFiddle.
Updated demo using Bootstrap 3.2.0 JSFiddle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With