Ad

How To Select Only One Radio Button Out Of A Complete Row In In Jsf?

- 1 answer

My Question is related to jsf.

I am trying to make a jsf dataTable with radio buttons.

For e.g. In the first row, there are 5 columns: The first column has a question and rest 4 are radio buttons.: I want the user to select only one radio button out of the 4 in a single row and repeat the same process for all the rows.

I have read the following link where a javascript code is given for selecting one row using radio-buttons: How to group Radio Buttons in h:datatable jsf2.0 and http://www.javabeat.net/how-to-use-hselectoneradio-inside-hdatatable-in-jsf/

But my requirement is to select one of the radio-button in a row

I got some clue here: http://www.javaworld.com/article/2077687/enterprise-java/group-radio-buttons-inside-a-jsf-datatable-component.html but I would rather prefer a javascript code to do this activity rather than going for a custom tag, if possible.Or if there is another way to do the same in pure jsf.

Edit:

Code in jsp:

<h:dataTable var="row" value="#{rateYourBillerBean.questionsList}">
   <h:column>
      <f:facet name="header">
         <h:outputText value="Question" />
      </f:facet>
      <h:outputText value="#{row.question}" />
   </h:column>
   <h:column>
      <f:facet name="header">
         <h:outputText value="Poor" />
      </f:facet>
      <h:selectOneRadio styleClass="rad" onclick="uncheckOthers(this)" value="#{row.poor}">
         <f:selectItem itemValue="1" />
      </h:selectOneRadio>
   </h:column>
   <h:column>
      <f:facet name="header">
         <h:outputText value="Average" />
      </f:facet>
      <h:selectOneRadio styleClass="rad" onclick="uncheckOthers(this)" value="#{row.average}">
         <f:selectItem itemValue="2" />
      </h:selectOneRadio>
   </h:column>
   <h:column>
      <f:facet name="header">
         <h:outputText value="Good" />
      </f:facet>
      <h:selectOneRadio styleClass="rad" onclick="uncheckOthers(this)" value="#{row.good}">
         <f:selectItem itemValue="3" />
      </h:selectOneRadio>
   </h:column>
   <h:column>
      <f:facet name="header">
         <h:outputText value="Excellent" />
      </f:facet>
      <h:selectOneRadio styleClass="rad" onclick="uncheckOthers(this)" value="#{row.excellent}">
         <f:selectItem itemValue="4" />
      </h:selectOneRadio>
   </h:column>
</h:dataTable>

JS:

<script>
    function uncheckOthers(radio) {
        var name = radio.name.substring(radio.name.lastIndexOf(':'));
        var elements = radio.form.elements;
        for (var i = 0; i < elements.length; i++) {
            if (elements[i].name.substring(elements[i].name.lastIndexOf(':')) == name) {
                elements[i].checked = false;
            }
        }
        radio.checked = true;
    }
</script>

The problem is that each radio button in the consecutive rows have the same value for radio.name.substring(radio.name.lastIndexOf(':')) but the radio buttons in the same row doesn't have the same name as I checked in "View Source" of browser. So how to overcome that.

Ad

Answer

The name of the radio buttons generated in html by jsf in the first row are: j_id_jsp_2000213722_8:0:rad1, j_id_jsp_2000213722_8:0:rad2, j_id_jsp_2000213722_8:0:rad3 and j_id_jsp_2000213722_8:0:rad4

Similarly, the name of the radio buttons generated in html by jsf in the second row are: j_id_jsp_2000213722_8:1:rad1, j_id_jsp_2000213722_8:1:rad2, j_id_jsp_2000213722_8:1:rad3 and j_id_jsp_2000213722_8:1:rad4

So we can see the string after last colon in the name (rad1, rad2, rad3) signifies that the column is different and the integer after the first colon (0,1,2)signifies that the row is different but they are same for every radio button in the same row.

So my logic will be that no two radio buttons with name i.e. 0 or 1 or 2 should be checked at the same time.

So I changed my script code as follows to extract that 0 or 1 or 2 for each row:

<script>
        function uncheckOthers(radio) {
            var name = radio.name.substring(radio.name.indexOf(':') + 1,
                    radio.name.indexOf(':') + 2);
            console.log("name=" + name)
            var elements = radio.form.elements;
            for (var i = 0; i < elements.length; i++) {
                if (elements[i].name.substring(
                        elements[i].name.indexOf(':') + 1, radio.name
                                .indexOf(':') + 2) == name)
                    elements[i].checked = false;
            }
            radio.checked = true;
        }
    </script>

My requirement is that it should allow me to select radio buttons simultaneously in different rows but not in the same row, in the first row all radio buttons have the name 0, in second 1, in third 2, and in fourth row the value of name is 4. So I am taking that part of name which is same for a row,i.e. the part after the first colon so that according to the logic, it will allow only one radio button to be checked with that name and it will uncheck all other radio buttons with the same name except the one checked. So this logic works for me.

Ad
source: stackoverflow.com
Ad