Group radio buttons inside a JSF dataTable component

Write a custom JSF tag for enhancing radio button behavior

JavaServer Faces is a server-side user interface component framework for Java-based Web applications and is now officially part of Java Platform, Enterprise Edition 5. One of the major advantages of JSF is its flexible component architecture.

Though JSF provides standard user interface components, sometimes the standard tags supplied by JSF are insufficient for easily representing complex user interface controls or certain behaviors of some GUI controls. Thus, a JSF developer must often write complex logic and the corresponding Java class in each page. In addition, implementing some special behaviors sometimes requires JavaScript. One such scenario arises while embedding a radio button inside the JSF dataTable tag. A radio button is generally required when we need to select only one option from a set of options. Let's consider two radio button scenarios for a JSF application:

  1. Our first scenario is often employed while using a single selection of a row in a table (dataTable). Here, when the page is submitted to the server side, our intention is to receive the row index selected in the table. In addition, all the radio buttons inside that particular column of the table should behave like a radio group (such as when one is selected, the others are unselected). This simple functionality is pretty difficult to achieve using JSF technology without JavaScript or third-party custom tag libraries. Figure 1 describes the scenario.
  2. The first scenario deals with grouping the radio button within a column. Our second scenario handles just the opposite: we must group the radio buttons inside a row. Say we need a feedback application where a manager rates different employees by selecting a single radio button from different column headers such as excellent or good. As shown in Figure 2, we group the radio buttons within a single row. Again, achieving this functionality using standard JSF tags without JavaScript can prove quite difficult.
Figure 1. Radio buttons grouped within a column of an HTML table
Figure 2. Radio buttons grouped within a row of an HTML table

The problem with standard JSF tags

Let's analyze why standard JSF tags are difficult to implement in our two scenarios. The following JSF page fragment shows the usage of the h:selectOneRadio tag:

 <h:selectOneRadio id="myRadio" value="#{myBackingBean.myRadioValue}">
   <f:selectItems value="#{myBackingBean.myRadioPossibleOptions}"/>   

Alternatively, instead of using f:selectItems, you can use multiple f:selectItems:

 <h:selectOneRadio id="myRadio" value="#{myBackingBean.myRadioValue}">
   <f:selectItem itemValue="0" itemLabel="#{myBackingBean.myRadioPossibleLabel1}"/>   
   <f:selectItem itemValue="1" itemLabel="#{myBackingBean.myRadioPossibleLabel2}"/>   
   <f:selectItem itemValue="2" itemLabel="#{myBackingBean.myRadioPossibleLabel3}"/>   

Note that itemValue property's value can also be taken from the backing bean as value-binding instead of hard-coding.

Both of the two syntaxes mandate that the f:selectItems tag or the f:selectItem tag (which are actually responsible for individual radio items) must be nested inside the h:selectOneRadio tag. All the radio buttons behave as if they were residing under a radio button group. We cannot put this radio button inside a JSF dataTable tag and span the radio button group behavior across rows or across columns because h:selectOneRadio cannot contain the h:column element, which represents a column inside an h:dataTable. When each column is rendered, the name generated by the JSF containers differs for each cell. As a result, individual radio buttons receive different names and create separate radio groups (with only one radio) in each group.

The important point to note is, if we use h:selectOneRadio and f:selectItems or f:selectItem inside dataTable, the radio buttons render properly; that is, when the page renders, the page displays a table that contains the right radio buttons. But the problem is all the radio buttons inside each cell (inside each <tr> and <td> tag) fall under different radio button groups, because each radio button's name attribute is generated uniquely by the JSF container.

1 2 Page 1