如何添加 html with thymeleaf 并在单击按钮时将对象或其字段绑定到 html?
How to add html with thymeleaf and bind object or its fields to that html on button click?
这很简单 java class 有一个字符串列表,例如:
public class Apple {
private List<String> listOfStrings;
// getters setters
}
html 百里香叶:
<form method="post" th:object="${apple}"> // apple is set through Model.addAttribute(.., ..) in Controller
<input type="text" th:each="str, iter : *{listOfStrings} th:field="*{listOfStrings[__${iter.index}__]}">
<button id="add" type="button" onclick="add()>Add</button>
<button id="remove" type="button" onclick="remove()">Remove</button>
<input type="submit" value="Save">
<form>
java脚本添加和删除新输入:
const newInputTextString="<input type=\"text\" th:field="?">" // th:field won't be evaluated/bound to apples listOfStrings index
function add() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
document.getElementById("add").insertAdjacentHTML("beforebegin", newInputTextString);
}
xhttp.open("GET", window.location.href);
xhttp.send();
}
function remove() {
// TODO
}
到目前为止,我只是通过 java 脚本添加 html,但我不能在其中包含 th: 标签,因为这些标签不会被评估并绑定到特定对象或字段。
预期功能:
- 点击删除按钮,最后输入的绑定到 listOfStrings 特定索引的文本类型将被删除。
- 单击添加按钮后,将添加新的文本类型输入并将其绑定到 listOfStrings 的下一个索引。
换句话说,我想让用户能够使用 html 按钮在该苹果对象的 listOfStrings 中删除和添加字符串。
随时纠正我的英文
th:field 本质上只是为您提供元素的 ID 和 NAME 属性。您不能通过 JS 添加 th:field,但您可以通过手动添加适当的 ID 和 NAME 属性来模拟其行为。话虽如此,您应该对 HTML 和 JS 代码进行一些细微的更改。
您应该始终记录当前的字符串总数,以便调整您的字符串索引。为此,我为所有字符串输入创建了一个 div 包装器,以便我们可以在 JS 中访问它。之后我们只读取其中的元素数量并从中创建一个新索引。
你可以看看下面的实现:
function createInput(index) {
var input = document.createElement('input');
input.setAttribute('type', 'text');
input.setAttribute('id', `listOfStrings[${index}]`);
input.setAttribute('name', `listOfStrings[${index}]`);
input.setAttribute('placeholder', `listOfStrings[${index}]`);
input.setAttribute('data-index', index);
input.setAttribute('data-input', '');
return input;
}
function addString() {
var inputsWrapper = document.querySelector('[data-inputs]');
var inputs = inputsWrapper.querySelectorAll('[data-input]');
var newIndex = inputs.length;
var newInput = createInput(newIndex);
inputsWrapper.append(newInput);
}
<form method="post" th:object="${apple}">
<div style="display: flex; flex-direction: column; max-width: 300px" data-inputs>
<input
type="text"
placeholder="listOfStrings[0]"
th:placeholder="${'listOfStrings[__${iter.index}__]'}"
th:each="str, iter : *{listOfStrings}"
th:attr="data-index=${__${iter.index}__}"
th:field="*{listOfStrings[__${iter.index}__]}"
data-input />
</div>
<button id="add" type="button" onclick="addString()">Add</button>
<button id="remove" type="button" onclick="remove()">Remove</button>
<input type="submit" value="Save">
<form>
这很简单 java class 有一个字符串列表,例如:
public class Apple {
private List<String> listOfStrings;
// getters setters
}
html 百里香叶:
<form method="post" th:object="${apple}"> // apple is set through Model.addAttribute(.., ..) in Controller
<input type="text" th:each="str, iter : *{listOfStrings} th:field="*{listOfStrings[__${iter.index}__]}">
<button id="add" type="button" onclick="add()>Add</button>
<button id="remove" type="button" onclick="remove()">Remove</button>
<input type="submit" value="Save">
<form>
java脚本添加和删除新输入:
const newInputTextString="<input type=\"text\" th:field="?">" // th:field won't be evaluated/bound to apples listOfStrings index
function add() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
document.getElementById("add").insertAdjacentHTML("beforebegin", newInputTextString);
}
xhttp.open("GET", window.location.href);
xhttp.send();
}
function remove() {
// TODO
}
到目前为止,我只是通过 java 脚本添加 html,但我不能在其中包含 th: 标签,因为这些标签不会被评估并绑定到特定对象或字段。
预期功能:
- 点击删除按钮,最后输入的绑定到 listOfStrings 特定索引的文本类型将被删除。
- 单击添加按钮后,将添加新的文本类型输入并将其绑定到 listOfStrings 的下一个索引。
换句话说,我想让用户能够使用 html 按钮在该苹果对象的 listOfStrings 中删除和添加字符串。
随时纠正我的英文
th:field 本质上只是为您提供元素的 ID 和 NAME 属性。您不能通过 JS 添加 th:field,但您可以通过手动添加适当的 ID 和 NAME 属性来模拟其行为。话虽如此,您应该对 HTML 和 JS 代码进行一些细微的更改。
您应该始终记录当前的字符串总数,以便调整您的字符串索引。为此,我为所有字符串输入创建了一个 div 包装器,以便我们可以在 JS 中访问它。之后我们只读取其中的元素数量并从中创建一个新索引。
你可以看看下面的实现:
function createInput(index) {
var input = document.createElement('input');
input.setAttribute('type', 'text');
input.setAttribute('id', `listOfStrings[${index}]`);
input.setAttribute('name', `listOfStrings[${index}]`);
input.setAttribute('placeholder', `listOfStrings[${index}]`);
input.setAttribute('data-index', index);
input.setAttribute('data-input', '');
return input;
}
function addString() {
var inputsWrapper = document.querySelector('[data-inputs]');
var inputs = inputsWrapper.querySelectorAll('[data-input]');
var newIndex = inputs.length;
var newInput = createInput(newIndex);
inputsWrapper.append(newInput);
}
<form method="post" th:object="${apple}">
<div style="display: flex; flex-direction: column; max-width: 300px" data-inputs>
<input
type="text"
placeholder="listOfStrings[0]"
th:placeholder="${'listOfStrings[__${iter.index}__]'}"
th:each="str, iter : *{listOfStrings}"
th:attr="data-index=${__${iter.index}__}"
th:field="*{listOfStrings[__${iter.index}__]}"
data-input />
</div>
<button id="add" type="button" onclick="addString()">Add</button>
<button id="remove" type="button" onclick="remove()">Remove</button>
<input type="submit" value="Save">
<form>