开发者

How to retain the sort order of primefaces datatable?

开发者 https://www.devze.com 2023-04-12 19:02 出处:网络
In my project I am using a ViewScoped bean and I have two pages one is main page and the other details page.

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 ne开发者_JS百科ed to retain the sort order. How can I achieve this?


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.


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>
0

精彩评论

暂无评论...
验证码 换一张
取 消