Thursday, July 22, 2010

Determine Which Row is Selected in a JSF Table

Let's say you have a JSF table with numerous rows, and that when one of them is "selected" you'd like to know which one it is. Let's assume a JSF event is fired off when you click on the row, resulting in a callback to your application. In this callback, you want to determine the identity of the row in a way that correlates to your application, such that you can proceed with whatever action is needed. Here's the sequence:
  1. Table is constructed with rows representing application objects A, B and C
  2. User clicks somewhere in row B, e.g. in an input text box
  3. JSF event fires and your application is called back
  4. The application determines that B has been selected and processes that application object as needed
Now the obvious way to "determine that B has been selected" would be to simply set the ID attribute for each row to an identifying value at table construction time. But, using such variables for the ID attribute is not allowed in JSF. Don't ask me why. Here's one way to get around this:
  1. Add a parameter to the UIComponent with the identity as needed
  2. Register an interest in the JSF event that will get fired when the UIComponent is selected
  3. Examine the event received in your application callback to find the UIParameter child
  4. Examine the UIParameter to extract the identity of the row
The code snippets, first for the JSF markup addressing step #1 and #2. Note that I'm using IceFaces, setting the per-row variable for use in each UIComponent comprising each row:
<ice:dataTable 
     var="thisRow"
     value="#{app.allRows}"
    ....
>
....
    <ice:inputText valueChangeListener="#{app.callback}">
        <f:param name="name" value="#{thisRow.id}"/>
    </ice:inputText>
....
</ice:dataTable>
Here are steps #3 and #4, the application callback:
public void callback(ValueChangeEvent event) { 

    for (UIComponent child : event.getComponent().getChildren()) {
        if (child instanceof UIParameter) {
            UIParameter param = (UIParameter) child;
            if ("name".equals(param.getName())) {
                String thisID = (String)param.getValue();
                if (thisID.equals(theIDofInterest)) {
                    // process as needed
                }
            }
        }
    }

No comments:

Post a Comment