According to the JSF 329 specification, I finally implemented it for JSF 2.3. With the new group attribute, you can group switches in the repeater component.
<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>
It will be available according to Mojarra 2.3.0-m07.
Prior to JSF 2.3, this is not trivial with the standard JSF <h:selectOneRadio> . In fact, the radio buttons in each row should be grouped with each other using the same input name so that other radio buttons are not marked with each selection. But they are not grouped, they have all their own name , so other switches will never be disabled.
Component libraries, such as PrimeFaces, solved this problem by providing a special attribute or column component. See also this demo example, which uses <p:column selectionMode="single"> to generate a single selection column. The selected value is referenced by the selection <p:dataTable> . If you are already using a component library and already have such a component in it, you should use it.
In the standard JSF <h:dataTable> with <h:selectOneRadio> you will need to enter a JavaScript workaround as follows, which removes all the other switches in the same column:
<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>
from
public void setSelectedItem(ValueChangeEvent event) { FacesContext context = FacesContext.getCurrentInstance(); selectedItem = context.getApplication().evaluateExpressionGet(context, "#{item}", Item.class); }
and
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; }