Sorting and filtering data in dataTable

The dataTable component provides AJAX-based built-in sorting and filtering based on its columns.

How to do it…

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:

How to do it…

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:

How to do it…

The dataTable component provides the filteredValue attribute where you can collect a list of filtered elements through its value.

There's more…

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:

Attribute Value

Action

contains

This applies if the column value contains the filter value

endsWith

This applies when the column value ends with the filter value

equals

This applies if the column value equals the filter value

exact

This applies if the text values of the column and the filter are the same

gt

This applies if the column value is greater than the filter value

gte

This applies if the column value is greater than or equal to the filter value

in

This applies if the column value is in the collection of filter values that are provided

lt

This applies if the column value is less than the filter value

lte

This applies if the column value is less than or equal to the filter value

startsWith

This applies if the column value starts with the filter value

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".

Tip

It is recommended that you use a scope longer than request scope, such as view scope, to keep the filteredValue so that the filtered list is still accessible after filtering.

Custom filtering

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) {
}

Options for filtering

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>

Global filtering

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:

Global filtering

Postprocessing events on sorting/filtering

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());
  }
}

PrimeFaces Cookbook Showcase application

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.249.198