I have view model which i am using to bind to a table of results. The view dynamically renders the table of results without any prior knowledge of number or name of columns, which is great. Similar to that described here and in the interest of keeping generic and not domain specific i have adapted the code sample from that questions answer here.
However i need to add a filter row to allow the user to filter, i have added a row of inputs based on the column names in the code below and attempted to bind them to the view model. It is important that they are bound to the view model so that when i refresh the grid the view model knows about any filters applied.
I have tried a couple of things
- firstly as shown in code snippet below i have created an observable filter object and attempted to bind each field in the table to a property on that filter object. This however does not seem to work.
- another option i tried was to create an observable array of filter objects based on the column names and bind the filter columns to that which also didnt seem to work
Any thoughts would be greatly appreciated
Many thanks, Ed
JS
var VM = function () {
var self = this;
self.items = ko.observableArray();
self.filters = ko.observable({});
self.columnNames = ko.computed(function () {
if (self.items().length === 0)
return [];
var props = [];
var obj = self.items()[0];
for (var name in obj)
props.push(name);
return props;
});
};
var vm = new VM();
ko.applyBindings(vm);
vm.items.push({
'Name': 'John',
'Age': 25
});
vm.items.push({
'Name': 'Morgan',
'Age': 26
});
View :
<table>
<thead>
<tr data-bind="foreach: columnNames">
<th> <span data-bind="text: $data"></span>
</th>
</tr>
</thead>
<tbody >
<!-- add filter rows -->
<tr data-bind="foreach: $root.columnNames">
<td ><input type='text' data-bind="value: $root.filters[$data]"/></td>
</tr>
<!-- add the items -->
<!-- ko foreach: items -->
<tr data-bind="foreach: $parent.columnNames">
<td data-bind="text: $parent[$data]"></td>
</tr>
<!-- /ko -->
</tbody>
</table>