Dynamically set table columns from ko.observableArray

I am trying to display a data table based on ko.observableArray where the returned columns are not defined in advance.

A sample element from my observable array self.userData()[0] will look like this:

 Object { RowNum: 1, ID: "123", Surname: "Bloggs", Forename: "Joe", Address line 1: "1 Park Lane" } 

These columns will differ each time based on what the user has selected for output.

I want the column headers in my output to be determined by what is present in the array, so my desired result is:

 <table> <thead> <tr> <th>RowNum</th> <th>ID</th> <th>Surname</th> <th>Forename</th> <th>Address line 1</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>123</td> <td>Bloggs</td> <td>Joe</td> <td>1 Park Lane</td> </tr> <!-- repeated for each row --> </tbody> </table> 

I know that I can use foreach to repeat rows and columns, but I'm not sure how to refer to it dynamically depending on what is present in my observableArray .

At the moment, I have this basic structure:

 <table> <thead> <tr data-bind="foreach: userData [property name] "> <th> <span data-bind="text: [property name]"></span> </th> </tr> </thead> <tbody data-bind="foreach: userData"> <tr data-bind="foreach: userData [property name]> <td data-bind="text: [property value]"> </td> </tr> </tbody> </table> 
+7
knockout-mvc
source share
1 answer

You can do it:

JS:

 var VM = function () { var self = this; self.items = ko.observableArray(); 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 data-bind="foreach: items"> <tr data-bind="foreach: $parent.columnNames"> <td data-bind="text: $parent[$data]"></td> </tr> </tbody> </table> 

See violin

Hope this helps.

+15
source share

All Articles