In our grid of user data, we have a field for each user that includes their age calculated as a string, such as 77 years, or 6 months, or 5 days. We need a way to be able to sort the grid by that column and have the ages sort numerically where a group such as 30 years, 50 years, 5 days, 10 years, 4 months would sort as 50 years, 30 years, 10 years, 4 months, 5 days. I have tried several sorting functions that sort alphanumerically but haven't been able to figure out how to force months to be less than years, and days to be less than months.
This is the current sorting function that I am trying to use that I found on stack overflow.
var a, b, a1, b1, rx=/(\d )|(\D )/g, rd=/\d /;
function AlphaNumericCaseInsensitive(as, bs) {
a= String(as).toLowerCase().match(rx);
b= String(bs).toLowerCase().match(rx);
while(a.length && b.length){
a1= a.shift();
b1= b.shift();
if(rd.test(a1) || rd.test(b1)){
if(!rd.test(a1)) return 1;
if(!rd.test(b1)) return -1;
if(a1!= b1) return a1-b1;
}
else if(a1!= b1) return a1> b1? 1: -1;
}
return a.length- b.length;
}
var dataSource = new kendo.data.DataSource({
data: [
{ id: 1, age: "101 y" },
{ id: 2, age: "2 m" },
{ id: 3, age: "11 y" },
{ id: 4, age: "1 y" },
{ id: 5, age: "2 y" },
{ id: 6, age: "4 d" },
]
});
$("#grid").kendoGrid({
dataSource: dataSource,
sortable: true,
columns: [{
field: "age",
sortable: {
compare: function(a, b) {
return AlphaNumericCaseInsensitive(a.item, b.item);
}
}
}]
});
CodePudding user response:
If you have a property in your data which you can be cast to Date
type, you can use it in the compare
method:
var dataSource = new kendo.data.DataSource({
data: [
{ id: 1, age: "101 y", dob: "1922-05-18" },
{ id: 2, age: "2 m", dob: "2022-03-18" },
{ id: 3, age: "11 y", dob: "2011-05-18" },
{ id: 4, age: "1 y", dob: "2021-05-18" },
{ id: 5, age: "2 y", dob: "2020-05-18" },
{ id: 6, age: "4 d", dob: "2022-05-14" },
]
});
$("#grid").kendoGrid({
dataSource: dataSource,
sortable: true,
columns: [{
field: "age",
sortable: {
compare: function(a, b) {
const dateA = Date.parse(a.dob),
dateB = Date.parse(b.dob);
if (dateA < dateB) return -1;
else if (dateA > dateB) return 1;
else return 0;
}
}
}]
});
Working demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2022.2.510/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2022.2.510/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2022.2.510/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2022.2.510/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2022.2.510/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2022.2.510/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2022.2.510/js/kendo.all.min.js"></script></head>
<body>
<div id="grid"></div>
<script>
var dataSource = new kendo.data.DataSource({
data: [
{ id: 1, age: "101 y", dob: "1922-05-18" },
{ id: 2, age: "2 m", dob: "2022-03-18" },
{ id: 3, age: "11 y", dob: "2011-05-18" },
{ id: 4, age: "1 y", dob: "2021-05-18" },
{ id: 5, age: "2 y", dob: "2020-05-18" },
{ id: 6, age: "4 d", dob: "2022-05-14" },
]
});
$("#grid").kendoGrid({
dataSource: dataSource,
sortable: true,
columns: [{
field: "age",
sortable: {
compare: function(a, b) {
const dateA = Date.parse(a.dob),
dateB = Date.parse(b.dob);
if (dateA < dateB) return -1;
else if (dateA > dateB) return 1;
else return 0;
}
}
}]
});
</script>
</body>
</html>