sortingjsfprimefacesprimefaces-datatable

Primefaces 10+ Datatable how to get sorted column from SortEvent?


We are currently using Primefaces version 8 and I am working on migrating us to version 12.

In the migration guide 8.0 -> 10.0.0, under DataTable, Breaking changes says this:

SortEvent: sorted datatable value is no longer passed to this event, instead get the sorted value through your managed bean (e.g YourBean#list used as value expression)

For the life of me I cannot figure out how to pass the column being sorted as a value expression.

Here is what we currently have working using Primefaces 8 (simplified):

<p:dataTable id="searchResultsTable" 
    value="#{nameBackingBean.queryResults}"
    var="searchResultsRow" widgetVar="tableWidget"
    sortBy="#{searchResultsRow.name}" sortOrder="ascending">
    
    <p:ajax event="sort" listener="#{nameBackingBean.sortedColumnSelected}" />
    
    <!-- Name -->
    <p:column headerText="Name"
        sortBy="#{searchResultsRow.name}">
        <h:outputText id="nameValue"
            value="#{searchResultsRow.name}" />
    </p:column>
    
    <!-- Age -->
    <p:column headerText="Age"
        sortBy="#{searchResultsRow.age}">
        <h:outputText id="ageValue"
            value="#{searchResultsRow.age}" />
    </p:column>
    
    ...

And here is the java backing bean method that is called when a sort is performed:

  public void sortedColumnSelected(AjaxBehaviorEvent event){
      if (null != event.getSource()){
         DataTable table = (DataTable) event.getSource();
         if(table != null && table.getSortColumn() != null){
            String headerText = table.getSortColumn().getHeaderText();
            String sortOrder = table.getSortOrder();
            
            if(headerText.equals("Name")){
               //we do something
            }else if (headerText.equals("Age")){
               //we do something else
            ...

The getSortColumn method is no longer available after Primefaces 8, so I am assuming I have to use some EL expression to figure out which column was sorted (based off of the sentence e.g. YourBean#list used as a value expression) and pass the value in like this...

<p:ajax event="sort" listener="#{nameBackingBean.sortedColumnSelected(el expression telling me what column was sorted)}" />

If anyone knows how to format the value expression to tell me which column was sorted, I would really appreciate it!


Solution

  • Of course after I post this, I think I figured it out.

    It looks like there is a method in DataTable called getActiveSortMeta which appears to hold the columns that are being sorted. The key in the map is the field being sorted. My DataTable only allows the sorting of one column at a time, so the map only contains one entry.

    Here is my example code:

    public void sortedColumnSelected(AjaxBehaviorEvent event) {
      if (null != event.getSource()) {
         DataTable table = (DataTable) event.getSource();
         
         /* This map should contain the column that is being sorted. Since only
          * one column can be sorted at a time, there should only be one. */
         Map <String, SortMeta> sortMap = table.getActiveSortMeta();
    
         if (MapUtils.isNotEmpty(sortMap)) {
         
            String fieldName = sortMap.keySet().iterator().next();
    
            SortMeta meta = sortMap.get(fieldName);
            String sortOrder = meta.getOrder().name();
    
            /* set the sort order so the report can display correctly. */
            setSortAscending(sortOrder.equals("ASCENDING"));
    
            if (fieldName.equals("name")) {
              //do something
            } else if (fieldName.equals("age")) {
              //do something else
            }
    

    Hope this helps someone else. If you know of a different way of doing this, I'd love to hear about it.

    Thanks all!