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>")
}
}
});
}
$('.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>
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;
}
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!
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) + “”)
}
}
});
}
Last comment was filtered it looks like, missing relevant modification to class applied to the span:
class=’sort-idx ” + widgetVar + “‘
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.
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) + “”);
}
}
});
}