How-to populate different select list content per table row

A frequent requirement posted on the OTN forum is to render cells of a table column using instances of af:selectOneChoices with each af:selectOneChoice instance showing different list values.

To implement this use case, the select list of the table column is populated dynamically from a managed bean for each row. The table's current rendered row object is accessible in the managed bean using the #{row} expression, where "row" is the value added to the table's var property.

<af:table var="row">
  ...
  <af:column ...>
    <af:selectOneChoice ...>
        <f:selectItems value="#{browseBean.items}"/>
    </af:selectOneChoice>
  </af:column
</af:table>

The browseBean managed bean referenced in the code snippet above has a setItems and getItems method defined that is accessible from EL using the #{browseBean.items} expression.

When the table renders, then the var property variable - the #{row} reference - is filled with the data object displayed in the current rendered table row.

The managed bean getItems method returns a List<SelectItem>, which is the model format expected by the f:selectItems tag to populate the af:selectOneChoice list.

public void setItems(ArrayList<SelectItem> items) {}
 
//this method is executed for each table row
public ArrayList<SelectItem> getItems() {
  FacesContext fctx = FacesContext.getCurrentInstance();   ELContext elctx = fctx.getELContext();   ExpressionFactory efactory =          fctx.getApplication().getExpressionFactory();          ValueExpression ve =          efactory.createValueExpression(elctx, "#{row}", Object.class);   
  Row rw = (Row) ve.getValue(elctx);       
 
//use one of the row attributes to determine which list to query and
 
//show in the current af:selectOneChoice list
 
// ...
 
ArrayList<SelectItem> alsi = new ArrayList<SelectItem>();
 
for( ... ){
     
SelectItem item = new SelectItem();
       
item.setLabel(...);
       
item.setValue(...);
       
alsi.add(item);
  
}
  
return alsi;
}

For better performance, the ADF Faces table stamps it data rows. Stamping means that the cell renderer component - af:selectOneChoice in this example - is instantiated once for the column and then repeatedly used to display the cell data for individual table rows. This however means that you cannot refresh a single select one choice component in a table to change its list values. Instead the whole table needs to be refreshed, rerunning the managed bean list query.

Be aware that having individual list values per table row is an expensive operation that should be used only on small tables for Business Services with low latency data fetching (e.g. ADF Business Components and EJB) and with server side caching strategies for the queried data (e.g. storing queried list data in a managed bean in session scope).

Comments:

Post a Comment:
Comments are closed for this entry.
About

The Oracle JDeveloper forum ranks in the Top 5 of the most active forums on the Oracle Technology Network (OTN).



The OTN Harvest blog is a summary of selected topics posted on the OTN Oracle JDeveloper forum.



It is an effort to turn knowledge exchange into an interesting read for developers who enjoy little nuggets of wisdom





Frank Nimphius

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today