Skip to main content

Knockoutjs check/uncheck all checkboxes using header checkbox.

While working with Knockoutjs ViewModel, if we implement the select all checkbox feature using traditional JavaScript/JQuery, then in such scenario we can see that Knockoutjs observable property is not getting updated when all checkboxes are checked/unchecked.

To handle such situation, we can create Knockoutjs computed property (with read/write) and can bind it to header checkbox and there is no need to use the traditional JQuery. Below is the sample code to demonstrate the same:

As usual create the Knockoutjs ViewModel and then bind it to UI using ko.applyBindings
function CheckViewModel() {
    var self = this;
    self.Countries = ko.observableArray(                                                       [
                    new Country("Australia"),
                     new Country("India"),
                     new Country("Russia"),
                    new Country("United Kingdom"),
                    new Country("United States")                                                ]);

    self.SelectAll = ko.computed({
        read: function () {
            var country = ko.utils.arrayFirst(self.Countries(), function (ctr) {
                return !ctr.Selected();
            });
            return country == null;
        },
        write: function (value) {
            ko.utils.arrayForEach(self.Countries(), function (ctr) {
                ctr.Selected(value);
            });
        }
    }).extend({ throttle: 1 });
}
Country = function (name) {
    this.CountyName = name;
    this.Selected = ko.observable(false);
}
ko.applyBindings(new CheckViewModel());

Once Knockoutjs ViewModel is ready to use, create the HTML and use Knockout binding.
<table>
    <thead>
        <tr>
            <th>
              <input type="checkbox" data-bind="checked: SelectAll" />
              Select All Countries
            </th>
        </tr>
    </thead>
    <tbody data-bind="foreach: $data.Countries">
        <tr>
            <td>
              <input type="checkbox" data-bind="checked: Selected" />
              <label data-bind="text: CountyName"></label>
            </td>
        </tr>
    </tbody>
</table>

See highlighted part of HTML and Scripts, we are binding header checkbox with property SelectAll and this property will help us implementing the check/uncheck all checkboxes feature.

Note: There is problem of ordo n ^ 2 when selecting deselecting all if we use simple Knockoutjs computed property.
To handle this either we can use a pasuable computed property or we can also extend the computed with a throttle, as shown below and also used in our script.

.extend({ throttle: 1 })

You can also see the working jsfiddle of this example.

Comments