Add Sort Index Indicators to Primefaces Multi-Sort DataTables

The primefaces DataTable is a powerful component and probably the most widely used component in our enterprise application development.

One of the features is the multi-sort capability. As expected, it enables sorting on multiple columns using a meta-key to add additional sort selections. The only downside is there are no visual indicators reflecting back the sort index for a given column.

While perhaps not the most elegant solution, what follows is a Javascript solution to the problem.

The JavaScript

This JavaScript function just needs to be included with your page. The parameter is the widgetVar you assign to your DataTable.

function updateSortIndexes(widgetVar) {
    $('.sort-idx').remove();
    var sortMeta = PF(widgetVar).sortMeta;
    if (sortMeta.length < 2)
        return;
    $(PF(widgetVar).sortableColumns).each(function(index) {
        var id=$(this).attr("id");
        for (var i = 0; i < sortMeta.length; i++) {
            if (sortMeta[i].col == id) {
              $(this).prepend("<span class='sort-idx'>" + (i + 1) + "</span>")
            }
        }
    });
}

The XHTML

The DataTable in your XHTML needs to assign a widgetVar and you’ll need to add a p:ajax sort event handler that executes our JavaScript on completion:

  <p:dataTable widgetVar="widCars"
    sortMode="multiple"
       ... >
     <p:ajax event="sort" oncomplete="updateSortIndexes('widCars');" />
      ...
  </p:dataTable>

The CSS

Finally, let’s style the sort index badges:

.sort-idx {
    font-size: 0.7em;
    padding: 2px 6px;
    border-radius: 8px;
    background: #DDD;
    color: #555;
    margin-right: 4px;
    position: relative;
    top: -2px;
}

Of course, that looks good with our template, but you may need to adjust for yours.
Enjoy!

4 comments
  1. Thanks for the great working example. We are currently using a slightly modified form to allow this functionality to be enabled when multiple datatables are on the same page:

    function updateSortIndexes(widgetVar) {
    $(‘.sort-idx.’ + widgetVar).remove();
    var sortMeta = PF(widgetVar).sortMeta;
    if (sortMeta.length < 2)
    return;
    $(PF(widgetVar).sortableColumns).each(function(index) {
    var id=$(this).attr("id");
    for (var i = 0; i < sortMeta.length; i++) {
    if (sortMeta[i].col == id) {
    $(this).prepend("” + (i + 1) + “”)
    }
    }
    });
    }

  2. Last comment was filtered it looks like, missing relevant modification to class applied to the span:
    class=’sort-idx ” + widgetVar + “‘

  3. Jesse,

    Thanks for the comments and I apologize for the slow approval. I have fix the issue on my end and hopefully won’t miss comments again 😉

    Thanks for the contribution too.

  4. Here’s a slightly modified version. I reduced duplicated code (PF widgetVar lookups and $(this) calls). I also changed the first part to only remove “.sort-idx” elements inside this widget instead of the entire page, in case there are multiple tables on the page.

    function updateSortIndexes(widgetVar) {
    var widget = PF(widgetVar);
    widget.jq.find(‘.sort-idx’).remove();
    var sortMeta = widget.sortMeta;
    if (sortMeta.length < 2)
    return;
    $(widget.sortableColumns).each(function(index) {
    var _this = $(this);
    var id = _this.attr("id");
    for (var i = 0; i < sortMeta.length; i++) {
    if (sortMeta[i].col == id) {
    _this.prepend("” + (i + 1) + “”);
    }
    }
    });
    }

Comments are closed.