Rectangle 27 1

This might be a PrimeFaces bug. I have seen some discussion about issues with DataTable sorting when a data model is used. Here is a link to one of the PrimeFaces defects in their tracker.

I just got the same answer in the forum! Actually Sorting for ListDataModel has been fixed in the last snapshot 3.0M2. And Am creating a Ticket for Filtering too. Thanks Jim

Thanks for the heads-up about the latest snapshot. I'm not using ListDataModel yet, but I'm probably going to need it in the future.

PrimeFaces DataTable Sorting & Filtering don't work with JSF DataModel...

jsf primefaces datamodel
Rectangle 27 2

I would like to confirm that I experience exactly the same problem described with primefaces-2.2.1.

The value (row elements) of my dataTable are computed from a query.

Sorting on a simple name String property fails unless I also have a filterBy, and even then it only works if I type in at least one letter into the filter box. Then I can sort ascending/descending within the filtered result.

Further I tested initialising the list only on page load (using <f:event type="preRenderView" listener="#{backingBean.reset}"/>) and the problem still occurs, although that strategy does ensure that other features of p:dataTable, such as inline cellEditor now work correctly (as described at stackoverflow.com/questions/6365877/). I think we are experiencing a genuine bug, not a misuse of the p:dataTable.

I never fixed that one. Probably as you said we are facing a bug,maybe with a different version of primefaces things are different. I still don't know how to solve it.

java - dataTable sorting problem (JSF2.0 + primefaces) - Stack Overflo...

java jsf java-ee jsf-2 primefaces
Rectangle 27 10

I wrote an extension to @truemmer's solution. His reverts the sorting order back to the default, where as mine will reverts to the previous sort the user selected.

Updating the same table as truemmer's works like this:

<p:commandButton value="refresh" action="#{tableController.refreshPrices}" update="myTable" oncomplete="postAjaxSortTable(myTableWidget)" />
function postAjaxSortTable(datatable) {
    var selectedColumn = undefined;

    // multisort support
    if(datatable && datatable.cfg.multiSort) {
        if(datatable.sortMeta.length > 0) {
            var lastSort = datatable.sortMeta[datatable.sortMeta.length-1];
            selectedColumn = $(document.getElementById(lastSort.col));
        }
    } else {
        selectedColumn = datatable.jq.find('.ui-state-active');
    }

    // no sorting selected -> quit
    if(!selectedColumn || selectedColumn.length <= 0) {
        return;
    }

    var sortorder = selectedColumn.data('sortorder')||"DESCENDING";
    datatable.sort(selectedColumn, sortorder, datatable.cfg.multiSort);
}

Nice solution. I'll upgrade to 3.5 soon and give it a try :) There's been lots of refactoring for tables in the current release.

I should note that I have been using this in 3.4.2. I don't know if this works very well or not in 3.5.*, but I doubt I'll be upgrading yet.

Still works under PrimeFaces 4.0 but I'm trying to improve it in order to manage multisort

sorting - p:datatable loses sort column and order after ajax refresh -...

ajax sorting jsf-2 primefaces datatable
Rectangle 27 1

Add this PhaseListener to your application and both sorting and filtering will be kept after updating the DataTable.

public class DataTableUpdatePhaseListener implements PhaseListener {

    private static final long serialVersionUID = 1L;

    @Override
    public void afterPhase(PhaseEvent event) {
        // Nothing to do here
    }

    @Override
    public void beforePhase(PhaseEvent event) {
        FacesContext facesContext = event.getFacesContext();
        if (!facesContext.isPostback()) {
            return;
        }

        PartialViewContext partialViewContext = facesContext.getPartialViewContext();
        if (partialViewContext != null) {
            Collection<String> renderIds = partialViewContext.getRenderIds();

            for (String renderId : renderIds) {
                UIComponent component = facesContext.getViewRoot().findComponent(renderId);
                if (component instanceof DataTable) {
                    DataTable table = (DataTable) component;
                    if (!table.isLazy()) {
                        updateDataTable(table);
                    }
                }
            }
        }
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }

    private void updateDataTable(DataTable table) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        if (facesContext == null || table == null) {
            return;
        }

        // Reapply filtering
        if (!table.getFilters().isEmpty()) {
            FilterFeature filterFeature = new FilterFeature();
            filterFeature.decode(facesContext, table);
        } else {
            table.setFilteredValue(null);
        }

        // Reapply sorting
        ValueExpression tableSortByVE = table.getValueExpression("sortBy");
        if (tableSortByVE != null) {
            String tableSortByExpression = tableSortByVE.getExpressionString();

            // Loop on children, that are the columns, to find the one whose order must be applied.
            for (UIComponent child : table.getChildren()) {
                Column column = (Column) child;
                ValueExpression columnSortByVe = column.getValueExpression("sortBy");
                if (columnSortByVe != null) {
                    String columnSortByExpression = columnSortByVe.getExpressionString();

                    if (tableSortByExpression != null && tableSortByExpression.equals(columnSortByExpression)) {
                        // Now sort table content
                        SortFeature sortFeature = new SortFeature();
                        sortFeature.sort(facesContext, table, tableSortByVE,
                                SortOrder.valueOf(table.getSortOrder().toUpperCase(Locale.ENGLISH)),
                                table.getSortFunction());

                        break;
                    }
                }
            }
        }
    }
}

