Laravel下jQuery通过Ajax动态生成多级表格表头及行的问题
Laravel DataTables动态两级表头渲染修复
问题核心原因
原有代码逻辑错误:遍历假期类型的循环中重复生成<tr>行标签,每遍历1个假期类型就生成2行完整表头,最终渲染出多组重复的错乱多行结构,不符合两级表头的预期。
已知前提
- 接口返回JSON结构:
data字段:假期类型列表,单条包含leaveTypeId(假期ID)、leaveName(假期名称)属性emp字段:员工列表,单条包含id(员工ID)、empName(员工姓名)属性
返回示例:
{"draw":0,"recordsTotal":14,"recordsFiltered":4,"data":[{"leaveTypeId":20,"leaveName":"Annual Leave"},{"leaveTypeId":7,"leaveName":"Hajj leave"},{"leaveTypeId":19,"leaveName":"TOIL"},{"leaveTypeId":11,"leaveName":"Unpaid leave"},{"leaveTypeId":2,"leaveName":"Sick Leave"},{"leaveTypeId":5,"leaveName":"Paternity leave"},{"leaveTypeId":6,"leaveName":"Maternity leave"}],"emp":[{"id":327,"empName":"Abbas "},{"id":162,"empName":"Abdo"},{"id":407,"empName":"Abdo"},{"id":411,"empName":"Abdo"},{"id":219,"empName":"Abdu"},{"id":334,"empName":"Abdul Hakeem "},{"id":330,"empName":"Abdul Kareem "},{"id":412,"empName":"Abdulaleem"},{"id":246,"empName":"Abdulaziz"},{"id":301,"empName":"Abdulfatah"},{"id":100,"empName":"Abdulgani"},{"id":364,"empName":"Abduljaleem "},{"id":95,"empName":"Abdulkareem"},{"id":287,"empName":"Abdulkareem"},{"id":413,"empName":"Abdulkarim"},{"id":711,"empName":"Abdulkhaliq"},{"id":15,"empName":"Abdullah"},{"id":19,"empName":"Abdullah "},{"id":69,"empName":"Abdullah"},{"id":70,"empName":"Abdullah"},{"id":71,"empName":"Abdullah"},{"id":96,"empName":"Abdullah "},{"id":97,"empName":"Abdullah "},{"id":200,"empName":"Abdullah "},{"id":243,"empName":"Abdullah"},{"id":244,"empName":"Abdullah"},{"id":249,"empName":"Abdullah"},{"id":258,"empName":"Abdullah"},{"id":455,"empName":"Abdullah "},{"id":546,"empName":"Abdullah "},{"id":591,"empName":"Abdullah "},{"id":708,"empName":"Abdullah"},{"id":542,"empName":"Abdulmalik"}]} - Blade预置表格结构:
<table id="LeaveSummaryGrid" class="table table-bordered table-striped"> <thead> </thead> <tbody> </tbody> </table> - 预期表头结构:
- 第一行:首列为
EmpName,后续每个假期类型占3列宽度(colspan="3")展示假期名称 - 第二行:首列为空,对应每个假期类型依次渲染
Ent.(应享额度)、Ava.(已用额度)、Bal.(剩余额度)三个子表头 - 表体:循环员工列表,每行首列展示员工姓名,后续对应每个假期类型渲染3个额度单元格
- 第一行:首列为
原有错误代码
$.ajax({ type: "get", url: url_search, //dataType:"json", //data: data, success: function (response) { var count = 1; var trHTML = ''; $.each(response.data, function (key,value) { trHTML += '<tr><th> EmpName' + '</th><th colspan="3">' + value.leaveName + '</th></tr>' + '<tr><th>' + '</th><th>Ent.' + '</th><th>Ava.' + '</th><th>Bal.' + '</th></tr>' ; count++; }); $('#LeaveSummaryGrid thead').append(trHTML); } });
修复后代码
两级表头仅需2个<tr>标签,不要在循环内重复创建行,首列EmpName可通过rowspan="2"直接跨两行,结构更简洁:
$.ajax({ type: "get", url: url_search, dataType: "json", success: function (response) { // 清空表格旧内容避免重复渲染 $('#LeaveSummaryGrid thead').empty(); $('#LeaveSummaryGrid tbody').empty(); const leaveTypeList = response.data; const empList = response.emp; // 初始化两行表头 let firstHeaderRow = '<tr><th rowspan="2">EmpName</th>'; let secondHeaderRow = '<tr>'; // 循环拼接表头列 $.each(leaveTypeList, function (index, leaveItem) { firstHeaderRow += `<th colspan="3">${leaveItem.leaveName}</th>`; secondHeaderRow += '<th>Ent.</th><th>Ava.</th><th>Bal.</th>'; }); firstHeaderRow += '</tr>'; secondHeaderRow += '</tr>'; // 插入表头到页面 $('#LeaveSummaryGrid thead').append(firstHeaderRow + secondHeaderRow); // 拼接表体数据行 let bodyContent = ''; $.each(empList, function (index, empItem) { bodyContent += `<tr><td>${empItem.empName}</td>`; // 每个假期类型对应3个额度单元格,可后续填充实际数据 $.each(leaveTypeList, function () { bodyContent += '<td></td><td></td><td></td>'; }); bodyContent += '</tr>'; }); // 插入表体到页面 $('#LeaveSummaryGrid tbody').append(bodyContent); // 如果需要初始化DataTables,可在此处执行对应初始化逻辑 } });
提示:返回的JSON结构不符合DataTables默认的返回规范,如果后续要使用DataTables原生分页、排序功能,需要调整后端返回结构,或者在DataTables初始化时配置自定义数据解析规则。
内容的提问来源于stack exchange,提问作者Ahad Ahmad
相关产品推荐
相关产品推荐

