The app I'm working on should allows it's users to create tables. I have a view in which users are able to create a table. They should be able to define here the table's columns. The columns that the user adds will be part from some predefined types of columns: BusinessFields, SourceKeys, SourceAttrs,...; At the same time columns should have some other proprieties that define the value they will contain: minlength, minValue, defaultValue,...These tables have to have a format(at least a column for the SourceKeys and TargetKeys categories), but this format is not so restrictive. The image will help to describe the point:I have made it work as you see in the image, but I don't like how I've made the bindings. My code design also reduces the flexibility (For example: It would be much more difficult to add a click binding for a row). JavaScript://column definitionfunction Column(columnName, minLength, maxLength, minValue, maxValue, reg_ex, role, order, defaultValue) {    var self = {};    self.name = ko.observable(columnName || 'new column');    self.minLength = ko.observable(minLength || null);    self.maxLength = ko.observable(maxLength || null);    self.minValue = ko.observable(minValue || null);    self.maxValue = ko.observable(maxValue || null);    self.reg_exp = ko.observable(reg_ex || null);    self.role = ko.observable(role ? role : 1);    self.order = ko.observable(order || null);    self.defaultValue = ko.observable(defaultValue || null);    return self;}//table definitionfunction Table() {    var self = {};    self.tableName = ko.observable('New table');    self.tableDescription = ko.observable('description');    self.businessFields = ko.observableArray([]);    self.sourceKeys = ko.observableArray([]);    self.sourceAttr = ko.observableArray([]);    self.targetKeys = ko.observableArray([]);    self.targetAttr = ko.observableArray([]);    self.attrFields = ko.observableArray([]);    self.technicalFields = ko.observableArray([]);    return self;}//the tablevar newTable = ko.observable(Table());//adding columns to the tablenewTable.businessFields.push(Column('col_1'));HTML: (only enough tho get the idea) <table class=table table-bordered>                <thead>                    <tr>                        <th></th>                        <th>Name</th>                        <th>Min Length</th>                        <th>Max Length</th>                        <th>Min Value</th>                        <th>Max Value</th>                        <th>Regular Expr</th>                        <th>Default Value</th>                    </tr>                </thead>                <tbody data-bind=with: newTable>                    <tr>                        <td data-bind=attr: { rowspan: function(){ if(businessFields().length == 0) return 1; else return businessFields().length; }()}>Business fields</td>                        <!-- ko if: businessFields().length > 0 -->                        <td><strong data-bind=text: businessFields()[0].name></strong></td>                        <td><span data-bind=text: businessFields()[0].minLength></span></td>                        <td><span data-bind=text: businessFields()[0].maxLength></span></td>                        <td><span data-bind=text: businessFields()[0].minValue></span></td>                        <td><span data-bind=text: businessFields()[0].maxValue></span></td>                        <td><span data-bind=text: businessFields()[0].reg_exp></span></td>                        <td><span data-bind=text: businessFields()[0].defaultValue></span></td>                        <!-- /ko -->                    </tr>                    <!-- ko foreach:  businessFields -->                    <!-- ko if: $index() !== 0 -->                    <tr>                        <td><strong data-bind=text: name></strong></td>                        <td><span data-bind=text: minLength></span></td>                        <td><span data-bind=text: maxLength></span></td>                        <td><span data-bind=text: minValue></span></td>                        <td><span data-bind=text: maxValue></span></td>                        <td><span data-bind=text: reg_exp></span></td>                        <td><span data-bind=text: defaultValue></span></td>                    </tr>                    <!-- /ko -->                    <!-- /ko -->                    <tr>                        <td data-bind=attr: { rowspan: function(){ if(sourceKeys().length == 0) return 1; else return sourceKeys().length; }()}>Source keys</td>                        <!-- ko if: sourceKeys().length > 0 -->                        <td><strong data-bind=text: sourceKeys()[0].name></strong></td>                        <td><span data-bind=text: sourceKeys()[0].minLength></span></td>                        <td><span data-bind=text: sourceKeys()[0].maxLength></span></td>                        <td><span data-bind=text: sourceKeys()[0].minValue></span></td>                        <td><span data-bind=text: sourceKeys()[0].maxValue></span></td>                        <td><span data-bind=text: sourceKeys()[0].reg_exp></span></td>                        <td><span data-bind=text: sourceKeys()[0].defaultValue></span></td>                        <!-- /ko -->                    </tr>                    <!-- ko foreach:  sourceKeys -->                    <!-- ko if: $index() !== 0 -->                    <tr>                        <td><strong data-bind=text: name></strong></td>                        <td><span data-bind=text: minLength></span></td>                        <td><span data-bind=text: maxLength></span></td>                        <td><span data-bind=text: minValue></span></td>                        <td><span data-bind=text: maxValue></span></td>                        <td><span data-bind=text: reg_exp></span></td>                        <td><span data-bind=text: defaultValue></span></td>                    </tr>                    <!-- /ko -->                    <!-- /ko -->                    ......                    ......Do you have any ideas on how could I bind to represent this 2D table? The JavaScript design is not a restriction, because I was thinking that storing the columns in different arrays is not a good idea for dynamic data. Maybe each column should have a variable that would identify from which category takes part. Therefore, the newTable object should be redesigned.
Knockout.js binding 2D table with rowspan
javascript;knockout.js
I would just add a columnGroup attribute to Column and then do a groupBy-type operation on that attribute. That would reduce your Table view-model to just a collection of Rows, which would be nice. Here's what I'm thinking for Columnfunction Column(columnName, columnGroup /* ... all your other attributes ... */) {    var self = {};    self.name = ko.observable(columnName || 'new column');    self.groupName = ko.observable(columnGroup || 'Misc.');    /* all your other boilerplate setting */    return self;}// returns a group object, which has a name and an array of items.// this will only be created once in the groups array.function ensureGroup (groups, groupName) {    var foundGroup;    groups.some(function (group) {        if (group.name === groupName) {            return foundGroup = group;        }    });    if (!foundGroup) {        foundGroup = {            name: groupName,            items: []        };        groups.push(foundGroup);    }    return foundGroup;}function Table() {    var self = {};    self.tableName = ko.observable('New table');    self.tableDescription = ko.observable('description');    self.columns = ko.observableArray([]);    self.columnGroups = ko.computed(function () {        var groups = self.columns().reduce(function (groups, column) {            var group = ensureGroup(groups, column.fieldGroup();            group.items.push(column);        }, []);        return groups;    });    return self;}You then just have to iterate over table.columnGroups in your template. Of course, this code is untested, and there are certainly ways to clean it up more, but I wanted to give you an approach to work from.