This is for non-lazy data tables. Data tables using a lazy model do not require this, as the lazy model will take care of sorting and filtering. For non-lazy data tables, this should work with both single and multiple column sorting but there is a bug in Primefaces that makes DataTable loose its MultiSortMeta between postbacks when updating the table. This means that the columns selected for sorting before postback are completely lost from FacesContext and component state and cannot be retrieved anymore upon postback. I'll look more into this later and provide an update if I manage to find a workaround or maybe Primefaces will fix it soon.

sorting - p:datatable loses sort column and order after ajax refresh -...

ajax sorting jsf-2 primefaces datatable
Rectangle 27 3

Solution posted below (LazyTable) works for the p:dataTable backed with LazyDataModel. Overriden load method is called after every update/refresh on the desired table and it handles sort properly. The problem with simple p:dataTable is that it performs predefined sort only on the first load, or after the click on sort column. This is a normal behaviour of a simple table.

So what are your possibilities for simple table :

Don't sort the table after update, but remove the sort column so end user is not missinformed. Add this to your action listener or action method for your update button :

UIComponent table  = FacesContext.getCurrentInstance().getViewRoot().findComponent(":dataTablesForm:dataTableId");
table.setValueExpression("sortBy", null);

Update the sort of the table manually by script. This is not the best solution, but primefaces doesn't provide any client side function for "resorting" the table. Basically you know that only one column at a time can be sorted and this column has a .ui-state-active. You can use it in a script and trigger 2 clicks on that column (1. click - other sort order, 2. click - back to current sort order).

<h:form id="mainForm">  
<div id="tableDiv">
   <p:dataTable id="dataTable" var="item" value="#{testBean.dummyItems}">
      .
      .
      .
   </p:dataTable> 
   <p:commandButton value="Refresh" oncomplete="refreshSort();" update=":mainForm:dataTable"/>
 </div>
function refreshSort(){
jQuery('#tableDiv').find('.ui-state-active').trigger('click');
jQuery('#tableDiv').find('.ui-state-active').trigger('click');
}

I know this is not the best workaround, but it works. You can use it as an inspiration to make something better.

IMHO the most proper way is to update directly the component you want. So for example :

<h:form id="dataTableForm">
  <p:dataTable id="dataTableToUpdate">
    .
    .
    .
  </p:dataTable>
  <p:commandButton value="Refresh" update=":dataTableForm:dataTableToUpdate" />
</h:form>

It should work fine in this scenario (I suppose it is your purpose) : Open the .xhtml with your p:dataTable, sort some column (keep the facelet opened), update dataTables data from another .xhtml for example, click on refresh button. The dataTable should show your added value in correct (previously chosen) sort order - sorting was performed after update.

So the sort is maintained for you? Or is the sort button just highlighted but the actual sort is the sort order of the objects in memory? I tried updating the DT directly and that had no effect on the behaviour for me.

Sort button is highlighted and the sort is done correctly. Objects are sorted differently than in memory - depending on the actual sort order. I've tried it for the posted scenario and it is working completely fine for me. What scope do you use for the dataTable bean ?

I have edited the answer, let me know if it is working for you.

Well the lazy table option doesn't appear to work for me. If I update the table the sort is reset. I'll have to test the other option but I suppose it would work. What does removing the sortyby do?

sorting - p:datatable loses sort column and order after ajax refresh -...

ajax sorting jsf-2 primefaces datatable
Rectangle 27 5

I have always been thinking that creation of solution like that is like reinventing the bicycle. Here https://github.com/sasa7812/jfbdemo is my solution. It was tested on EclipseLink and Hibernate (EclipseLink in production, we used it in several projects for simple cases). Sometimes you just need a quick solution to make a dataTable with sorting and filtering, nothing fancy. It is able to filter and sort on joined fields, and even on collections. Project contains demo on Primefaces showing the abilities of FilterCriteriaBuilder. In the heart of it you just need this:

public List<T> loadFilterBuilder(int first, int pageSize, Map<String, Boolean> sorts, List<FieldFilter> argumentFilters, Class<? extends AbstractEntity> entityClass) {
    FilterCriteriaBuilder<T> fcb = new FilterCriteriaBuilder<>(getEntityManager(), (Class<T>) entityClass);
    fcb.addFilters(argumentFilters).addOrders(sorts);
    Query q = getEntityManager().createQuery(fcb.getQuery());
    q.setFirstResult(first);
    q.setMaxResults(pageSize);
    return q.getResultList();
}

to get the results from database.

I really need someone to tell me that it is usefull and is used somewhere to continue my work on this library.

java - Really dynamic JPA CriteriaBuilder - Stack Overflow

java jpa jpa-2.0 criteria-api
Rectangle 27 0

As it turns out, this bug was due to the data in the individual rows being mostly identical.

Solution: Set a rowKey attribute on the datatable, to the date field. Now it works fine with or without sorting.

primefaces - Bug when editing date field in DataTable component - Stac...

primefaces