如何在Thymeleaf下拉框选中项变更时直接调用Spring Boot Controller接口
实现方案
方案1:下拉变更触发表单提交(整页刷新,改造成本最低)
Thymeleaf本身是服务端渲染模板,不处理前端交互逻辑,你只需要给<select>标签加原生的onchange事件即可,选中变更时直接触发所属表单的提交操作,不需要点击提交按钮。
修改后的代码如下:
<form th:action="@{/getdata}" method="post"> <table class="table"> <tr> <td> <!-- 加onchange事件,选中变更直接提交所属表单 --> <select th:name="thetablename" onchange="this.form.submit()"> <option th:if="${thetablename.isEmpty()}">Select Table</option> <option th:each="table: ${tables}" th:value="${table.tablename}" th:selected="${table.tablename eq thetablename}" th:text="${table.displayname}"></option> </select> </td> <!-- 提交按钮可以保留也可以加hidden属性隐藏 --> <td><input type="submit" th:value="${buttonlabel}" hidden/></td> </tr> </table> <!-- data shows here after submit --> </form>
这个方案不需要改后端逻辑,和原来点击提交的逻辑完全一致,只是触发提交的时机从点击按钮变成了下拉选择变更。
方案2:异步请求无刷新更新数据(体验更好)
如果不需要整页刷新,只想更新页面上的数据展示区域,可以用原生JS的Fetch API发起异步请求:
第一步:修改HTML标签加标识
<form th:action="@{/getdata}" method="post"> <table class="table"> <tr> <td> <!-- 给select加id方便JS获取 --> <select id="tableSelect" th:name="thetablename"> <option th:if="${thetablename.isEmpty()}">Select Table</option> <option th:each="table: ${tables}" th:value="${table.tablename}" th:selected="${table.tablename eq thetablename}" th:text="${table.displayname}"></option> </select> </td> <td><input type="submit" th:value="${buttonlabel}" hidden/></td> </tr> </table> </form> <!-- 给数据展示区域加id方便JS更新内容 --> <div id="dataContainer"> <!-- data shows here after select --> </div>
第二步:加入JS监听事件
<script th:inline="javascript"> // 监听下拉框变更事件 document.getElementById('tableSelect').addEventListener('change', function() { const selectedTable = this.value; // 跳过默认提示选项的请求 if (!selectedTable) { document.getElementById('dataContainer').innerHTML = ''; return; } // 发起POST请求 fetch(/*[[@{/getdata}]]*/ '', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', // 如果开启了Spring Security CSRF校验,需要加上对应的CSRF头 }, body: 'thetablename=' + encodeURIComponent(selectedTable) }).then(res => res.text()) .then(html => { // 把后端返回的内容更新到数据展示区域 document.getElementById('dataContainer').innerHTML = html; }); }); </script>
这个方案后端可以根据请求类型返回视图片段或者JSON数据,前端自行解析渲染即可。
注意事项
- 如果项目集成了Spring Security且开启了CSRF防护,异步请求需要携带CSRF令牌,你可以在页面head中加入以下标签存储令牌:
<meta name="_csrf" th:content="${_csrf.token}"/> <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
然后在Fetch请求的headers中带上对应的头即可。
内容的提问来源于stack exchange,提问作者Woodchuck
相关产品推荐
相关产品推荐

