The dataTable
component provides AJAX-based built-in sorting and filtering based on its columns.
The dataTable
component provides sorting options based on AJAX by enabling the sortBy
attribute at the column level. The following is the definition of a table that lists the Car
data; sorting is enabled on the name
and year
attributes:
<p:dataTable id="sorting" var="car"
value="#{dataTableBean.cars}">
<p:column headerText="Year" sortBy="#{car.year}">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Name" sortBy="#{car.name}"
>
<h:outputText value="#{car.name}" />
</p:column>
</p:dataTable>
When sorting is enabled, the headers of those columns will have the sort direction represented with small arrow icons as pointed out in this image:
The dataTable
component provides filtering based on AJAX by enabling the filterBy
attribute for the columns. The following is the definition of a table that lists the Car
data; filtering is enabled on the name
and year
attributes:
<p:dataTable id="filtering" var="car" value="#{dataTableBean.cars}"> <p:column headerText="Year" filterBy="#{car.year}"> <h:outputText value="#{car.year}" /> </p:column> <p:column headerText="Name" filterBy="#{car.name}"> <h:outputText value="#{car.name}" /> </p:column> </p:dataTable>
When filtering is enabled in the headers of those columns, they will contain input text fields in order to retrieve the filtering characters from the user. The appearance of the table will be as follows:
The dataTable
component provides the filteredValue
attribute where you can collect a list of filtered elements through its value.
Also, it is possible to set filter matching with custom matchers. The filterMatchMode
attribute enables this built-in matcher mechanism, which is set to startsWith
by default. The other possible values are listed as follows:
The filter text field can be positioned before or after the header text by setting the filterPosition
attribute. The values can be either top
or bottom
(the latter is the default value).
With the filterMaxLength
attribute, it is possible to restrict the filter input according to the given number of characters, for example, filterMaxLength="2"
.
When filterMatchMode
is not enough, it's possible to provide custom filtering with the filterFunction
attribute. The method signature provided to the filterFunction
attribute should be stated as follows:
public boolean filterMethod(Object value, Object filter, Locale locale) { }
Filtering also supports a drop-down box as the filtering mechanism instead of the input text field. This can be achieved by providing a list with the filterOptions
attribute. The definition of the column is given here:
<p:dataTable id="withFilterOptions" var="car" value="#{dataTableBean.cars}" style="width: 300px;"> <p:column headerText="Year" filterBy="#{car.year}" filterMatchMode="startsWith"> <h:outputText value="#{car.year}" /> </p:column> <p:column headerText="Name" filterBy="#{car.name}" filterOptions="#{dataTableBean.carNamesAsOptions}"> <h:outputText value="#{car.name}" /> </p:column> </p:dataTable>
The dataTable
component provides global filtering by invoking the client-side method, filter()
. The global filter can be positioned at the header
facet of the table, as shown in the following code snippet:
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Search all fields:" />
<p:inputText id="globalFilter"
onkeyup="carsTable.filter()" />
</p:outputPanel>
</f:facet>
Filtering will be triggered on the onkeyup
event by invoking the mentioned filter()
method of the table, the widgetVar
attribute of which is set to carsTable
. The appearance of a table with global filtering will be as follows:
It's possible to execute post-processing events with <f:event>
that will invoke a method on the backing bean defined with the listener
attribute. The definition of dataTable
with postprocessors is given here:
<p:dataTable id="withPostEvents" var="car" value="#{dataTableBean.cars}"> <f:event type="org.primefaces.event.data.PostSortEvent" listener="#{dataTableBean.postSort}" /> <f:event type="org.primefaces.event.data.PostFilterEvent" listener="#{dataTableBean.postFilter}" /> <p:column headerText="Year" sortBy="#{car.year}" filterBy="#{car.year}"> <h:outputText value="#{car.year}" /> </p:column> <p:column headerText="Name" sortBy="#{car.name}" filterBy="#{car.name}"> <h:outputText value="#{car.name}" /> </p:column> </p:dataTable>
The definitions of the listener methods are given as follows:
public void postSort(ComponentSystemEvent e) { System.out.println(((DataTable) e.getComponent()).getSortColumn().getHeaderText()); } public void postFilter(ComponentSystemEvent e) { DataTable dt = (DataTable) e.getComponent(); for (Iterator it = dt.getFilteredValue().iterator(); it.hasNext();) { Car car = (Car) it.next(); System.out.println(car.getName()); } }
This recipe is available in the demo web application on GitHub (https://github.com/ova2/primefaces-cookbook/tree/second-edition). Clone the project if you have not done it yet, explore the project structure, and build and deploy the WAR file on application servers compatible with Servlet 3.x, such as JBoss WildFly and Apache TomEE.
The showcase for the recipe is available at http://localhost:8080/pf-cookbook/views/chapter5/dataTableSortFilter.jsf
.