【问题标题】:Checkbox input using MaterializeCSS and Thymeleaf使用 MaterializeCSS 和 Thymeleaf 的复选框输入
【发布时间】:2020-08-12 02:50:53
【问题描述】:

嘿,我正在使用带有 Thymeleaf 的 Spring Boot 和 Spring Web。对于前端,我使用 MaterializeCSS 和带有 this 样式 CSS/JS 的数据表。

我想显示一个表格,用户可以在其中选择通过 Thymeleaf 迭代解析的数据集。我尝试使用包含 CheckBox 元素列表的 CheckBoxWrapper 形式来实现。 CheckBox 元素本身包含一个布尔值。 你可以在这个问题的末尾找到我的完整代码。

但是如果我尝试这样做(我认为?)Thymeleaf 会在复选框之后直接生成另一个隐藏的输入字段。浏览器中的 HTML 然后看起来像 this 这导致浏览器不显示复选框。如果我(重新)将生成的隐藏输入移到标签之外,则复选框将正确显示。 See the difference on this picture

有没有办法让复选框正确显示,同时仍然能够将复选框输入到服务器? (与百里香叶)

如果您需要有关任何相关问题的更多信息,请告诉我。

代码 - HTML

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      lang="en">
<head>
    <meta charset="UTF-8">
    <title>This is some really important detail</title>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
    <link rel="stylesheet" th:href="@{/css/materialize.css}" />
    <link rel="stylesheet" th:href="@{/css/datatables.css}" />
</head>
<body>

<div class="container">
    <div id="admin" class="col s10 offset-s1">
        <div class="card material-table">
            <div class="table-header">
                <span class="table-title">Table Headline</span>
                <div class="actions">
                    <a href="#" class="search-toggle waves-effect btn-flat nopadding"><i class="material-icons">search</i></a>
                </div>
            </div>
            <form action="/submit" th:object="${checkBoxWrapper}">
                <table id="datatable">
                    <thead>
                    <tr>
                        <th>Check</th>
                        <th>Name</th>
                    </tr>
                    </thead>
                    <tbody>
                    <th:block th:each="element,status : ${persons}">
                        <tr>
                            <td>
                                <div>
                                    <label>
                                        <input type="checkbox" th:id="'checkbox'+${status.index}"
                                               th:field="*{list[__${status.index}__].val}"/>
                                        <span>Desc</span>
                                    </label>
                                </div>
                            </td>
                            <td>
                                <th:block th:text="${element.name}"> -</th:block>
                            </td>
                        </tr>
                    </th:block>
                    </tbody>
                </table>
            </form>
        </div>
    </div>
</div>

</body>
<script th:src="@{/webjars/datatables/1.10.20/js/jquery.dataTables.js}"></script>
<script th:src="@{/webjars/jquery/3.4.1/jquery.js}"></script>
<script th:src="@{/script/datatables.js}"></script>
<script th:src="@{/script/materialize.js}"></script>
</html>

代码 - 控制器

@Controller
public class MyController {

    @GetMapping("/")
    public String home(Model model){

        List<Person> pList = new ArrayList<>();
        pList.add(new Person("Mick"));
        pList.add(new Person("Kevin"));
        pList.add(new Person("Joe"));
        model.addAttribute("persons", pList);

        List<CheckBox> cList = new ArrayList<>();
        for (int i = 0; i < pList.size(); i++) {
            cList.add(new CheckBox(false));
        }
        CheckBoxWrapper checkBoxWrapper = new CheckBoxWrapper(cList);
        model.addAttribute("checkBoxWrapper", checkBoxWrapper);

        return "/home";
    }

    @PostMapping("/submit")
    @ResponseBody
    public String submit(@ModelAttribute CheckBoxWrapper checkBoxWrapper){

        return "success";
    }
}

代码 - 复选框

public class CheckBox {

    private boolean val;

    //Getter, Setter, Constructor

}

代码 - CheckBoxWrapper

public class CheckBoxWrapper {

    List<CheckBox> list = new ArrayList<>();

    //Getter, Setter, Constructor

}

代码 - 人

public class Person{

    String name;

    //Getter, Setter, Constructor

}

【问题讨论】:

    标签: java html datatables thymeleaf materialize


    【解决方案1】:

    如果您可以将隐藏的输入移到复选框上方,那就太好了:

    <label>
       <input type="hidden" name="_list[0].val" value="on"><!-- First is ok! -->
       <input type="checkbox" /><!-- I still display -->
       <span>Red</span>
    </label>
    

    Codepen

    请注意,这里的标记非常严格 - 因为每个唯一的复选框和跨度配对都必须包含在它们自己的标签中。任何变化都会破坏组件。

    https://materializecss.com/checkboxes.html

    【讨论】:

    • 感谢您的回复!那么您会建议更改订单吗?只用JS?
    • JS 可以工作,它很hacky,但可能是你唯一的选择。最好的方法是控制 Thymeleaf 输出隐藏输入的方式/时间/地点。你有什么办法来操纵它吗?
    • 我不知道在哪里可以告诉 thymeleaf 将此隐藏输入放在复选框上方。我让它与 JS 一起工作。如果我找到更好的解决方案,我会分享它:)
    【解决方案2】:

    使用接受的答案作为起点(关键是输入的顺序很重要),我设法想出了一个需要最少 js 的解决方法。只需要手动创建隐藏字段和复选框并适当地命名它们,以便 Spring 可以在提交时找到它们各自的值。隐藏字段必须以“_”为前缀,并且复选框必须在 id 的末尾有一个数字索引。每个值都可以使用 Thymeleaf 表达式从支持字段导出。 例如,如果名为“myForm”的支持对象有一个名为“mySwitch”的字段,您可以执行以下操作:

    <label>
       <input type="hidden" name="_mySwitch" th:value="${myForm.mySwitch} ? 'on'">
       <input type="checkbox" id="mySwitch1" name="mySwitch" th:value="${myForm.mySwitch} ? 'true'" th:checked="${myForm.mySwitch} ? 'checked'">
       Off
       <span class="lever"></span>
       On
    </label>
    

    不幸的是,这仍然需要一些 js 来设置适当的值以进行提交。使用 jQuery:

    $('#mySwitch1').click(function(){
       if ($(this).is(":checked")){
          $(this).val('true');
          $('#_mySwitch').val('on');
       }else{
          $('#_mySwitch').val('');
       }
    });
    

    这将正确地从 Spring @ModelAttribute 读取当前值,并在页面加载时为开关设置适当的状态,并在提交时提供正确的值。希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-07
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      • 2016-04-03
      • 1970-01-01
      • 2017-11-12
      • 1970-01-01
      相关资源
      最近更新 更多