Zachary Scott
Zachary Scott

Reputation: 21162

Knockout js: Code to bind an object rather than individual values

This puts a checkbox next to each item of a list where changing the checked status adds/removes that value from the SelectedItems array:

<script type="text/x-jquery-tmpl" id="tmpl">
    <input name="cSelect" 
           type="checkbox"
           value="${ ID }"
           data-bind="checked: VM.SelectedItems" />
    <!-- Add other item content here -->
</script>

VM.SelectedItems = ko.observeableArray([]);

At any point, SelectedItems contains the ids of the checked items.

What if I wanted the checkbox to add and remove an object to SelectedItems? For example, I want to store an actual object of { id : 3, checked : true } instead of serializing it for the value attribute?

Upvotes: 2

Views: 3098

Answers (3)

jesal
jesal

Reputation: 7938

With KnockoutJS 3.0.0 you can use the checkedValue parameter:

<input name="cSelect" type="checkbox" value="${ ID }" data-bind="checkedValue: $data, checked: VM.SelectedItems" />

If your binding also includes checkedValue, this defines the value used by the checked binding instead of the element’s value attribute. This is useful if you want the value to be something other than a string (such as an integer or object), or you want the value set dynamically.

More details in the documentation

Upvotes: 1

muthuvel
muthuvel

Reputation: 1132

We can use like

<input type="checkbox" data-bind="attr: {value: JSON.parse($data).Id}, checked: $root.selectedIds"/>

and write a click event in the checkbox to get a selected data or subscripe method for selectedIds and get the selected id entire details as a JSON and we have to use JSON.parse to get the data.

but I don't how to store entire object with out JSON.

Upvotes: -1

RP Niemeyer
RP Niemeyer

Reputation: 114792

When using the checked binding against an array, it will only work with an array of primitives.

One option is to create a computed observable that builds your array of objects from the selected ids.

var ViewModel = function() {
    var self = this;
    this.items = [{id: 1, name: "one"}, {id: 2, name: "two"}, {id: 3, name: "three"}];
    this.selectedIds = ko.observableArray();
    this.selectedItems = ko.computed(function() {
        return ko.utils.arrayMap(self.selectedIds(), function(id) {
            return ko.utils.arrayFirst(self.items, function(item) {
                return item.id == id; //selected id will be a string
            }); 
        });
    });                                                           
};

ko.applyBindings(new ViewModel());

If you are dealing with a large number of items, then you might want to build an object that is an index of the items by key, so that you can loop through selectedIds and directly grab each object to reduce the amount of looping.

Here is a sample: http://jsfiddle.net/rniemeyer/pQQsY/

Upvotes: 6

Related Questions