The current JavaServer Faces™ (JSF) implementation does not offer an easy solution for performing single selections on datatable rows. IBM's implementation of JSF does provide a row selection feature with multiple selection checkboxes in a datatable. However, the row selection feature with single selection radio buttons in a datatable -- for choosing just one row and performing more than one action on the specified row object -- has not been implemented.
Developers have been discussing this issue and trying to find solutions and workarounds. Different discussions and suggestions can be found in Sun™ and IBM's JSF discussion forums. The author has investigated two different approaches:
- Render your own radio button using the JSF image component, and use a hidden field together with JavaScript™ to handle the radio button click action
- Use the regular JSF radio buttons together with the JavaScript to handle the radio button selection
Each approach has its advantages and disadvantages. The first approach is more flexible, but it is not as simple as the second approach.
This article presents a JSR168 portlet implementation of the second approach. It shows you how to add row selection feature in a datatable using JSF radio buttons. You will see detailed steps of adding JSF radio buttons in a datatable using IBM® Rational® Application Developer 6.0 (IRAD).
The idea is to use the JSF Radio Button Group (with only one radio button in the group) in the datatable row for the radio button itself, and to use JavaScript functionality to handle the radio button click (select or clear radio buttons). By correctly setting the properties of the selectOne Radio button component, you can bypass the validation of the radio button component, and then use JavaScript functions to control the behavior (status change and row highlighting) of the radio buttons instead. The context of the selected row is passed to the backing bean through the valueChangeListener().
This section describes the implementation details. In this example, the implementation is done in IRAD and tested on IBM® WebSphere® Portal test server v5.1.
This example assumes that you have created a datatable of 2 columns in a JSR 168 portlet project in IRAD (as shown in Figure 1), and that you have the following files:
- TableRow.java (data model)
- TableDataBean.java (Java bean )
- RowSelectRadioButtonInDataTableView.jsp (Automatically generated JavaServer Page™ or JSP)
- RowSelectRadioButtonInDataTableView.java (Automatically generated backing bean)
Figure 1. A simple datatable without row selection
The data model, TableRow.java, presented here is a minimal example just for the purpose of the demo implementation. Listing 1 illustrates the base table data model that defines the data structure of your table row object.
Listing 1. TableRow.java
public class TableRow {
String name, id;
public TableRow(String name, String id) {
this.name = name;
this.id = id;
}
… …
}
|
Listing 2 is the JavaBean™ that prepares the data for your datatable.
Listing 2. TableDataBean.java
public class TableDataBean {
private TableRow[] tableRow;
private List tableRows;
public TableDataBean() {
tableRows = new ArrayList(10);
tableRows.add(new TableRow("PETER","000001"));
tableRows.add(new TableRow("PATRIC","000002"));
tableRows.add(new TableRow("RONALD","000003"));
tableRows.add(new TableRow("ROGERS","000004"));
tableRows.add(new TableRow("RICHARD","000005"));
tableRows.add(new TableRow("TOMLEE","000006"));
tableRow = (TableRow[]) tableRows.toArray(new TableRow[tableRows.size()]);
}
……
}
|
The JSP view and the backing bean are automatically generated when you create the portlet project. In this example, they are named RowSelectRadioButtonInDataTableView.jsp and RowSelectRadioButtonInDataTableView.java.
Now you want to add a row selection column so that you can perform single row selection on this datatable. The following sections describe how to add this row selection feature using the visual design tool in IRAD.
Add properties in your backing bean
Add the following code (Listing 3) in your backing bean (in this example, the backing bean is RowSelectRadioButtonInDataTableView.java).
Listing 3. Backing bean code
private Integer id; //For radio button component value
private int selectedRowId = -1; // For radio button item value, also used as selected row ID.
private TableRow selectedRow; // For table row data.
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public int getSelectedRowId() {
return selectedRowId;
}
public TableRow getSelectedRow() {
return selectedRow;
}
|
The attribute id is for the component value of the Radio Button Group. It will be bound to the Value field (see Figure 6 in the following section). The attribute selectedRowId is for the item value of the radio button, and will be bound to the item value field (see Figure 7). The key to making the group work in a datatable is to set the above two values properly. The two values must be the same type or compatible types (otherwise, you will get validation error). In this example, we use Integer and int (they are compatible). You can also use String if you want. If the component value is null, then the JSF will skip the validation when the form is submitted. Otherwise, it will compare each item value with the component value in a radio button group. If they are the same, that radio button item is selected.
In a datatable, you have a radio button group (contains only one item) in each row. If the component value is the same as the item value, all rows will be selected. That's not what we want. Therefore, you should not set any value to the id attribute (it is null if not set). This way, you bypass the validation. No radio button is selected after the form is submitted. You can then use the JavaScript to select or clear the radio button you clicked (refer to the following sections for details). It does not matter how you set the value of selectedRowId here. In this example, it is set to -1, because it is reused as the selected row number and -1 means no selection is made. The attribute selectedRow is for the TableRow object which holds the data of the selected row in your datatable.
Add a new column for row selection
Using IRAD tools, you can perform the following steps (see Figure 2):
- Select the datatable and go to Properties
- Choose
h:datatable - Click Add to add a new column
Figure 2. Adding new column
- Then, you set the Label of the column to Select and move it up to the top, as shown in Figure 3.
Figure 3. New column setting
The new column is added. The next step is to add the Radio Buttons to the new column.
Add JSF Radio Button Group component
- After a new column is added, drag the Radio Button Group component from the Faces Components palette into the new column (see Figure 4) to add the radio button.
Figure 4. Add Radio Button Group in datatable
- In the Properties view, Click Add Choice and then remove the Name and Value in the radio button choice table. The Properties view should look like Figure 5.
Figure 5. Properties view for radio button
Then, you set the component value to the following:
"#{pc_RowSelectRadioButtonInDataTableView.id}".
Figure 6 describes the detailed steps of how to do that.
Figure 6. Set the component value
You also need to set the item value to this:
"#{pc_RowSelectRadioButtonInDataTableView.selectedRowId}".
Figure 7. Set the item value
Now you've completed the settings. The properties of the radio button should look like Figure 8.
Figure 8. Radio button properties
Now, you have added the radio button in the datatable. You can save the files and run your code. You will see the radio buttons in the datatable, and you can click on them. Notice that when you select a new row, previously selected rows are not cleared. You need to use a JavaScript function to handle this.
Add JavaScript functions in your JSP to handle radio button click
You need to change the states of radio buttons so that when you click on one of them, only this radio button is selected, all others are cleared, and the newly selected row is highlighted.
This can be done on the client with the help of JavaScript. You can add the following functions (Listing 4) in your JSP (In this example, the JSP is RowSelectRadioButtonInDataTableView.jsp).
Listing 4. Adding functions to your JSP
The JavaScript function radiobuttonClick(thisObj, thisEvent) takes the object as input. The input object thisObj is the radio button being clicked. This function loops through each element in the form (assuming the name is form1) and checks whether the element is a radio button (assuming the name is radio1) inside your datatable (assuming the name is table1). It sets the states of all radio buttons in the datatable to false (clear all radio buttons first) and the state of the current radio button to true (this is the clicked radio button passing in by thisObj). Then it finds the row that this radio button belongs to and highlights the row. Function getRow(element) just returns the parent row object that a radio button belongs to.
In order to highlight the selected row, you need to add a link to the Style sheet, and add the rowHighlighted class in your style sheet (Listing 5).
Listing 5. Adding the rowHighlighted class
.rowHighlighted{
background-color:#8C92C6; //This is just an example color
}
|
To invoke this function, add the call in Listing 6 to the selectOneRadio tag in your JSP file.
Listing 6. Adding a call in your JSP file
Now, you can click on the radio buttons to make a selection. The radiobuttonClick() function is invoked when you click on a radio button inside the dataTable row. The selected radio button will be checked and the selected row highlighted.
Handle value change and actions in backing bean
The purpose of having a selectOne radio button is to be able to perform different actions on a specific table row. In order to do that, you need to know which row is selected. This can be done by adding code in the handleRadio1ValueChange() method of your backing bean (in this example, this is RowSelectRadioButtonInDataTable.java). Figure 9 shows how to do that.
- Select the radio button
- Go to Properties view and select the Quick Edit tab
- Choose Value Changed
- Double click in the view area and then add the code shown in Figure 9
Figure 9. Handle value changed action
Note that the selectedRow is the table row object of type TableRow (in this example). Make sure you have defined it.
Finally, let's handle the actions on the selected row. Since you know the selected row ID and selected row data through valueChangedListener (see Figure 9), you can pass them to the next view for processing. In this example, all you do is display which row is selected and the details of the selected row. We use the Show Selected Row button to invoke the response view RowSelectActionResponse.jsp and display the details of the selected row in it. The selectedRowID and selected row data can be passed in request scope. Figure 10 shows how this is done.
- Click Show Selected Row
- Go to Properties view and select the Quick Edit tab
- Choose command and double click in the properties view
- Then add the code shown in Figure 10
Figure 10. Handle actions on selected row
In RowSelectActionResponse.jsp, there are fields (selected row, action, ID, and Name) that contain the selected row information. They are bound to the request variables that are set in the doButton1Action() method(Figure 10). Figure 11 shows how the values of the fields are bound to the request scope variables (in the Design view of the IRAD visual editor).
Figure 11. Value binding in Row Select Response view
This view just gives an example of how you can handle actions on your selected row. You will hook up your own views in your application. For details of this view and its backing bean, refer to the source code of RowSelectResponse.java.
Now that you have completed adding row selection in your datatable, test it to see how it works. Figures 12 and 13 demonstrate how the example implementation of row selection works.
Figure 12. Making single row selection
Figure 13. Details view of the selected row
The idea of adding a row selection feature in the JSF datatable using the existing JSF selectOne radio buttons and JavaScript has been discussed by different people in JSF forums. This article presented a JSR 168 portlet implementation of this idea using IRAD. The approach presented in this article can be served as a workaround for the single row selection feature of a JSF datatable before JSF offers an implemented solution.
The author would like to thank Yury Kats of the IBM Software Group for reviewing this article and offering valuable suggestions.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample source code | codesample.zip | 2.57 MB | HTTP |
Information about download methods
Learn
-
Sun's JSF forum: The problem of row selection using radio buttons in a datatable has been discussed by many people in Sun's JSF forum. Do check the following threads--thread 1 and thread 2.
-
Eclipse.org: For information about Eclipse development.
-
IBM Rational Application Developer product page: Find technical documentation, how-to articles, education, downloads, and product information about Rational Application Developer.
Get products and technologies
-
IBM Rational Application Developer: Download a trial version from developerWorks.
Discuss
- Participate in the discussion forum.
-
Rational Software Architect, Software Modeler, Application Developer and Web Developer forum: Ask questions about Rational Application Developer.
-
JavaServer Faces forum: Ask questions about IBM WebSphere JavaServer Faces.




