使用 Javascript 和 Thymeleaf 动态添加表单输入

问题描述 投票:0回答:1

我想知道使用 Javascript 和 Thymeleaf 动态添加表单元素最惯用/最佳的解决方案是什么。对于上下文,我有一个在服务器端生成的表单,如下所示:

<form
    th:action="@{/some/path})}"
    th:object="${pathBulletinForm}"
    method="post"
    class="mb-3 border rounded needs-validation"
    novalidate
    id="bulletinForm"
>
    <select th:field="*{conditionRating}" type="select" id="conditionRating" name="conditionRating" class="form-select">
        <option label="-- Select a Condition --" value=""></option>
        <option th:each="pathConditionOpt : ${T(com.francisbailey.pathbulletin.persistence.model.PathCondition).values()}" th:value="${pathConditionOpt}" th:text="${pathConditionOpt.displayName}" th:attr="data-description='descriptionFor' + ${pathConditionOpt.name}"></option>
    </select>
    <a href="#" id="addConditionRating"><i class="bi bi-plus-circle"></i> Add Rating</i>
</form>

现在,我想做的是让用户单击一个按钮,它会自动将相同的

select
下拉列表附加到表单中。换句话说,他们可以在表单中附加多个“conditionRatings”。这在纯 javascript/客户端中很容易做到,但我喜欢在服务器端生成下拉列表,因为这些值来自枚举和单一事实来源。

我不确定最好的方法是什么。在 Javascript 中设置这个模板值看起来是可能的,但有点难看。

为了添加表单元素,我知道我可以执行以下操作:

<script>
const ratingButton = document.getElementById("addConditionRating");
const form = document.getElementById("bulletinForm")

ratingButton.addEventListener(e => {
    form.appendChild(`<select>My Condition Ratings Template Here?</select>`);    
});
</script>

但是,我不确定如何在那里设置实际的选择下拉菜单。我还需要将侦听器绑定到每个下拉列表,以在下拉列表下方显示服务器端呈现的描述/标签。

javascript spring-boot thymeleaf
1个回答
0
投票

一种选择是将下拉代码放入片段中。 然后,您可以在页面中使用相同的代码,并添加另一个控制器方法以仅返回条件下拉列表。 例如这样的事情:

page.html

<head>
  <meta charset="UTF-8"/>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
  <script>
        $(function() {
            $('#addConditionRating').click(() => {
                $.get('/condition',(data) => {
                    $('#conditionContainer').append(data);
                }); 
            });
        });
  </script>
</head>
<body>
    <form
        th:action="@{/some/path}"
        th:object="${pathBulletinForm}"
        method="post"
        class="mb-3 border rounded needs-validation"
        novalidate
        id="bulletinForm"
    >
        <div id="conditionContainer">
            <th:block th:replace="~{fragments :: condition}" />
        </div>
        <a href="#" id="addConditionRating"><i class="bi bi-plus-circle"></i> Add Rating</i>
    </form>
</body>

fragments.html

<html>
    <body>
        <select th:fragment="condition" type="select" id="conditionRating" name="conditionRating" class="form-select">
            <option label="-- Select a Condition --" value=""></option>
            <option th:each="pathConditionOpt : ${T(com.francisbailey.pathbulletin.persistence.model.PathCondition).values()}"
                    th:value="${pathConditionOpt}"
                    th:text="${pathConditionOpt.displayName}"
                    th:attr="data-description='descriptionFor' + ${pathConditionOpt.name}"></option>
        </select>
    </body>
</html>

然后添加一个返回该页面片段的控制器方法:

@GetMapping("/condition")
public String condition() {
    return "fragments :: condition";
}
© www.soinside.com 2019 - 2024. All rights reserved.