Search code examples
primefacesprimefaces-datatable

Primefaces Datatable custom sort Function with dynamic columns


Using Primefaces 3.5, I get a PropertyNotFoundException when I try to use a custom sort function with dynamic columns.

My datatable in xhtml file is (just show the relevant code)

<p:dataTable id="dataTableVersioneMonitoraggio" var="row" value="# {monitoraggioBean.pacchetti}" 
                 rowKey="#{row.pacchetto.id}">

<p:columns value="#{monitoraggioBean.columns}" var="column"
           sortBy="#{row.celle[column.posizione].cella.valore}"
                sortFunction="#{monitoraggioBean.customSort}">               
  ...         
</p:columns>

</p:dataTable>

The incomplete method in my view scope backing bean is:

public int customSort(Object val1, Object val2) {
    System.out.println("mySort" + val1 + "/" + val2);
    return 0;
}

The problem is I can't reach this method in the bean and I get the following errors:

GRAVE [javax.enterprise.resource.webcontainer.jsf.context] (http--0.0.0.0-8080-3) javax.el.PropertyNotFoundException: /monitoraggio.xhtml @80,161 sortFunction="#{monitoraggioBean.customSort}": The class 'com.packman.bean.MonitoraggioBean' does not have the property 'customSort'.

I have tried custom sort function with p:column tag and it works.

Any idea ?

Thanks


Solution

  • I've come up with a solution/workaround. I think this is a bug of Primefaces 3.5 on p columns tag and sortFunction property.

    Primefaces expects a method expression on sortFunction="#{monitoraggioBean.customSort}" but it wants to treat it as value expression and tries to find out for getter/setter methods.

    My workaround is to define "getter" for the name method in sortFunction and to create the Method Expression in the backing bean.

    public MethodExpression getOrdina() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getApplication().getExpressionFactory().createMethodExpression(context.getELContext(), "#{monitoraggioBean.ordina}", Integer.class, new Class[]{Object.class, Object.class});
    }
    

    The mehod for custom sorting has to be defined too in the bean:

    public int customSort(Object val1, Object val2) {
        System.out.println("mySort" + val1 + "/" + val2);
        return 0;
    }
    

    In this way, when you click on the header of a column firstly getOrdina() is called and then customSort(...), where you can implement your sorting logic.

    Enjoy ! :)