Skip to content Skip to sidebar Skip to footer

Merge Equal Table Cells With Jquery

Simple html table with NxM values. The aim is to merge equal cells in column with jQuery. Note, that in one row there are no duplicates. I got how to hide the equal cells, but is

Solution 1:

If I get what you mean here, this my edited version: http://jsfiddle.net/djhU7/4/

So instead of $(this).text('') I did this:

    $($this.parent().prev().children()[index]).attr('rowspan', 2);
    $this.hide();

What I did, was the I set the rowspan of first cell to 2. This attribute "will indicates for how many rows the cell extends." which will make the above cell twice bigger, and I hid the cell with the duplicate information so the extra cell will go away. Note that removing the cell will ruin the index check for the next cell. This was a just a quick and dirty solution but rowspan attribute has to be used somewhere to achieve it.

Here's another version, that sets rowspan on the time when inserting the cells into the table, beside the fact that it works with 3 duplicate cells and more, it's also faster, because it avoids re-rendering of the table(though it can be optimized more, but I don't think at this moment you wanna care about it, premature optimization is the root of all evil!): http://jsfiddle.net/g7uY9/1/

for (var i = 0; i < obj.length; i++) {


   tr = $('<tr/>');

    addColumn(tr, 'columnA', i);
    addColumn(tr, 'columnB', i);
    addColumn(tr, 'columnC', i);
    $('#testTable').append(tr);

}

functionaddColumn(tr, column, i) {
    var row = obj[i],
        prevRow = obj[i - 1],
        td = $('<td>' + row[column] + '</td>');
    if (prevRow && row[column] === prevRow[column]) {
        td.hide();
    } else {
        var rowspan = 1;
        for (var j = i; j < obj.length - 1; j++) {
            if (obj[j][column] === obj[j + 1][column]) {
                rowspan++;
            } else {
                break;
            }
        }
        td.attr('rowspan', rowspan);
    }

    tr.append(td);
}

Solution 2:

Please find the improved answer for your query with row expand/collapse. Here is my fiddle:

functionMergeGridCells()
{
    var dimension_cells = newArray();
    var dimension_col = null;

    var i = 1;
    // First, scan first row of headers for the "Dimensions" column.
    $("#mytable").find('th').each(function () {
        if ($(this).text() == 'Id') {
            dimension_col = i;
        }
        i++;
    });

    // first_instance holds the first instance of identical tdvar first_instance = null;
    var rowspan=1;
    // iterate through rows
    $("#mytable").find('tr.parent-grid-row').each(function () {

        // find the td of the correct column (determined by the dimension_col set above)var dimension_td = $(this).find('td.parent-grid-column:nth-child(' + dimension_col + ')');

        if (first_instance == null) {
            // must be the first row
            first_instance = dimension_td;
        } elseif (dimension_td.text() == first_instance.text()) {
            // the current td is identical to the previous// remove the current td
            dimension_td.remove();
            ++rowspan;
            // increment the rowspan attribute of the first instance
            first_instance.attr('rowspan', rowspan);
        } else {
            // this cell is different from the last
            first_instance = dimension_td;
            rowspan=1;
        }
    });
}

Jquery Cell Merging

Solution 3:

Here's a runnable version of carla's answer:

functionSummerizeTable(table) {
  $(table).each(function() {
    $(table).find('td').each(function() {
      var $this = $(this);
      var col = $this.index();
      var html = $this.html();
      var row = $(this).parent()[0].rowIndex; 
      var span = 1;
      var cell_above = $($this.parent().prev().children()[col]);

      // look for cells one above another with the same textwhile (cell_above.html() === html) { // if the text is the same
        span += 1; // increase the span
        cell_above_old = cell_above; // store this cell
        cell_above = $(cell_above.parent().prev().children()[col]); // and go to the next cell above
      }

      // if there are at least two columns with the same value, // set a new span to the first and hide the otherif (span > 1) {
        // console.log(span);
        $(cell_above_old).attr('rowspan', span);
        $this.hide();
      }
      
    });
  });
}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><buttononclick="SummerizeTable('#table1')">Summerize</button><tableid="table1"border="1"cellspacing="0" ><thead><tr><th>State</th><th>City</th><th>Street</th></tr></thead><tbody><tr><td>VT</td><td>Burlington</td><td>Elm</td></tr><tr><td>NY</td><td>Manhattan</td><td>Main</td></tr><tr><td>NY</td><td>Manhattan</td><td>Oak</td></tr><tr><td>NY</td><td>Albany</td><td>State</td></tr></tbody></table>

Solution 4:

