Tuesday, June 2, 2009

Nested JSF DataTable - Refresh issue and workaround

Nested dataTables - JSF refresh issue

Nested dataTables can be very useful in iterating over nested collections, but unfortunately JSF has a bug that prevents the nested table from being updated in certain cases. If you see a discrepancy in the nested table this fix might be what you need.

We use a dataTable to iterate over configurations stored in a list inside which each object nests another list. An ice:dataTable component is used to display a collection on the UI and the user has an option of adding new rows to the table. New rows are added without a page refresh, using ICEfaces Ajax capabilities.
We saw the refresh problem when the nested table had a drop-down component which seemed to be copied from the row that was previously in the position of the added row. Fortunately there is a quick work around to fix the issue.
The basic idea is to bind the parent data table to a backing bean component and then force a refresh when a new row is added. This is how you can do it:

1. Create component property in the backing bean:

private UIData tableBinding;
public UIData getTableBinding() {
return tableBinding;
}

public void setTableBinding(UIData tableBinding) {
this.tableBinding = tableBinding;
}


2. Force refresh in the action method by clearing the children of component:


public void processChanges(){
getUIBean().getTableBinding().getChildren().clear();
}


3. Bind the parent data table in jspx:

< ice:datatable id="parentTable" binding = "#{uiBean.tableBinding}">
</ice:dateTable>
-----
Dev environment: ICEfaces 1.8, MyEclipse 6.5, Liferay 5.1.2
 
1.