基于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
相关产品推荐
相关产品推荐

