How to use h: selectOneRadio in h: dataTable to select one row?

I have a list of pages displayed in a table. There is a homePage property on every page and I want the switch column for this property to be added to the datatable, and the user can check only one value. How can I get this value on the server side?

I saw several examples: http://jforum.icesoft.org/JForum/posts/list/14157.page , but I would like to know what is the best practice in this case.

+5
source share
3 answers

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; } 
+19
source

I found another solution, and I want to share it with you, is to use h:selectBooleanCheckbox , as well as the only JS select function proposed by BalusC:

  <ace:column id="homePage" headerText="Home Page"> <h:selectBooleanCheckbox value="#{adpage.homePage}" onclick="dataTableSelectOneRadio(this);"></h:selectBooleanCheckbox> </ace:column> 

and JS:

 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; } 

this will check only one checkbox and update the boolean property in the checked / unchecked object.

0
source

The selectedRadioButton variable must be declared outside the function.

 var selectedRadioButton; function uncheckRadioButtons(radioButton) { if (selectedRadioButton != null) { selectedRadioButton.checked = false; } selectedRadioButton = radioButton; selectedRadioButton.checked = true; } 

and in xhtml

  <h:selectOneRadio onclick="uncheckRadioButtons(this);"> <f:selectItem itemValue="null" /> </h:selectOneRadio> 
0
source

All Articles