0
votes

I'm new to JSF and have trouble with sorting in a DataTable. I use Tomcat 7 and Jetty 9 (Jetty for testing) and PrimeFaces 5.1 with JSF-2.2. I display some results on a page in a DataTable. I want to have this sortable, and with my code, the columns display sorting arrows, but clicking on them does not sort the table, it just changes the sort-indicator arrow in the column header. I'm aware of the question , but the solution in that does not work and contradicts the code in the PrimeFaces showcase.

I made a small sample to demonstrate the problem:

table.xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<!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:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
    <h:form>
        <p:dataTable value="#{tableTest.list}" var="token">
            <p:column headerText="Fisch" sortBy="#{token}">
                <h:outputText value="#{token}"/>
            </p:column>
        </p:dataTable>
    </h:form>
</h:body>
</html>

Backing bean:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import java.util.Arrays;
import java.util.List;

@ManagedBean(name = "tableTest")
@RequestScoped
public class TableTest {

    public List<String> getList() {
        return Arrays.asList("Aal","Zander","Barsch","Brasse","Wels","Feldchen");
    }
}

The servlet mapping in web.xml:

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
    <!-- Production -->
</context-param>

<context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xhtml</param-value>
</context-param>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

<!-- HTML comments become components unless they're stripped -->
<context-param>
    <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
</context-param>

When I inspect the newtork with firefox's debug mode, I see the following response for clicking on sort:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response id="j_id1">
    <changes>
        <update id="j_idt4:j_idt5">
            <![CDATA[
            <tr data-ri="0" class="ui-widget-content ui-datatable-even" role="row">
                <td role="gridcell">Aal</td>
            </tr><tr data-ri="1" class="ui-widget-content ui-datatable-odd" role="row">
                <td role="gridcell">Zander</td>
            </tr>
            <tr data-ri="2" class="ui-widget-content ui-datatable-even" role="row">
                <td role="gridcell">Barsch</td>
            </tr>
            <tr data-ri="3" class="ui-widget-content ui-datatable-odd" role="row">
                <td role="gridcell">Brasse</td>
            </tr>
            <tr data-ri="4" class="ui-widget-content ui-datatable-even" role="row">
                <td role="gridcell">Wels</td>
            </tr><tr data-ri="5" class="ui-widget-content ui-datatable-odd" role="row">
                <td role="gridcell">Feldchen</td>
            </tr>]]>
        </update>

        <update id="j_id1:javax.faces.ViewState:0">
            <![CDATA[5844788699585149238:6667543622103173254]]>
        </update>
    </changes>
</partial-response>

I'm new to JSF and have no more clues how to get the sorting to work. Can somebody help me to get the sorting function working?

1

1 Answers

1
votes

You might want to view scope your backing bean and add a list property like this:

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import java.util.Arrays;
import java.util.List;

@ManagedBean(name = "tableTest")
@ViewScoped
public class TableTest {

    private List<String> fishList;

    @PostConstruct
    public void init() {
        this.fishList = Arrays.asList("Aal","Zander","Barsch","Brasse","Wels","Feldchen");
    }

    public List<String> getFishList() {
        return this.fishList;
    }

}

To be exact: the view-scope is optional, but you need a real property. So this example would also work, although i do not recommend it:

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

import java.util.Arrays;
import java.util.List;

@ManagedBean(name = "tableTest")
@RequestScoped
public class TableTest {

    private List<String> list = Arrays.asList("Aal","Zander","Barsch","Brasse","Wels","Feldchen");

    public List<String> getList() {
        return list;
    }

}

The reason for this behaviour is, that the property (the list) is accessed multiple times during the request. And in your example you always return a new list (Arrays.asList creates a new list with a new id) on every access to the property. Yet, it seems that list-sorting only works when the list object stays the same during the request.