Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to retain the sort order of primefaces datatable?

Tags:

jsf

primefaces

In my project I am using a ViewScoped bean and I have two pages one is main page and the other details page.

In the main page I have a primefaces datatable with sorting and filtering functionality. The datatable has a link in each row. If I sort a column, then it works properly. If I click on a link in the main page, then it will go to the details page showing the details of the corresponding row. In the details page I have a back button. If I click on it, it will take me back to the main page, but the sort order is not retained in the datatable.

I need to retain the sort order. How can I achieve this?

like image 499
user1234 Avatar asked Oct 11 '11 14:10

user1234


People also ask

Is there A P DataTable with sort and filter capabilities in PrimeFaces?

So testing primefaces-10.0.0-RC1 and particularly want to implement a p:dataTable with sort and filter capabilities. The samples look amazing by the way, but they seem to miss some additional context/info in order to understand full implementation requirements.

How to sort data in DataTable component?

As a work around you can call some methods in datatable component to, first know what the last "sorted by column" and the you can use the primefaces datatable sorting feature. This will force the datatable to do the sorting whenever you want: /** * This code will first find what is the current order and the apply the sorting process to data.

How do I set the Order of data in a table?

Using the order initialisation parameter, you can set the table to display the data in exactly the order that you want. The order parameter is an array of arrays where the first value of the inner array is the column to order on, and the second is 'asc' (ascending ordering) or 'desc' (descending ordering) as required.

What is default order in SQL Server?

Default ordering (sorting) The order parameter is an array of arrays where the first value of the inner array is the column to order on, and the second is 'asc' (ascending ordering) or 'desc' (descending ordering) as required. order is a 2D array to allow multi-column ordering to be defined.


2 Answers

I know this question is pretty old, but I just worked on this so I figured I'd share my solution for the future.

We're using PrimeFaces 3.5

This was only implemented on a lazy loading table and never implemented on an in-memory table. The biggest difference that might exist is you would need to store the column type (Class) for an in-memory table.

First of all, you need some sort of SessionScoped controller that you can save the sort state to. You'll need to store two states: sort column and sort order (ascending/descending).

Secondly, bind the p:datatable to an object in your ViewScoped controller (binding="#{viewController.datatable}"), and implement the basic getter and setter for it. In the setter method, I have this:

public void setDatatable(DataTable datatable) {
    ExpressionFactory expressionFactory = ExpressionFactory.newInstance();
    ELContext elContext = FacesContext.getCurrentInstance().getELContext();
    if(!datatableInitialized) {
        if(getSessionController().getSortState() == null) {
            datatable.setValueExpression("sortBy", expressionFactory.createValueExpression(elContext, DEFAULT_SORT_COLUMN, Object.class));
            datatable.setSortOrder(DEFAULT_SORT_DIRECTION);
        } else {
            SortState state = getSessionController().getSortState();
            datatable.setValueExpression("sortBy", expressionFactory.createValueExpression(elContext, state.getValueExpression(), Object.class));
            datatable.setSortOrder(state.getDirection());
        }
        datatableInitialized = true;
    }
    this.datatable = datatable;
}

The important bits are the setValueExpression lines, the second parameter of the createValueExpression method requires the JSF style expression, ie: #{pojo.stuff}. Also notice how I'm just using Object.class as the type, I believe I can get away with this because the table is lazy loaded and I'm handling all the sorting myself in the LazyDataModel implementation.

Third, add the sorting event to the datatable:

<p:ajax event="sort" listener="#{viewController.sortListener}" />

and the listener in the controller:

public void sortListener(SortEvent event) {
    SortState state = new SortState();
    state.setValueExpression(event.getSortColumn().getValueExpression("sortBy").getExpressionString());
    state.setDirection(event.isAscending() ? "ascending" : "descending");
    getSessionController().setOpportunitiesSortState(state);
}

That's it.

like image 56
Greg Noe Avatar answered Oct 16 '22 19:10

Greg Noe


5 years later, PrimeFaces supports this feature out of the box. Starting from version 6.0.10, PrimeFaces added the TableState feature. It will allow your DataTable to maintain its state even after leaving the page.

As stated in the docs, all you need to do is enable the multiViewState attribute on the DataTable.

<p:dataTable id="tableStateTable" value="#{view.items}" var="item" 
             multiViewState="true">
    ...
</p:dataTable>
like image 1
Jaims Avatar answered Oct 16 '22 19:10

Jaims