PrimeFaces dataTable sorting not working

datatablejsfprimefacessorting

I am having trouble getting the PrimeFaces dataTable component's sort behavior to work as documented. (I am using PrimFaces 4.0, JSF 2.1.12, and Tomcat 7.0.) The problem I am seeing doesn't correspond to any of the other problem reports/discussions related to PF dataTable, as far as I can tell. To explore the problem I created an example based closely on the ShowCase example of using a sorted dataTable, copying the ShowCase source code for the tableBean backing bean (including the generation of local car data for the example; no external DB access is involved) and the supporting Car class. The xhtml is also a very close copy of the ShowCase example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
    <h:head>
    </h:head>
    <h:body>
           <h:form>

               <p:dataTable id="dataTable" var="car" value="#{tableBean.carsSmall}">
                   <f:facet name="header">
                       Ajax Sorting
                   </f:facet>

                   <p:column id="modelHeader" sortBy="#{car.model}">
                       <f:facet name="header">
                           <h:outputText value="Model" />
                       </f:facet>
                       <h:outputText value="#{car.model}" />
                   </p:column>

                   <p:column sortBy="#{car.year}">
                       <f:facet name="header">
                           <h:outputText value="Year" />
                       </f:facet>
                       <h:outputText value="#{car.year}" />
                   </p:column>

                   <p:column sortBy="#{car.manufacturer}">
                       <f:facet name="header">
                           <h:outputText value="Manufacturer" />
                       </f:facet>
                       <h:outputText value="#{car.manufacturer}" />
                   </p:column>

                   <p:column sortBy="#{car.color}">
                       <f:facet name="header">
                           <h:outputText value="Color" />
                       </f:facet>
                       <h:outputText value="#{car.color}" />
                   </p:column>
               </p:dataTable>

           </h:form>
    </h:body>
</html>

When the xhtml is run, the data table shows up, but with only one column displayed as being available for sorting (i.e., with the up/down arrow icon in the header).

The dataTable has two problems:

  1. Only one of the columns (Year) is shown as usable for sorting. (Year is a property of type "int" in the Car class, whereas the other three columns are type String, so one aspect of the problem is that the sortBy="#{car.xxx}" tag is being ignored for String fields.)
  2. The Year column is, in fact, not sortable. Clicking on the up/down arrows of the Year header has no effect. A server callback does occur when the Year header is clicked on, but the table is not sorted. I have tracked down an ELException that occurs during the server callback, in which the code is failing to handle the expression "#{car.0}". That "0" should, no doubt, be "year", and the failed expression no doubt is why no sorting is happening.

Any help would be appreciated in figuring out why this very simple example (copied almost verbatim from the ShowCase sources) of trying to use a PrimeFaces sortable dataTable is giving me grief.

Best Solution

Your firs string is

<p:dataTable id="dataTable" var="car" value="#{tableBean.cars}">

so tableBean has a method

public List<Car> getCars()
{
    return carEJB.findAll();
}

but your bean has no variable to save method result after sort.

Solution:

public class CarController
{
...
    private List<Car> cars;
...
    privare void reset()
    {
        cars = carEJB.findAll();
    }
...
    public List<Car> getCars()
    {
        return cars;
    }
}
Related Question