Click here to Skip to main content
13,512,345 members
Click here to Skip to main content
Add your own
alternative version


8 bookmarked
Posted 15 Jun 2014

Knockout Data-binding to Table with rowspan

, 15 Jun 2014
Rate this:
Please Sign up or sign in to vote.
Knockout Data-binding to Table with rowspan


Using foreach data binding in knockout, we can easily bind data to a table. But the trike part comes when we need to use rowspan in table. An example could be as simple as below or could be even more complex one, when we are using rowspans to make data more presentable to the user.


To accomplish our goal, we are going to use:

  1. Regular foreach data binding
  2. Container less data binding to bind additional data
  3. attr data binding to specify the rowspan

Using the Code

For a quick preview, checkout

Let’s specify some models which we are going to use in the model binding.

function Subject(name, mark) { = name;
    this.mark = parseFloat(mark).toFixed(2);       

function Student(name, regNo, subjects) { = name;
    this.regNo = regNo;
    this.subjects = subjects;
    this.totalMark = function() {
        var total = parseFloat(0);
        $.each(subjects, function(i) {
            total += parseFloat(subjects[i].mark);
        return parseFloat(total).toFixed(2);
    this.average = function() {
        var avg = this.totalMark() / parseFloat(subjects.length);
        return parseFloat(avg).toFixed(2);
    this.rowSpan = subjects.length + 1;             // + 1 is important

Here is our view model where self.init() is populating the binding data.

/*View Model*/
function ViewModel() {
    var self = this;
    self.students = ko.observableArray([]);

    self.init = function () {
        var subjects = [
            new Subject('Math', 50),
            new Subject('Physics', 50),
            new Subject('Chemistry', 50)
        var students = [
            new Student('Alan', 'Std-01', subjects),
            new Student('Scott', 'Std-01', subjects),
            new Student('John', 'Std-01', subjects)

Finally, we are going to apply binding for the view model:

/*binding view model*/
$(document).ready(function() {
    var vm = new ViewModel();
    vm.init();            //populates the binding data

Now let’s hook this view model to HTML table.

  1. <tbody data-bind="foreach: students"> - is just the regular binding
  2. <!-- ko foreach: subjects --> <!-- /ko --> - is the important container less binding for row murching
  3. attr: { rowspan: rowSpan } - is the rowspan binding to use rowspan in the table
            <th>Student Name</th>
            <th>Student Reg No.</th>
            <th>Subject Name</th>
            <th>Obtained Marks</th>
            <th>Total Marks</th>
            <th>Average Marks</th>
    <tbody data-bind="foreach: students">
            <td data-bind="text: name, attr: { rowspan: rowSpan }"></td>
            <td data-bind="text: regNo, attr: { rowspan: rowSpan }"></td>
            <!--important to user class hidden to hide the cell-->
            <td class="hidden"></td>         
            <td class="hidden"></td>
            <td data-bind="text: totalMark(), attr: { rowspan: rowSpan }"></td>
            <td data-bind="text: average(), attr: { rowspan: rowSpan }"></td>

        <!--knockout Containerless Binding-->
        <!-- ko foreach: subjects -->               
            <!--important to user class hiddenTop to hide top border-->
            <td class="hiddenTop" data-bind="text: name"></td>
            <td class="hiddenTop" data-bind="text: mark"></td>
        <!-- /ko -->

Now in the header section, let’s specify some styles so that our table may have a fresh and clean look. Here are some styles that are really important to use:

  1. td.hidden - hides unnecessary cells
  2. td.hiddenTop - hides unnecessary top border from cells
    table {
        border: 1px solid black;
        border-collapse: collapse;
        width: 700px;
    thead {
        font-size: 15px;
        font-weight: bold
    tbody {
        font-size: 15px;
        font-weight: normal
    td, th {
        border: 1px solid black;
        text-align: center;
        padding: 10px;
    td.hidden {
        border-width: 0px;
        padding: 0px;
    td.hiddenTop {
        border-top-width: 0px;

Find the VS 2010 solution in the attachment.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Bangladesh Bangladesh
No Biography provided

You may also be interested in...

Comments and Discussions

-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.180417.1 | Last Updated 15 Jun 2014
Article Copyright 2014 by DiponRoy
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid