如何实现带可展开子行的PHP动态填充HTML DataTable?
实现DataTable父子行展开功能(按设备编号分组)
我来帮你搞定这个需求!要实现父行展示设备编号、展开后显示同编号下所有设备的详细信息,咱们得从后端数据分组和前端DataTable交互两方面入手,一步步来:
1. 先给后端数据按设备编号分组
首先你需要把平的$devices数组按device_no分组,这样同一个设备编号下的所有设备会被归到一组,方便后续渲染父子行。
替换你原来的PHP循环部分,改成下面的分组逻辑:
<?php // 按device_no分组设备数据 $grouped_devices = []; foreach ($devices as $device) { $dev_no = $device["device_no"]; if (!isset($grouped_devices[$dev_no])) { $grouped_devices[$dev_no] = [ 'device_name' => $device["name"], 'devices' => [] ]; } $grouped_devices[$dev_no]['devices'][] = $device; } ?>
2. 修改HTML表格结构
接下来调整表格,添加一个「展开/收起」的操作列,父行只展示设备编号和设备名称,子行的详细内容咱们通过JS动态渲染:
<table id="example" class="table table-bordered table-striped" cellspacing="0" width="100%"> <thead> <th></th> <!-- 展开按钮列 --> <th>Device</th> <th>Dev.no</th> <th>Date added on stock</th> <!-- 父行只显示关键汇总信息 --> </thead> <tbody> <?php if (!empty($grouped_devices)) { ?> <?php foreach ($grouped_devices as $dev_no => $group) : ?> <tr class="parent-row"> <td> <button class="btn btn-xs btn-expand">+</button> <!-- 展开按钮 --> </td> <td><?php echo $group["device_name"] ?></td> <td><?php echo $dev_no ?></td> <td><?php echo $group["devices"][0]["created_date"] ?></td> <!-- 取组内首个设备的日期,也可后端做汇总处理 --> </tr> <?php endforeach; ?> <?php } ?> </tbody> </table>
3. 前端DataTable配置与展开逻辑
最后用DataTable的API来实现行展开功能,点击按钮时动态生成子行,展示该设备编号下所有设备的详细信息:
$(document).ready(function() { // 初始化DataTable var table = $('#example').DataTable({ "order": [[2, 'asc']], // 按设备编号排序 "columnDefs": [ { "orderable": false, "targets": 0 } // 展开列禁止排序 ] }); // 绑定展开按钮点击事件 $('#example tbody').on('click', '.btn-expand', function() { var tr = $(this).closest('tr'); var row = table.row(tr); var dev_no = tr.find('td:eq(2)').text(); // 获取当前行的设备编号 // 如果子行已展开,就收起 if (row.child.isShown()) { row.child.hide(); $(this).text('+'); } else { // 动态生成子行的内容:一个嵌套详细表格 var childHtml = '<table class="table table-sm table-bordered" width="100%">'; childHtml += '<thead><tr><th>Barcode</th><th>IMEI</th><th>Serial no.</th><th>Date added</th></tr></thead><tbody>'; // 从分组数据中匹配当前设备编号的所有设备 <?php foreach ($grouped_devices as $dn => $g) : ?> if ("<?php echo $dn ?>" === dev_no) { <?php foreach ($g['devices'] as $d) : ?> childHtml += '<tr><td><?php echo $d["barcode"] ?></td><td><?php echo $d["serial_imei"] ?></td><td><?php echo $d["serial_no"] ?></td><td><?php echo $d["created_date"] ?></td></tr>'; <?php endforeach; ?> } <?php endforeach; ?> childHtml += '</tbody></table>'; // 显示子行 row.child(childHtml).show(); $(this).text('-'); } }); });
一些实用提示:
- 如果你用了Font Awesome,可以把按钮换成图标,比如
<i class="fa fa-plus-circle"></i>和<i class="fa fa-minus-circle"></i>,视觉效果更友好。 - 如果同一设备编号下的创建日期不一致,你可以在后端分组时处理成「最早日期/最晚日期」,或者父行直接显示「多个日期」。
- 确保你已经引入了jQuery、DataTable的CSS和JS文件,否则代码无法正常运行。
内容的提问来源于stack exchange,提问作者showtime
相关产品推荐
相关产品推荐

