DataTable Enhancements

PrimeFaces 3.4 brings major refactor and enhancements on DataTable. We’ve been adding features with each release to datatable and at some point it became harder to maintain. For 3.4, we’ve taken our time to improve the internals and thanks to the new clear design, it was easy for us to add various popular requests from the community.

Refer to Datatable from Children

Long time PrimeFaces users would be familiar with this, datatable can’t be updated or processed from it’s children. Common case is deleting a row from table and updating it. This is due to a fact of a mojarra issue actually, myfaces works fine but we’ve overriden some behavior to make it independent from the implementation. So following wasn’t }working;

<p:dataTable id="table"> ... <p:column> <p:commandButton value="Delete" update="table" /> </p:column> </p:dataTable> 1 2 3 4 5 6 <p:dataTable id = "table" > ... <p:column> <p:commandButton value = "Delete" update = "table" /> </p:column> </p:dataTable>

Common workaround was adding an output panel as a wrapper and updating it instead. But it also requires access to naming containers.

<p:outputPanel id="wrapper"> <p:dataTable id="table"> ... <p:column> <p:commandButton value="Delete" update=":form:wrapper" /> </p:column> </p:dataTable> </p:outputPanel> 1 2 3 4 5 6 7 8 <p:outputPanel id = "wrapper" > <p:dataTable id = "table" > ... <p:column> <p:commandButton value = "Delete" update = ":form:wrapper" /> </p:column> </p:dataTable> </p:outputPanel>

As of 3.4, first sample is supported so you don’t need a wrapper anymore. This is also backward compatible for sure.

Column to Process DataGrid-DataList Action

Core UIData, requires a column as a wrapper for it’s children, otherwise it doesn’t process the children and does not provide unique ids to content. This makes sense for dataTable for dataGrid-dataList, there are no columns in layout. So following wasn’t working;

<p:dataGrid or p:dataList var="item" value="#{bean.items}"> <p:commandButton value="Select" actionListener="#{bean.select(item)}" /> </p:dataTable> 1 2 3 <p:dataGrid or p : dataList var = "item" value = "#{bean.items}" > <p:commandButton value = "Select" actionListener = "#{bean.select(item)}" /> </p:dataTable>

Workound was adding a column to process the button or input action;

<p:dataGrid or p:dataList var="item" value="#{bean.items}"> <p:column> <p:commandButton value="Select" actionListener="#{bean.select(item)}" /> </p:column> </p:dataTable> 1 2 3 4 5 <p:dataGrid or p : dataList var = "item" value = "#{bean.items}" > <p:column> <p:commandButton value = "Select" actionListener = "#{bean.select(item)}" /> </p:column> </p:dataTable>

As of 3.4, first sample will work as data component will process children without requiring a column.

First Class p:columns Support

We’ve spent a lot of time on p:columns to fix it’s limitations;

Input and Action Source components are now supported.

Static and Dynamic columns can be used together in dragdrop reordering

LazyDataModel support for sorting and filtering with dynamic columns

Filtering Improvements

Performance of datatable has been improved by introducing filterValue option, we were keeping filtered data in view state before and tried not keeping it anywhere, just do filtering everytime, way before other features like row selection to restore state but realized these two solutions are not perfect. Filtering changes the model so it should be where your model is, the backing bean. FilterValue attribute is a reference to a list in your bean and datatable populates-clears it during filtering. To be backward compatible, fallback is to use viewstate but a log message is provided to migrate. Also filtering now has a short delay just like autocomplete to avoid many ajax requests to the server.

All this is just the visible part of the iceberg, there are tons of other things improved, all will be available next monday.