8
votes

I using knockout for mapping JSON obejct to user control, I have a list of single checkboxes, They look like

 <input type="checkbox" data-bind="checked: IsEnabled1" />

I Have JsonObject

 var viewModel = {
            IsEnabled1 :ko.observable(true),            
            IsEnabled2 :ko.observable(true),
            IsEnabled3 :ko.observable(false)
        };
  ...
  ko.applyBindings(viewModel);

And I want to add global check box that will be check/uncheck all other, I made this changes on JavaScript side but global check box update UI part but they data from separate check boxes doesn't mapping to JSON object .

Global checkbox

  $("#GeneralTable thead tr th:first input:checkbox").click(function () {
            var checkedStatus = this.checked;
            $("#GeneralTable tbody tr td:first-child input:checkbox").each(function () {
                this.checked = checkedStatus;                    
            });

        });

after this code my JSON object contain data that not related to UI.

How to update all JSON after change check boxes from JS side ?

2
The code you posted isn't enough for us to answer your question.Makram Saleh
Now should be better. Thanks.Arbejdsglæde
Problem in your code,that you interacts with nodes. But you need to interact with data. It is better in MVVM world :-) Please check my answer. I think it will work for you.Romanych

2 Answers

17
votes

Please check the example: http://jsfiddle.net/MenukaIshan/5gaLjh2c/

I think it is exactly what you need. All items have IsChecked observable property. ViewModel contains computed observable (readable and writeable) to check or uncheck all items.

3
votes

There is an alternative solution here http://jsfiddle.net/rniemeyer/kXYuU/

The solution above can be improved in two ways

-To make AllChecked false for empty lists, we need to check length

-To reduce the number recalculations when selecting all for a long list, we need to add throttle

self.AllChecked = ko.computed({
    read: function() {
        var firstUnchecked = ko.utils.arrayFirst(self.Items, function(item) {
            return item.IsChecked() == false;
        });
        return self.Items.length && !firstUnchecked;
    },
    write: function(value) {
        ko.utils.arrayForEach(self.Items, function(item) {
            item.IsChecked(value);
        });
    }
}).extend({ throttle: 1 });