根据JSF规范问题329,我最终在JSF 2.3中实现了它。使用新的group
属性,您现在可以将单选按钮组合在重复器组件中。
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:selectOneRadio group="foo" value="#{bean.selectedItem}">
<f:selectItem itemValue="#{item}" />
</h:selectOneRadio>
</h:column>
</h:dataTable>
它将在Mojarra 2.3.0-m07中提供。
在JSF 2.3之前,使用标准的JSF <h:selectOneRadio>
并不容易实现这个功能。基本上,每一行中的单选按钮需要使用相同的输入名称进行分组,以便在选择一个单选按钮时取消选择其他单选按钮。但是它们没有被分组,它们都有自己的name
属性,因此其他单选按钮永远不会被取消选择。
像PrimeFaces这样的组件库通过提供特殊的属性或列组件来解决这个问题。请参见此示例,该示例使用<p:column selectionMode="single">
生成一个单选列。所选值由<p:dataTable>
的selection
属性引用。如果您已经使用组件库,并且它已经为您提供了这样的组件,请使用它。
在使用标准JSF <h:dataTable>
和<h:selectOneRadio>
时,您需要使用以下JavaScript解决方法,以取消同一列中的所有其他单选按钮的选择:
<h:dataTable value="#{bean.items}" var="item">
<h:column>
<h:selectOneRadio valueChangeListener="#{bean.setSelectedItem}"
onclick="dataTableSelectOneRadio(this);">
<f:selectItem itemValue="null" />
</h:selectOneRadio>
</h:column>
...
</h:dataTable>
使用
public void setSelectedItem(ValueChangeEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
selectedItem = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class);
}
和
function dataTableSelectOneRadio(radio) {
var radioId = radio.name.substring(radio.name.lastIndexOf(':'));
for (var i = 0; i < radio.form.elements.length; i++) {
var element = radio.form.elements[i];
if (element.name.substring(element.name.lastIndexOf(':')) == radioId) {
element.checked = false;
}
}
radio.checked = true;
}
h:selectOneRadio
内使用<f:ajax execute="@this" render="@form" />
以使valueChangeListener
生效时,单选按钮会被选中然后再次取消选中,请问有什么想法吗?我想要被选中的单选按钮保持选中状态,而旧选择的则应该取消选中。 - Mahmoud Saleh<f:ajax>
。 - BalusC