GraemeMiller
GraemeMiller

Reputation: 12273

How can I merge table cells with same content in Knockoutjs?

I am trying to create table with Knockoutjs. I want to merge table cells if the value of a propety of the cells is the same. I can't figure out how to do this.

I have the following code

<table id="EventTracker"> <tbody data-bind="template: { name: 'person-template', foreach: Person}"></tbody></table>
<script type="text/html" id="person-template">
    <tr><td data-bind="text: Name"></td><!-- ko template: { name: 'event-template', foreach: event }--> <!-- /ko --> </tr> 
</script>

<script type="text/html" id="event-template">
    <td data-bind="text: Label"></td>
</script>

The table is created fine. However I don't want individual cells displayed if the contents are the same in each. If the event that is being used to create the td is the same as the prior one I want to increase the colspan of the cell by 1. Effectively not creating an individual cell but merging them. E.g. If I have 3 cells with the same text they should merge and create a single td with a colspan of 3. I don't know how to code that in Knockoutjs.

Any ideas?

Upvotes: 1

Views: 3154

Answers (1)

RP Niemeyer
RP Niemeyer

Reputation: 114792

Rather than complicate the template, I would look to build a mapped version of your event data in your view model that would make binding easier.

A computed observable on your person objects might look like:

this.eventCells = ko.computed(function() {
    var current,
        result = [];

    ko.utils.arrayForEach(this.events(), function(event) {
        if (current && current.label() !== event.label()) {
            current = null;
        } 

        if (!current) {
            current = { label: event.label, count: 0 };   
            result.push(current);
        }

        current.count++;      
    });

    return result;   
}, this);

Now, you can foreach through eventCells and then bind like:

data-bind="text: label, attr: { colspan: count }"

Here is a sample: http://jsfiddle.net/rniemeyer/3g8jw/

Upvotes: 4

Related Questions