Primefaces Datatable custom sort Function with dynamic columns

24.9k views Asked by At

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

2

There are 2 answers

0
Carmine Carella On BEST ANSWER

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 ! :)

0
Aveline On

I have encountered a similar problem and I solved it like this.

First, I made a Sorter class (helper) which I would then use in my JSF-page through EL.

Sorter.java

@Component
public class Sorter {


    /**
     * Compares two objects that are Strings on their int value. Can be used to sort any column that contains Integer-based data.
     * @param obj1
     * @param obj2
     * @return
     */
    public int sortIdByString(Object obj1,Object obj2){
        int id1 = Integer.parseInt((String)obj1);
        int id2 = Integer.parseInt((String)obj2);
        if(id1 < id2){
            return -1;
        }else if(id1 == id2){
            return 0;
        }else{
            return 1;
        }
    }
}

JSF-page

<p:column headerText="#{msgs['page.customer.detail.vendingMachine.number']}"
    sortBy="#{vendingMachine.nummer}" sortFunction="#{sorter.sortIdByString}">
    <h:outputText value="#{vendingMachine.nummer}"/>
</p:column>