使用 jquery 将行跨度添加到每行的第一个 td

Posted

技术标签:

【中文标题】使用 jquery 将行跨度添加到每行的第一个 td【英文标题】:Add rowspan to first td of each row using jquery 【发布时间】:2021-07-28 01:53:51 【问题描述】:

我有一张桌子。我想将 rowspan 添加到每行的第一个 td 。但是当我这样做时,它会弄乱表格并将表格中的数据向右推。

这是我的代码:

let data = [
  device: 'iphone',   site: 'google', val1:10, val2:20, val3:30,
  device: 'iphone',  site: 'bing', val1:23, val2:12, val3:14,
  device: 'iphone',  site: 'jeeves', val1:67, val2:78, val3:12,
  device: 'ipad',  site: 'google', val1:10, val2:20, val3:30,
  device: 'ipad',  site: 'bing', val1:23, val2:12, val3:14,
  device: 'ipad',  site: 'jeeves', val1:67, val2:78, val3:12,
  device: 'mac',   site: 'google', val1:10, val2:20, val3:30,
  device: 'mac',   site: 'bing', val1:23, val2:12, val3:14,
  device: 'mac',   site: 'jeeves', val1:67, val2:78, val3:15  
]

let heads = Object.keys(data[0]);
heads.forEach(d => $(`#headers`).append(`<th>$d</th>`));

data.forEach(td => 
  $(`#body_deets`).append(`<tr></tr>`);
  heads.forEach(th => 
    $(`#body_deets > tr:last`).append(`<td>$td[th]</td>`);
  );
);

$(`#body_deets > tr > td:first-child`).each(function() 
    $(this).attr('rowspan', '3');
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table class='table' border=1>
  <thead><tr id='headers'></tr></thead>
    <tbody id='body_deets'></tbody>
</table>

如您所见,这是添加行跨度并将我的大量数据推送到右侧。

我怎样才能让我的桌子看起来像这样:

有没有办法使用 jQuery 来做到这一点?

【问题讨论】:

【参考方案1】:

假设您想将每三个单元格组合成一个单元格,您需要在三个单元格中的第一个上设置rowspan,然后删除接下来的两个:

let data = [
    device: 'iphone',
    site: 'google',
    val1: 10,
    val2: 20,
    val3: 30
  ,
  
    device: 'iphone',
    site: 'bing',
    val1: 23,
    val2: 12,
    val3: 14
  ,
  
    device: 'iphone',
    site: 'jeeves',
    val1: 67,
    val2: 78,
    val3: 12
  ,
  
    device: 'ipad',
    site: 'google',
    val1: 10,
    val2: 20,
    val3: 30
  ,
  
    device: 'ipad',
    site: 'bing',
    val1: 23,
    val2: 12,
    val3: 14
  ,
  
    device: 'ipad',
    site: 'jeeves',
    val1: 67,
    val2: 78,
    val3: 12
  ,
  
    device: 'mac',
    site: 'google',
    val1: 10,
    val2: 20,
    val3: 30
  ,
  
    device: 'mac',
    site: 'bing',
    val1: 23,
    val2: 12,
    val3: 14
  ,
  
    device: 'mac',
    site: 'jeeves',
    val1: 67,
    val2: 78,
    val3: 15
  
]

let heads = Object.keys(data[0]);
heads.forEach(d => $(`#headers`).append(`<th>$d</th>`));

data.forEach(td => 
  $(`#body_deets`).append(`<tr></tr>`);
  heads.forEach(th => 
    $(`#body_deets > tr:last`).append(`<td>$td[th]</td>`);
  );
);

$(`#body_deets > tr > td:first-child`).each(function(index) 
  if(index % 3 == 0) 
    $(this).attr('rowspan','3');
   else 
    $(this).remove();
  
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table class='table' border=1>
  <thead>
    <tr id='headers'></tr>
  </thead>
  <tbody id='body_deets'></tbody>
</table>

【讨论】:

【参考方案2】:

对于 colspan 元素,您只需要 1 个&lt;td&gt;。只需删除这样的额外内容:

$(`#body_deets > tr > td:first-child`).each(function(index,elem) 
        if (index%3!=0) $(this).remove();
         else $(this).attr('rowspan', '3');
    );

【讨论】:

【参考方案3】:

我会提前计算指数范围。请参阅indexRange 函数和rowSpan 分配。


  "iphone":  "first": 0 , "last": 2 ,
  "ipad":    "first": 3 , "last": 5 ,
  "mac":     "first": 6 , "last": 8 

const data = [
   device: 'iphone' , site: 'google' , val1: 10 , val2: 20, val3: 30 ,
   device: 'iphone' , site: 'bing'   , val1: 23 , val2: 12, val3: 14 ,
   device: 'iphone' , site: 'jeeves' , val1: 67 , val2: 78, val3: 12 ,
   device: 'ipad'   , site: 'google' , val1: 10 , val2: 20, val3: 30 ,
   device: 'ipad'   , site: 'bing'   , val1: 23 , val2: 12, val3: 14 ,
   device: 'ipad'   , site: 'jeeves' , val1: 67 , val2: 78, val3: 12 ,
   device: 'mac'    , site: 'google' , val1: 10 , val2: 20, val3: 30 ,
   device: 'mac'    , site: 'bing'   , val1: 23 , val2: 12, val3: 14 ,
   device: 'mac'    , site: 'jeeves' , val1: 67 , val2: 78, val3: 15   
 ]; 

let fields =  Object.keys(data[0]);
fields.forEach(d => $(`#headers`).append(`<th>$d</th>`));

const indexRange = data.reduce((acc,  device , index) =>
  ( ...acc, [device]: 
    first: acc[device]?.first ?? index,
    last: index || acc[device]?.last
   ), );

console.log(indexRange);

data.forEach((record, rowIndex) => 
  $(`#body_deets`).append(`<tr></tr>`);
  const  device  = record;
  const  first, last  = indexRange[device];
  fields.forEach((field, colIndex) => 
    const value = record[field];
    if (colIndex === 0) 
      if (rowIndex === first) 
        const rowSpan = last - first + 1;
        $(`#body_deets > tr:last`).append(`<td rowspan="$rowSpan">$value</td>`);
       
     else 
      $(`#body_deets > tr:last`).append(`<td>$value</td>`);
    
  );
);
table 
  border-collapse: collapse;


table, th, td 
  border: thin solid #CCC;


th, td 
  padding: 0.33em;


thead > tr 
  background: #DDD;


tbody tr:nth-child(even) 
  background: #EEE;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table class="table">
  <thead>
    <tr id="headers"></tr>
  </thead>
  <tbody id="body_deets"></tbody>
</table>

【讨论】:

以上是关于使用 jquery 将行跨度添加到每行的第一个 td的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jQuery 将行追加到表中?

如何在laravel中使用jquery将行添加到数据表中

使用 jQuery DataTables 插件,fnAddData() 是不是将行添加到 html 表格的顶部或底部?

如何在 JFXTable 视图中添加按钮编辑和删除以及如何将行编辑到 SQL

Numpy - 将行添加到数组

jquery 动态创建div并判断是每行的第几个