I really liked Farid first solution, but I needed to select the range of lines and which columns it would be applied, so I made a few modifications (including the possiblity of more than 2 cells merge). http://jsfiddle.net/djhU7/72/

function Merge_cells($id_table,$lin_ini,$lin_fim,$array_col=array()){

$colunas="";  
for($k=0;$k<count($array_col);$k++)  $colunas=$colunas . " col =='$array_col[$k]' ||";
if(count($array_col)>0) $colunas="(".substr($colunas,0,-3).") &&";    

echo   "<script>
$('#$id_table td').each(function() 
{
    var \$this = $(this);
    var col = \$this.index();                
    var txt =  \$this.text();                
    var row = $(this).parent()[0].rowIndex; 

    //define the interval of lines and columns it will look atif((col==0 || col==1 || col==2) row>=firstRow && row<=lastRow){ 
        span=1;
        cell_above = $(\$this.parent().prev().children()[col]);

        //look for cells one above another with the same textwhile(cell_above.text()=== txt){                    //if the text is the same
            span+=1;                                        //increase the span
            cell_above_old = cell_above;                    //store this cell
            cell_above = $(cell_above.parent().prev().children()[col]);    //and go to the next cell above
        }

        //if there are at least two columns with the same value, set a new span to the first and hide the otherif(span>1) {
            console.log(span);
            $(cell_above_old).attr('rowspan',span); 
            \$this.hide();
        }              
    }
});

       </script>";
}

Solution 5:

I extended carla's solution. With two functions, we can merge horizontally or vertically and exclude or include cells to merge. try the working sample. https://jsfiddle.net/bn3u63pe

/*
* merge horizontally
* ex) autoMergeByCol('theTable', 2, 0, 0);
*/functionautoMergeByCol(tableId
        , rowStartIndex // zero or positive
        , colStart      // zero or positive
        , colEnd        // equals to colStart or greater than colStart or negative to go to the end of cols) {
    /*
    console.log('autoMergeByCol tableId=' + tableId
        + ', rowStartIndex=' + rowStartIndex
        + ', colStart=' + colStart
        + ', colEnd=' + colEnd
    );
    */var trArr = $('#' + tableId).find('tr');        // rows arrayfor(var rowIndex = rowStartIndex ; rowIndex < trArr.length ; rowIndex++) {
    var tdArr = $(trArr[rowIndex]).find('td');  // cols array of the rowif(colEnd < 0) colEnd = tdArr.length - 1;       // if colEnd is negative, process at the end of the cols;for(var colIndex = colStart ; colIndex < tdArr.length && colIndex <= colEnd ; colIndex++) {
            var span = 1;
            var theCell = $(tdArr)[colIndex];
            if($(theCell).attr('rowspan')) {continue;}
            var cellNext = $($(theCell).parent().children()[colIndex + span]);      
            while(cellNext != undefined 
                    && $(theCell).text() == $(cellNext).text()
                    && colIndex + span <= colEnd ) {
                span++;
                cellNext.hide();
                cellNext = $($(cellNext).parent().children()[colIndex + span]);     
            }
            if(span > 1) $(theCell).attr('colspan', span);
        }
    }
}

/*
* merge vertically
* ex) autoMergeByCol('theTable', 2, 0, 0);
*/functionautoMergeByRow(tableId
        , rowStartIndex // zero or positive
        , colStart      // zero or positive
        , colEnd        // equals to colStart or greater than colStart or negative) {
    /*
    console.log('autoMergeByRow tableId=' + tableId
        + ', rowStartIndex=' + rowStartIndex
        + ', colStart=' + colStart
        + ', colEnd=' + colEnd
    );
    */var trArr = $('#' + tableId).find('tr');            // rows arrayfor(var rowIndex = rowStartIndex ; rowIndex < trArr.length ; rowIndex++) {
        var tdArr = $(trArr[rowIndex]).find('td');  // cols array of the rowif(colEnd < 0) colEnd = tdArr.length - 1;       // if colEnd is negative, process at the end of the cols;for(var colIndex = colStart ; colIndex < tdArr.length && colIndex <= colEnd ; colIndex++) {
            var span = 1;
            var theCell = $(tdArr)[colIndex];
            if($(theCell).attr('colspan')) {continue;}
            var cellBelow = $($(theCell).parent().next().children()[colIndex]);         
            while(cellBelow != undefined 
                    && $(theCell).text() == $(cellBelow).text()) {
                span++;
                cellBelow.hide();
                cellBelow = $($(cellBelow).parent().next().children()[colIndex]);           
            }
            if(span > 1) $(theCell).attr('rowspan', span);          
        }
    }
}

Post a Comment for "Merge Equal Table Cells With Jquery"