如何用Thymeleaf实现可点击展开详情的动态表格(无jQuery)
实现可点击展开/收起的动态表格行(Thymeleaf + JS + CSS)
当然可行!咱们完全可以用你指定的技术栈(Thymeleaf、JS、HTML、CSS、Java)实现这个点击展开/收起详情的功能。核心思路是给每个数据行添加点击事件,切换对应详情行的显示状态,下面是具体的实现步骤和完整代码:
1. 调整Thymeleaf表格结构
我们需要给每个数据行添加唯一标识,同时在每一行下方插入一个跨列的隐藏详情行,用来渲染该行对应的动态详情数据。假设你的Projectphase对象有一个getDetails()方法返回详情列表(比如子任务、明细数据等),代码调整如下:
<body> <style> .data-row { cursor: pointer; transition: background-color 0.2s; } .data-row:hover { background-color: #f5f5f5; } .data-row.highlighted { background-color: #e8f4f8; } .details-row { display: none; background-color: #fafafa; } .details-row.active { display: table-row; } .details-content { padding: 15px; } .detail-item { margin: 5px 0; padding: 8px; border-bottom: 1px solid #eee; } </style> <table border="1" cellpadding="8" cellspacing="0"> <tr> <th>Phasen Name</th> <th>PC</th> <th>AC</th> <th>EV</th> </tr> <!-- 数据行 --> <tr th:each="Projectphase, iterStat : ${evaPhasen}" class="data-row" data-id="phase-${iterStat.index}"> <td th:text="${Projectphase.phasenname}"></td> <td th:text="${Projectphase.plannedValue}"></td> <td th:text="${Projectphase.actualCost}"></td> <td th:text="${Projectphase.earnedValue}"></td> </tr> <!-- 详情行 --> <tr th:each="Projectphase, iterStat : ${evaPhasen}" class="details-row" id="details-phase-${iterStat.index}"> <td colspan="4" class="details-content"> <h4>详情 - <span th:text="${Projectphase.phasenname}"></span></h4> <div th:if="${not #lists.isEmpty(Projectphase.details)}"> <div th:each="detail : ${Projectphase.details}" class="detail-item"> <span th:text="${detail.name}"></span>: <span th:text="${detail.value}"></span> </div> </div> <div th:if="${#lists.isEmpty(Projectphase.details)}"> <em>无详情数据</em> </div> </td> </tr> </table> <script> // 获取所有数据行 const dataRows = document.querySelectorAll('.data-row'); dataRows.forEach(row => { row.addEventListener('click', function() { // 获取当前行的标识ID const phaseId = this.getAttribute('data-id'); // 找到对应的详情行 const detailsRow = document.getElementById(`details-${phaseId}`); // 切换显示状态 detailsRow.classList.toggle('active'); // 给点击的行添加/移除高亮样式 this.classList.toggle('highlighted'); }); }); </script> </body>
2. 各部分代码说明
- Thymeleaf部分:
- 使用
iterStat.index给每个数据行和详情行生成唯一标识,确保二者一一对应; - 详情行用
colspan="4"跨所有列,保证表格布局整齐; - 通过
th:if判断是否存在详情数据,动态显示对应内容。
- 使用
- CSS部分:
- 给数据行添加鼠标悬停效果和指针样式,提升交互体验;
- 默认隐藏详情行,通过
active类控制显示状态; - 给详情内容添加内边距和分隔线,优化视觉层次感。
- JavaScript部分:
- 监听所有数据行的点击事件;
- 通过
data-id属性关联对应的详情行,使用classList.toggle()一键切换显示/隐藏状态; - 可选的高亮样式,让用户更清晰地识别当前点击的行。
3. Java后端配合
确保你的Projectphase实体类包含详情数据的属性和getter方法,示例如下:
public class Projectphase { private String phasenname; private Double plannedValue; private Double actualCost; private Double earnedValue; private List<Detail> details; // 存储该行的详情数据 // 省略其他属性的getter/setter public List<Detail> getDetails() { return details; } public void setDetails(List<Detail> details) { this.details = details; } // 内部类定义详情数据结构 public static class Detail { private String name; private String value; // getter/setter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } }
在后端控制器中,给每个Projectphase对象填充好详情数据后,再将evaPhasen列表传递到前端即可。
这样就能完美实现点击数据行展开对应详情、再次点击收起的功能啦!
内容的提问来源于stack exchange,提问作者Manuel




