使用Thymeleaf-Spring在模板上生成单选按钮

时间:2013-11-08 17:44:18

标签: spring radio-button thymeleaf

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

我正在使用Thymeleaf-Spring作为观点。

目标
我正在创建一个动态表单,其中包含一个包含邮政地址的表。在可用地址中,一个将被标记为主要地址。有关示例,请参阅this fiddle

问题

简短版本 - 每行都有一个单选按钮,我需要在行级别作为一个复选框(已经接受,这必须通过JS完成),并像表级别的单选按钮一样。 / p>

使用以下代码设置表正文。

<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中的值分配一个唯一的名称和ID。这当然会产生每个单选按钮在其自己的组内的不需要的行为。它们都可以同时被选中,而不是在任何给定时间只选择表中的一个。

我的第一个尝试解决方案是修改父行以包含新的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无法再将表单元素连接到object属性。这当然是不可接受的。

当前解决方案
我当前的解决方案,我不是特别喜欢,是坚持使用连接到object属性的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似乎无法处理跨物体的单选按钮列表。

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

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

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

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

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