我无法使用我想要的行为创建动态表单。我想我有一个解决方案,但我认为那里必须有更好的解决方案。
我正在使用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:id
和th: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似乎无法处理跨物体的单选按钮列表。
我认为其他人也遇到了同样的限制。你是怎么克服的?我目前的解决方案是目前最好的吗?任何人都可以提供更好的选择吗?
感谢您的时间。
答案 0 :(得分:0)
我认为您的问题是只在表单中选择一个单选按钮。因为您仍然需要将唯一名称应用于单选按钮以维护面向对象的方法。您可以应用以下JavaScript来强制只选择一个项目并取消选择同一页面上的剩余项目:
$(document).ready(function(e) {
$("input[type=radio]").change(function() {
$('input[type=radio]:checked').not(this).prop('checked', false);
});
});
如果此页面上有另一组单选按钮,则可以更改选择器。