Reputation: 592
I am trying to create a group of checkboxes with one button that is used to uncheck all the checkboxes when selected using knockout. I have seen this functionality with a checkbox to select/deselect all other checkboxes but I want this button to be a radio button so it cannot be unchecked but I want it to automatically uncheck when any of the checkboxes are checked.
My problem with the code below is that the read function is called before the write function so when I click on the radio button, it reads that a checkbox is checked and then clears the checkboxes. So I need to selected it twice to get it to update.
My code is as follows:
JS:
function AppViewModel() {
var self = this;
self.fruits = ko.observableArray([
{name : 'Apple', selected : ko.observable(false)},
{name : 'Banana', selected : ko.observable(false)},
{name : 'Coconut', selected : ko.observable(false)}
]);
self.fruitGroup = ko.computed({
read : function() {
var someSelected = false;
var fruitsArray = self.fruits();
fruitsArray.forEach(function(fruit){
if (fruit.selected()) {
someSelected = true;
}
});
return !someSelected;
},
write : function(newState) {
var fruitsArray = self.fruits();
fruitsArray.forEach(function (fruit){
fruit.selected(false);
});
return true;
}
});
}
ko.applyBindings(new AppViewModel());
HTML:
<input type="radio" data-bind="checked: fruitGroup"/>
<label>None</label>
<hr/>
<div data-bind="foreach: fruits">
<div>
<input type="checkbox" data-bind="checked: selected, attr: {id: name}"/>
<label data-bind="text: name, attr: {for: name}">Fruit</label>
</div>
</div>
http://jsfiddle.net/dp3jngmu/1/
Upvotes: 1
Views: 1632
Reputation: 23372
Radio buttons aren't meant to be unchecked after one of the group's items is checked. The only reason they can start out unchecked, is to not force defaults upon the user. (https://ux.stackexchange.com/questions/13511/why-is-it-impossible-to-deselect-html-radio-inputs)
To circumvent this (UX) issue, I'd advice to use a checkbox.
<input type="checkbox" data-bind="checked: fruitGroup"/>
If you don't want the user to be able to uncheck this box, leaving it unclear what the app's current state is, you could use the enable
or disable
data-bind:
<input type="checkbox" data-bind="checked: fruitGroup, disable: fruitGroup"/>
Check out these minor updates here: http://jsfiddle.net/uprk0qm6/
If you really want to go against the UX patterns and fix it with a radio button, I guess you'd have to create a custom binding to remove the 'checked' property from the element. Or find out a way to re-insert the element after each update. For example, by using if
data-binds and click
bindings: http://jsfiddle.net/h2xca0wr/ (this will reset your keyboard/tab based navigation and probably bring up some other accessibility issues)
Upvotes: 1