user2424495
user2424495

Reputation: 592

uncheck checkboxes with radio button using knockout

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

Answers (1)

user3297291
user3297291

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

Related Questions