You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于JSON创建带可展开分组行的嵌套表格(jQuery实现)

实现按mezzo分组的可展开嵌套表格

没问题,我来帮你搞定这个需求!核心是先把数据按mezzo分组,再生成带展开/收起功能的嵌套表格结构,下面是完整的实现方案:

步骤1:数据分组(关键改进)

你之前只做了排序,但没有把相同mezzo的条目归为一组。我们可以用Array.reduce()把原始数据转换成按mezzo分组的结构,这样后续生成DOM会更清晰:

var response = [
  { "mezzo":"fiat punto", "tipologia":"auto", "id":"1" },
  { "mezzo":"fiat punto", "tipologia":"auto", "id":"2" },
  { "mezzo":"fiat punto", "tipologia":"auto", "id":"3" },
  { "mezzo":"alfa giulia", "tipologia":"auto", "id":"1" },
  { "mezzo":"alfa giulia", "tipologia":"auto", "id":"2" },
  { "mezzo":"fiat punto", "tipologia":"auto", "id":"4" },
  { "mezzo":"alfa giulia", "tipologia":"auto", "id":"3" }
];

// 1. 按mezzo分组
const groupedData = response.reduce((acc, item) => {
  const groupKey = item.mezzo.toLowerCase();
  if (!acc[groupKey]) {
    // 初始化分组:保存分组名称、类型,以及该组的所有条目
    acc[groupKey] = {
      displayName: item.mezzo,
      tipologia: item.tipologia,
      items: []
    };
  }
  acc[groupKey].items.push(item);
  return acc;
}, {});

// 2. 把分组后的对象转成数组,并保持你原来的排序逻辑
const groupedArray = Object.values(groupedData).sort((a, b) => {
  const mezzoA = a.displayName.toLowerCase();
  const mezzoB = b.displayName.toLowerCase();
  if (mezzoA > mezzoB) return -1;
  if (mezzoA < mezzoB) return 1;
  return 0;
});

步骤2:生成嵌套表格DOM

现在我们遍历分组后的数组,每个分组生成两行:

  • 第一行:分组标题行(带展开按钮,显示mezzo和tipologia)
  • 第二行:包含子表格的行(默认隐藏,里面是该分组下的所有id条目)
$(function () {
  const parentFrag = document.createDocumentFragment();
  
  $.each(groupedArray, (_, group) => {
    // 生成父行(分组标题行)
    const parentTr = document.createElement('tr');
    parentTr.className = 'group-header';
    parentTr.innerHTML = `
      <td><a href="#">></a></td>
      <td>${group.displayName}</td>
      <td>${group.tipologia}</td>
      <td>${group.items.length} 条</td> <!-- 显示该组条目数量,更直观 -->
    `;
    parentFrag.appendChild(parentTr);

    // 生成子行(包含嵌套表格)
    const childTr = document.createElement('tr');
    childTr.className = 'group-content';
    // 子表格的td要跨4列,和表头对齐
    childTr.innerHTML = `
      <td colspan="4">
        <table border="1" class="child-table">
          <thead>
            <tr>
              <td>ID</td>
              <td>Tipologia</td>
            </tr>
          </thead>
          <tbody>
            ${group.items.map(item => `<tr><td>${item.id}</td><td>${item.tipologia}</td></tr>`).join('')}
          </tbody>
        </table>
      </td>
    `;
    parentFrag.appendChild(childTr);
  });

  // 把生成的DOM片段添加到页面
  $('.parent').append(parentFrag);

  // 步骤3:绑定展开/收起事件
  // 初始化隐藏所有子表格
  $('.group-content').hide();

  $('td > a').on('click', function (e) {
    e.preventDefault();
    // 切换当前分组的子行显示/隐藏
    const targetRow = $(this).closest('.group-header').next('.group-content');
    targetRow.toggle();
    // 切换展开按钮的图标,提升交互体验
    $(this).text(targetRow.is(':visible') ? 'v' : '>');
  });
});

对应的HTML结构

你的HTML可以保持基础结构,微调表头让逻辑更合理:

<table border="1" class="main-table">
  <thead>
    <tr>
      <td></td>
      <td>Mezzo</td>
      <td>Tipologia</td>
      <td>统计</td>
    </tr>
  </thead>
  <tbody class="parent">
  </tbody>
</table>

额外优化(可选)

加一点CSS让表格更美观,提升可读性:

.group-header {
  cursor: pointer;
  background-color: #f5f5f5;
}
.child-table {
  width: 100%;
  margin: 5px 0;
}
.child-table thead {
  background-color: #e0e0e0;
}

这样就能实现你想要的效果:相同mezzo的条目被自动分组,点击展开按钮可以查看该分组下的所有详情,再次点击即可收起。

内容的提问来源于stack exchange,提问作者ufollettu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:57:11