FlyingSpaten
FlyingSpaten

Reputation: 101

Primefaces 5 dynamic DataTable pre-Sort

I'm trying to build a fully dynamic DataTable with Primefaces 5.0.

I've got a Config-Object for eachs column and I want the DT to sort by one of them from the beginning.

Here's my DT:

<p:dataTable id="ticketTable"
                 widgetVar="ticketTable"
                 value="#{ticketBean.ticketDataModell}"
                 var="ticket"
                 lazy="true"
                 paginator="true"
                 rows="20"
                 sortBy="#{dataPortletConfigBean.sortByKey}"
                 >

The sortByKey is a String. It's the name of the Variable I want to sort by. So I want to replace something like sortBy="key" with sortBy="#{bean.GiveMeAKey}".

But it doesn't work. I get this: could not resolve property: sortByKey of: [...]

How can I get this to work? Thanks

Upvotes: 1

Views: 4266

Answers (3)

FlyingSpaten
FlyingSpaten

Reputation: 101

I got it working now.

First: The Problem. I wanted to give the Data-Table the possibilty to have a default-sort (on load). Thats what the sortBy-Tag in <p:dataTable> does or should do.

As long ass you write your sort-field in the DT-Tag e.g. sortBy="name" it works. But when you pass a ValueExpression as for Example sortBy="#{bean.giveMeSomeKey}". He just cuts the '#{', everything bevor the '.' and the last '}' away an tries to sort by the field with the name of his result String. In this case 'giveMeSomeKey'.

That makes a default sorting with dynamic values impossible. (At least in PF 5.0)

Second: The Resolve. I checked out the PF 5.0-Sources and modified the DataTableTemplate-File. (It's a template, wich is filled when PF is being built. It will later be compiled into the DataTable-Class).

There I modified the Method protected String resolveSortField().

Before:

protected String resolveSortField() {
        UIColumn column = this.getSortColumn();
        String sortField = null;
        ValueExpression tableSortByVE = this.getValueExpression("sortBy");
        Object tableSortByProperty = this.getSortBy();
        if(column == null) {
            sortField = (tableSortByVE == null) 
                     ? (String) tableSortByProperty 
                     : resolveStaticField(tableSortByVE);
        }

After:

protected String resolveSortField() {
        UIColumn column = this.getSortColumn();
        String sortField = null;
        ValueExpression tableSortByVE = this.getValueExpression("sortBy");
        Object tableSortByProperty = this.getSortBy();
        if(column == null) {
            sortField = (tableSortByVE != null) 
                ? tableSortByVE.getExpressionString().contains("[") 
                ? resolveDynamicField(tableSortByVE) 
                : resolveStaticField(tableSortByVE) 
                : (String) tableSortByProperty;
        }

After building and including it into my project it worked.

So now I can tell my DT:

<p:dataTable [...] sortBy="#{ticket[dataPortletConfigBean.sortByKey]}" And it will default-sort my DT After the (String)key I pass him with sortByKey, as long as it is a field in my Ticket.

It's not the perfect solution, but it works.

Upvotes: 1

spauny
spauny

Reputation: 5096

I don't remember if this was available in PF 5.0 but now in 5.1 you can use the sortField attribute present in datatable. This was implemented for this exact purpose:

From Primefaces documentation:

sortField: Name of the field to pass lazy load method for sorting. If not specified, sortBy expression is used to extract the name.

After that you have to define a similar value for each column using the field attribute. If the columns are not dynamic just the sort then the field attribute will be the same value as the column itself has.

Snippet of code:

 <p:dataTable  var="repo" value="#{repoStrategy.flaggedRepos}" sortOrder="${repoStrategy.sortOrder}" sortField="${repoStrategy.sortBy}"
                                  style="width: 100%" paginator="true" rows="10" rowIndexVar="rowIndex" >

           <p:column headerText="Name" sortBy="#{repo.name}" field="repo.name">
                  <a href="#{repo.url}" target="_blank">#{repo.name}</a>
           </p:column>

Upvotes: 0

Yamada
Yamada

Reputation: 723

I tested your requirement and it worked fine.

Check if your property sortByKey in dataPortletConfigBean is returning a string like in:

public String getSortByKey() {
  return "ticket.number";
}

Also ensure that the targeted column defines the sortBy attribute:

<p:column sortBy="#{ticket.number}" headerText="Number"> 
   #{ticket.number}
</p:column>

Upvotes: 0

Related Questions