Table binding with dynamic columns examples

2,069 views
Skip to first unread message

Keith Reimer

unread,
Oct 19, 2012, 2:58:51 PM10/19/12
to knock...@googlegroups.com
I searched and didn't see this anywhere, so I made up a couple jsfiddles for it and thought I'd post it for others.  2 different variations.  Hope it helps. 
- Keith

1st Version:  Method on the object to get a column value:
http://jsfiddle.net/keithr/AY3Cp/4/

In the example, I have a columns observableArray and a rows observableArray.  The table's header is bound to the columns array.  Then the body does a foreach on the rows array.  Within that is a nested array that refers back out to the columns, which then calls the row object with the column name to get the value for that column for that row instance.  


HTML
<table>
    <thead>
    <tr data-bind="foreach: columns">        
        <th data-bind="text: name"></th>
    </tr>
    </thead>
    <tbody data-bind="foreach: rows">
        <tr data-bind="foreach: $root.columns">   
            <!-- At this level in the binding the row object is now $parent, and the column is now $data -->        
            <td data-bind="text: $parent.getColumnValue($data)"></td>
        </tr>
    </tbody>
</table>

JS

var item function(val{
    var name val;
    this.getColumnValue function(col{
        // TODO: Real check for value for col name.
        return col.name "_val_" name;
    };
}
var viewModel {
    rowsko.observableArray(),
    columnsko.observableArray(
};

for (var 06i++{
    viewModel.columns.push({name'col' });
    viewModel.rows.push(new item('test' i));  
}
ko.applyBindings(viewModel);


 
2nd version: Object to define column header and property on row object to use:

This make the column object more robust with a propertyName and columnHeader properties.  It then binds the table row headers to columnHeader, and bind the row cells to the propertyName on the object.  Then your row object just has to have properties with all the propertyName values

HTML
<table>
    <thead>
    <tr data-bind="foreach: columns">        
        <th data-bind="text: columnHeader"></th>
    </tr>
    </thead>
    <tbody data-bind="foreach: rows">
        <tr data-bind="foreach: $root.columns">   
            <!-- At this level in the binding the row object is now $parent, and the column is now $data -->        
            <td data-bind="text: $parent[$data.propertyName]"></td>
        </tr>
    </tbody>
</table>

JS

var column function(i){
    this.propertyName 'Prop' i;
    this.columnHeader 'Col ' i;
}    
var item function(val{
    this.Prop0 'p1_' val;
    this.Prop1 'p2_' val;
    this.Prop2 'p3_' val;
    this.Prop3 'p4_' val;
    this.Prop4 'p5_' val;
    this.Prop5 'p6_' val;
}    
var viewModel {
    rowsko.observableArray(),
    columnsko.observableArray(
};
for (var 06i++{
    viewModel.columns.push(new column(i));
    viewModel.rows.push(new item('test' i));  
}
ko.applyBindings(viewModel);


Keith Reimer

unread,
Oct 19, 2012, 3:10:13 PM10/19/12
to knock...@googlegroups.com
Sorry, 2nd fiddle link is wrong.  Here's a better one:  http://jsfiddle.net/keithr/cBJyA/
Reply all
Reply to author
Forward
0 new messages