使用jQuery合并相等的表格单元格

时间:2014-02-02 15:21:31

标签: javascript jquery html dom

具有NxM值的简单html表。 目的是将列中的相等单元格与jQuery合并。 请注意,在一行中没有重复。

我知道如何隐藏相同的单元格,但有没有办法将单元格与数据结合在一起?

HTML:

<table border="1" id="testTable">
<tr>
    <td>First</td>
    <td>A</td>
    <td>A</td>
</tr>
<tr>
    <td>First</td>
    <td>A</td>
    <td>B</td>
</tr>
<tr>
    <td>Second</td>
    <td>V</td>
    <td>S</td>
</tr>
<tr>
    <td>Third</td>
    <td>D</td>
    <td>H</td>
</tr>
<tr>
    <td>Third</td>
    <td>E</td>
    <td>E</td>       
</tr>
</table>

JS:

var seenArray = {};
$('#testTable td').each(function() 
{
    var index =  $(this).index();
    var txt = $(this).text();
    if (seenArray[index] === txt) 
    {
        $(this).text(''); //I think here should be "marging"
    }
    else 
    {
        seenArray[index] = txt;
    }
});

jsFiddle

P.S。还有一件事,数据最初是在json数组中检索的,然后我先做.parseJSON()并使用以下内容将数据放入表中:

for (var i = 0; i < obj.length; i++) 
{
    tr = $('<tr/>');
    tr.append("<td>" + obj[i]['columnA'] + "</td>");
    tr.append("<td>" + obj[i]['columnB'] + "</td>");
    tr.append("<td>" + obj[i]['columnC'] + "</td>");
    $('#testTable').append(tr); 
}

UPD

alFReD NSH为2个细胞提供了很好的解决方案。 Here是他的解决方案。 但是,如果有超过2个相等的单元格。

6 个答案:

答案 0 :(得分:9)

如果我在这里得到你的意思,我的编辑版本为:http://jsfiddle.net/djhU7/4/

所以我没有$(this).text('')而是这样做了:

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

我做了什么,是我将第一个单元格的rowspan设置为2.此属性“将指示单元格延伸的行数。”这将使上面的单元格变大两倍,并且我用重复的信息隐藏了单元格,这样额外的单元格就会消失。请注意,删除单元格将破坏下一个单元格的索引检查。这只是一个快速而又肮脏的解决方案,但必须在某处使用rowspan属性来实现它。

这是另一个版本,在将单元格插入表格时设置行距,除了它可以处理3个重复单元格以及更多单元格之外,它也更快,因为它避免了重新渲染表格(尽管它可以更优化,但我不认为此刻你想关心它,过早的优化是万恶之源!):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);

}

function addColumn(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);
}

答案 1 :(得分:6)

请使用行展开/折叠查找针对您的查询的改进答案。这是我的小提琴:

function MergeGridCells()
{
    var dimension_cells = new Array();
    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 td
    var 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;
        } else if (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

答案 2 :(得分:3)

这是carla's answer的可运行版本:

function SummerizeTable(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 text
      while (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 other
      if (span > 1) {
        // console.log(span);
        $(cell_above_old).attr('rowspan', span);
        $this.hide();
      }
      
    });
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="SummerizeTable('#table1')">Summerize</button>
<table id="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>

答案 3 :(得分:1)

我真的很喜欢Farid的第一个解决方案,但是我需要选择行的范围和应用的列,所以我做了一些修改(包括超过2个单元合并的可能性)。 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 at
    if((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 text
        while(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 other
        if(span>1) {
            console.log(span);
            $(cell_above_old).attr('rowspan',span); 
            \$this.hide();
        }              
    }
});

       </script>";
}

答案 4 :(得分:1)

我扩展了卡拉的解决方案。 有两个功能,我们可以水平或垂直合并 并排除或包含要合并的单元格。 尝试工作样本。 https://jsfiddle.net/bn3u63pe

/*
* merge horizontally
* ex) autoMergeByCol('theTable', 2, 0, 0);
*/
function autoMergeByCol(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 array
    for(var rowIndex = rowStartIndex ; rowIndex < trArr.length ; rowIndex++) {
    var tdArr = $(trArr[rowIndex]).find('td');  // cols array of the row
    if(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);
*/
function autoMergeByRow(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 array
    for(var rowIndex = rowStartIndex ; rowIndex < trArr.length ; rowIndex++) {
        var tdArr = $(trArr[rowIndex]).find('td');  // cols array of the row
        if(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);          
        }
    }
}

答案 5 :(得分:1)

  $(document).ready(function () {
        SummerizeTable($('#example'));
      })



      function SummerizeTable(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]);

            while (cell_above.html() === html) { 
              span += 1; 
              cell_above_old = cell_above; 
              cell_above = $(cell_above.parent().prev().children()[col]); 
            }

            if (span > 1) {
              $(cell_above_old).attr('rowspan', span);
              $this.hide();
            }

          });
        });
      }

请参见工作示例here