Reputation: 1415
I am trying to sort on a column called Priority. There are 5 possible values for this column: High, Medium, Low, Unprioritized, and N/A. I'd like to be able to sort them in that order (as ascending) or the reverse (as descending). My approach was to create a custom sorting function based on what I found here. This is what I did:
option["columnDefs"] = [
{
"render":function(data,type,row) {
var $select;
switch(data) {
case: "High":
$select = $('<div class="my-class-high" priority="high">High</div');
break;
case: "Medium":
$select = $('<div class="my-class-medium" priority="medium">Medium</div');
break;
// etc. for other values.
}
return $select.prop("outerHTML");
},
"targets" : 7,
"sType" : "priority"
}
];
function getRank(cellHtml) {
switch ($(cellHtml).attr("priority")) {
case "high":
return 0;
case "medium":
return 1;
case "low":
return 2;
case "unprioritized":
return 3;
case "notapplicable":
return 4;
default:
throw "Unrecognized priority.";
}
}
jQuery.fn.dataTableExt.oSort["priority-desc"] = function (x, y) {
return getRank(x) < getRank(y);
};
jQuery.fn.dataTableExt.oSort["priority-asc"] = function (x, y) {
return getRank(x) > getRank(y);
};
//further down...
$(#mytable).DataTable(option);
All of the code, including the sort function, is being hit as expected. When I click on the Priority column, the glyph flips. My problem is that the sort order as displayed never changes: It remains at ascending, which is correctly displayed with High priorities at the top of the table.
I created a temporary event handler function to check on things:
$(tableLookup).on('order.dt',function() {
var order = table.order();
});
With this I can verify further that the sort order is changing (internally, at least) each time I click the column header, even though the displayed order isn't updating.
I'm running jquery.dataTables.js version 1.10.4.
I've also tried to use the data-sort attribute, as suggested in Anjani's answer, here. This has no effect on the sort order at all--the table still sorts the column alphabetically using the displayed text.
Any ideas what could be causing these issues I'm seeing and how to get sort working?
Upvotes: 0
Views: 2700
Reputation: 680
The answer saved my day: https://stackoverflow.com/a/25319252/1554947
var table = $('#table');
table = table.DataTable({
columns: [
{ data: "link" },
{ data: "code" },
{ data: "entryDateTime" }
],
columnDefs: [
{
targets: 2,
render: function (data, type) {
if (type == "display") {
var date = new Date(data);
var options = { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric" };
return date.toLocaleDateString('tr-TR', options);
}
return data;
}
}
],
order: [[2, "desc"]] // default order when page loaded
});
Upvotes: 0
Reputation: 3028
You can do this with the render function. The 2nd argument of the render function is what version of the data that DataTables is asking for. When it is sort
then it is asking for the value that should be used for sorting. With this you don't need the custom sorting method.
var example = $('#example').DataTable({
columns: [
null,
null,
{
render: function(data,type,row) {
if(type == 'sort'){
return getRank(data.toLowerCase());
}
switch(data) {
case "N/A":
return '<div class="my-class-notapplicable">' + data + '</div>';
default:
return '<div class="my-class-' + data.toLowerCase() + '">' + data + '</div>';
}
}
}
]
});
function getRank(data) {
switch (data) {
case "high":
return 0;
case "medium":
return 1;
case "low":
return 2;
case "unprioritized":
return 3;
case "n/a":
return 4;
default:
throw "Unrecognized priority.";
}
}
https://datatables.net/reference/option/columns.render
Upvotes: 0
Reputation: 5699
This seems to work:
var example = $('#example').DataTable({
columns: [
null,
null,
{
sType : "priority",
render: function(data,type,row) {
var retVal = $("<div/>");
switch(data) {
case "High":
retVal = retVal
.addClass("my-class-"+data.toLowerCase())
.attr("data-priority", data.toLowerCase())
.text(data);
break;
case "Medium":
retVal = retVal
.addClass("my-class-"+data.toLowerCase())
.attr("data-priority", data.toLowerCase())
.text(data)
break;
case "Low":
retVal = retVal
.addClass("my-class-"+data.toLowerCase())
.attr("data-priority", data.toLowerCase())
.text(data)
break;
case "Unprioritized":
retVal = retVal
.addClass("my-class-"+data.toLowerCase())
.attr("data-priority", data.toLowerCase())
.text(data)
break;
case "N/A":
retVal = retVal
.addClass("my-class-notapplicable")
.attr("data-priority", "notapplicable")
.text(data)
break;
}
return retVal.prop("outerHTML");
}
}
]
});
function getRank(data) {
switch (data) {
case "high":
return 0;
case "medium":
return 1;
case "low":
return 2;
case "unprioritized":
return 3;
case "notapplicable":
return 4;
default:
throw "Unrecognized priority.";
}
}
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
"priority-pre": function ( a ) {
return getRank($(a).data("priority"));
},
"priority-asc": function( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"priority-desc": function(a,b) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
});
Your render case function was borked so I'm not sure if you were actually calling your order function, always a good idea to check what the console says.
I dare say the order function could be tidied and I'm not sure why I dislike switch statements as much as I do but I really, really do. YMMV though. Hope that helps, working JSFiddle here.
Upvotes: 1