弹簧启动。百里香叶。如何使 table 的列可点击以向 Controller 发送请求?
SpringBoot. Thymeleaf. How to make table's column clickable to send request to Controller?
我创建了包含 8 列的 table:
<table border="1" cellspacing="0" cellpadding="0">
<tr height="30">
<div th:each="horiz1, state : ${#numbers.sequence(1, 8)}">
<td width="30" th:value=${state.count} th:attr="action=@{/}" >
</td>
</div>
</tr>
</table>
事实上,每一列(标签“td”)都应该作为一个按钮,点击后将我发送到控制器(@PostMapping 或@GetMapping),我将尝试阅读 th:value。 如何制作?
我尝试使用 th:href="@{/}" 而不是 th:attr="action=@{/}" - 不起作用。
我试图在标签“td”之间插入表单按钮,但无法使其不可见,并且无法使其大小与列的完整大小一致。
UPD。完整 html 代码
<body>
<table border="1" cellspacing="0" cellpadding="0">
<div th:each="vert : ${#numbers.sequence(1, 4)}">
<tr height="30">
<div th:each="horiz1, state : ${#numbers.sequence(1, 8)}">
<td width="30" th:value=${state.count} th:attr="action=@{/}" th:style="${state.odd}? 'background: #f4cd8d' : 'background: #745853'">
</td>
</div>
</tr>
<tr height="30">
<div th:each="horiz2, state : ${#numbers.sequence(1, 8)}">
<td width="30" th:style="${state.even}? 'background: #f4cd8d' : 'background: #745853' "> </td>
</div>
</tr>
</div>
</table>
</body>
我正在制作棋盘。点击任何单元格后,它应该进入控制器,进行一些计算和highlite单元格,马可以移动的地方。
简化百里香叶
其中部分内容可能与您的核心问题没有直接关系,但您可以做很多事情来简化生成国际象棋的 Thymeleaf table。
通过这样做,您可以摆脱所有当前正在使用的 <div>
元素,也可以更轻松地处理点击事件,稍后:
<table id="chessboard" border="1" cellspacing="0" cellpadding="0">
<tr height="30"
th:each="row, rStat : ${#numbers.sequence(1, 8)}">
<td th:each="col, cStat : ${#numbers.sequence(1, 8)}"
width="30"
th:data-row=${rStat.count}
th:data-col=${cStat.count}
th:style="${(rStat.odd and cStat.odd) or (rStat.even and cStat.even)}
? 'background: #f4cd8d' : 'background: #745853'">
</td>
</tr>
</table>
这里的主要区别是:
- 我将 Thymeleaf
th:each
迭代器放在 <tr>
和 <td>
标签中。
- 我只有一个逻辑来处理每个方块的着色。
- 我在每个
<td>
中创建两个 data-
属性来唯一标识每个方块。
请注意:
您可能会争辩说,在这里使用 Thymeleaf 并没有太大好处,因为在 Thymeleaf 模板中基本上所有内容都是 hard-coded。通常,您会期望 Thymeleaf 从控制器接收值 - 但对于绘制棋盘,不需要这样的 server-provided 数据。
我想它确实允许使用更紧凑的模板。
单击每个方块
上面Thymeleaf生成的结果HTML没有点击事件。在 <script>...</script>
标签中紧跟 table HTML 添加这些事件会更容易 - 例如:
// get an array containing the <td> elements
var squares = document.getElementsByTagName('td');
// loop through that array, adding an event to each element:
for (i = 0; i < squares.length; i++) {
squares[i].addEventListener('click', function (e) {
console.log('clicked on row ' + this.getAttribute('data-row')
+ ' col ' + this.getAttribute('data-col'));
});
}
在我的例子中,点击事件只会导致一行信息文本打印到浏览器的控制台 - 例如:
在您的情况下,您希望将此数据(行号和列号)发送到您的控制器。这是一个更大的问题。
如果您不熟悉如何执行此操作,您可以研究各种问题 - 例如: - 可能还有更多类似的问题。
如果遇到困难,可以提出一个新的、更有针对性的 follow-up 问题。
我创建了包含 8 列的 table:
<table border="1" cellspacing="0" cellpadding="0">
<tr height="30">
<div th:each="horiz1, state : ${#numbers.sequence(1, 8)}">
<td width="30" th:value=${state.count} th:attr="action=@{/}" >
</td>
</div>
</tr>
</table>
事实上,每一列(标签“td”)都应该作为一个按钮,点击后将我发送到控制器(@PostMapping 或@GetMapping),我将尝试阅读 th:value。 如何制作?
我尝试使用 th:href="@{/}" 而不是 th:attr="action=@{/}" - 不起作用。 我试图在标签“td”之间插入表单按钮,但无法使其不可见,并且无法使其大小与列的完整大小一致。
UPD。完整 html 代码
<body>
<table border="1" cellspacing="0" cellpadding="0">
<div th:each="vert : ${#numbers.sequence(1, 4)}">
<tr height="30">
<div th:each="horiz1, state : ${#numbers.sequence(1, 8)}">
<td width="30" th:value=${state.count} th:attr="action=@{/}" th:style="${state.odd}? 'background: #f4cd8d' : 'background: #745853'">
</td>
</div>
</tr>
<tr height="30">
<div th:each="horiz2, state : ${#numbers.sequence(1, 8)}">
<td width="30" th:style="${state.even}? 'background: #f4cd8d' : 'background: #745853' "> </td>
</div>
</tr>
</div>
</table>
</body>
我正在制作棋盘。点击任何单元格后,它应该进入控制器,进行一些计算和highlite单元格,马可以移动的地方。
简化百里香叶
其中部分内容可能与您的核心问题没有直接关系,但您可以做很多事情来简化生成国际象棋的 Thymeleaf table。
通过这样做,您可以摆脱所有当前正在使用的 <div>
元素,也可以更轻松地处理点击事件,稍后:
<table id="chessboard" border="1" cellspacing="0" cellpadding="0">
<tr height="30"
th:each="row, rStat : ${#numbers.sequence(1, 8)}">
<td th:each="col, cStat : ${#numbers.sequence(1, 8)}"
width="30"
th:data-row=${rStat.count}
th:data-col=${cStat.count}
th:style="${(rStat.odd and cStat.odd) or (rStat.even and cStat.even)}
? 'background: #f4cd8d' : 'background: #745853'">
</td>
</tr>
</table>
这里的主要区别是:
- 我将 Thymeleaf
th:each
迭代器放在<tr>
和<td>
标签中。 - 我只有一个逻辑来处理每个方块的着色。
- 我在每个
<td>
中创建两个data-
属性来唯一标识每个方块。
请注意:
您可能会争辩说,在这里使用 Thymeleaf 并没有太大好处,因为在 Thymeleaf 模板中基本上所有内容都是 hard-coded。通常,您会期望 Thymeleaf 从控制器接收值 - 但对于绘制棋盘,不需要这样的 server-provided 数据。
我想它确实允许使用更紧凑的模板。
单击每个方块
上面Thymeleaf生成的结果HTML没有点击事件。在 <script>...</script>
标签中紧跟 table HTML 添加这些事件会更容易 - 例如:
// get an array containing the <td> elements
var squares = document.getElementsByTagName('td');
// loop through that array, adding an event to each element:
for (i = 0; i < squares.length; i++) {
squares[i].addEventListener('click', function (e) {
console.log('clicked on row ' + this.getAttribute('data-row')
+ ' col ' + this.getAttribute('data-col'));
});
}
在我的例子中,点击事件只会导致一行信息文本打印到浏览器的控制台 - 例如:
在您的情况下,您希望将此数据(行号和列号)发送到您的控制器。这是一个更大的问题。
如果您不熟悉如何执行此操作,您可以研究各种问题 - 例如:
如果遇到困难,可以提出一个新的、更有针对性的 follow-up 问题。