2

我无法创建具有我想要的行为的动态表单。我想我有一个解决方案,但我认为必须有一个更好的解决方案。

我正在使用 Thymeleaf-Spring 作为视图。


正在创建一个动态表单,其中将包含一个包含邮政地址的表格。在可用地址中,一个将被标记为主地址。有关示例,请参见此小提琴。

问题

短版 - 每行都有一个单选按钮,我需要在行级别充当复选框(已经接受这必须通过 JS 完成),并且在表级别充当单选按钮。

表体是使用以下代码设置的。

<tr th:each="addr : ${addresses}" th:include="address :: row"
    th:with="prefix=__${prefix}__.address[__${addrStat.index}__]."/>

存在前缀变量分配是因为该表嵌套在表单上的几个级别。它所做的只是将额外的数据附加到已经存在的前缀上。

被拉入的地址片段如下所示(为简洁起见,此处为压缩格式):

<tr th:fragment="row">
    <td>
        <input type="text" th:field="*{__${prefix}__line1}"/>
        <input type="text" th:field="*{__${prefix}__line2}"/>
    </td>
    <td><input type="text" th:field="*{__${prefix}__city}"/></td>
    <td><select th:field="*{__${prefix}__state}"/></td>
    <td><input type="text" th:field="*{__${prefix}__zip}"/></td>
    <td><select th:field="*{__${prefix}__type}"/></td>
    <td><input type="checkbox" th:field="*{__${prefix}__valid}"/></td>
    <td>
        <input type="radio"
               th:field="*{__${prefix}__primary}"
               th:value="*{__${prefix}__primary}"
               th:checked="*{__${prefix}__primary}"/>
    </td>
</tr>

将放置一点 jQuery 以确保元素的值true是选中单选按钮时,false否则。

问题是当 Thymeleaf 生成这些行中的每一行时,每个单选按钮都根据th:field. 这当然会产生每个单选按钮在其自己的组内的不良行为。它们都可以同时被选中,而不是在任何给定时间只选中表中的一个。

我第一次尝试的解决方案是修改父行以包含一个新group变量:

<tr th:each="addr: ${addresses}" th:include="address :: row"
    th:with="group='__${prefix}__primaryAddress',  
             prefix='__${prefix}__address[__${addrStat.index}__].'"/>

然后将th:field单选按钮上的属性替换为个人th:idth:name属性:

<input type="radio"
       th:id="'__${prefix}__primary'"
       th:name="${group}"
       th:value="*{__${prefix}__primary}"
       th:checked="*{__${prefix}__primary}"/>

这在表单上提供了所需的行为,但以失去回发价值为代价。Thymeleaf-Spring 无法再将表单元素连接到对象属性。这当然是不能接受的。

当前解决方案
我当前的解决方案,我不是特别喜欢,是坚持使用th:field连接到对象属性的属性并包含一个data-group属性,该属性将允许我通过 jQuery 强制分组。

<input type="radio"
    th:field="*{__${prefix}__primary}"
    th:value="*{__${prefix}__primary}"
    th:checked="*{__${prefix}__primary}"
    th:attr="data-group=${group}"/>

就像我说的那样,我不是特别喜欢这个解决方案,因为我觉得我正在覆盖(或者可能是复制)单选按钮的标准行为,但我找不到任何其他方法。目前,Thymeleaf 似乎无法处理跨对象的单选按钮列表。

我认为其他人也遇到了同样的限制。你是怎么克服的?我目前的解决方案是目前最好的吗?谁能提供更好的选择?

感谢您的时间。

4

1 回答 1

0

我认为您的问题是在表单中只选择一个单选按钮。因为您仍然需要对单选按钮应用唯一名称以维护面向对象的方法。您可以应用以下 JavaScript 来强制仅选择一项并取消选择剩余在同一页面上的内容:

$(document).ready(function(e) {
    $("input[type=radio]").change(function() {
        $('input[type=radio]:checked').not(this).prop('checked', false);
    });
});

如果此页面上有另一组单选按钮,您可以更改选择器。

于 2018-03-21T09:08:14.680 回答