为 jQuery 数据表实现自定义 sSortType 和排序函数
Posted
技术标签:
【中文标题】为 jQuery 数据表实现自定义 sSortType 和排序函数【英文标题】:Implementing a custom sSortType and sort function for jQuery dataTables 【发布时间】:2014-01-12 15:10:59 【问题描述】:我很难按照documentation 页面上的说明进行操作。我有一个表格,在一列中显示平均持续时间,采用 HH:MM 格式,例如 10:45 表示十小时四十五分钟。我希望能够按此列中的值对整个表格进行排序。
这是我的初始化代码:
var aoTable = $("#TableStatistic").dataTable(
"bDestroy": true,
"sDom": "<'row-fluid dt-header'<'span6'f><'span6'T>>t<'row-fluid dt-footer'<'span6'i><'span6'p>>",
"oTableTools":
"aButtons": ["xls", "pdf", "print"],
"sSwfPath": "../Content/media/swf/copy_csv_xls_pdf.swf"
,
"aaData": statisticsModel.byCategoriesList(),
"aaSorting": [[0, "desc"]],
"bPaginate": false,
"aoColumns": [
"mDataProp": "CategoryName", "sTitle": "Reports.CategoryName" ,
"mDataProp": "AverageTime", "sTitle": "Reports.AverageTime", "sSortDataType": "duration-desc",
"mDataProp": "NumberOfProblemsSolved", "sTitle": "Reports.NumberOfProblemsSolved"
],
"oLanguage": MeridianTranslation.DataTable
);
以下是我认为在我的表中添加新排序函数和新 sSortType 的正确方法:
jQuery.extend(jQuery.fn.dataTableExt.oSort['duration-desc'] = function (x, y)
var xHours = parseInt(x.slice(0, x.indexOf(':')));
var xMinutes = parseInt(x.slice(x.indexOf(':') + 1, x.length)) + xHours * 60;
var yHours = parseInt(y.slice(0, y.indexOf(':')));
var yMinutes = parseInt(y.slice(y.indexOf(':') + 1, y.length)) + yHours * 60;
return ((xMinutes < yMinutes) ? -1 : ((xMinutes > yMinutes) ? 1 : 0));
);
jQuery.extend(jQuery.fn.dataTableExt.oSort['duration-asc'] = function (x, y)
var xHours = parseInt(x.slice(0, x.indexOf(':')));
var xMinutes = parseInt(x.slice(x.indexOf(':')+1, x.length)) + xHours * 60;
var yHours = parseInt(y.slice(0, y.indexOf(':')));
var yMinutes = parseInt(y.slice(y.indexOf(':')+1, y.length)) + yHours * 60;
return ((xMinutes < yMinutes) ? 1 : ((xMinutes > yMinutes) ? -1 : 0));
);
我想有一种比我做的方法更好的方法来提取分钟数,但是让我们假设我的算法是有效的。我必须怎么做才能正确初始化我的 dataTable 并将这种排序功能和数据类型集成到其中?表本身可以正确呈现,但是当我尝试对有问题的列进行排序时,它会按字典顺序对自身进行排序,就好像它是一个字符串一样。 有什么想法吗?
【问题讨论】:
【参考方案1】:您应该同时提供<type>-asc
方法和<type>-desc
方法。
然后根据列的sType
属性进行排序:
jQuery.fn.dataTableExt.oSort["duration-desc"] = function (x, y)
...
;
jQuery.fn.dataTableExt.oSort["duration-asc"] = function (x, y)
...
var oTable = $("#products").dataTable(
"aaData": [
[1, "Dinner", "0:40"],
[2, "Study", "11:25"],
[3, "Sleep", "7:30"]
],
"aoColumns": [
...
,
...
,
...
"bSortable": true,
"sType": "duration"
]
);
这是一个简单的jsFiddle 示例。
【讨论】:
在看到您的答案之前,我设法解决了这个问题,但是最好有它以供将来参考,尽管如此。谢谢。 它们是您的数据集中需要比较的相应键的 2 个元素。在 OP 的情况下,这些是来自AverageTime
列的 2 个“持续时间”字符串。它应该从Array.prototype.sort 返回一个遵循compareFunction
标准的值,因为这是基于比较的排序。【参考方案2】:
为了扩展 MasterAM 在之前的回答中所说的内容,以下是我完全解决问题的方法:
首先,在处理自定义数据类型时,需要一种类型检测方法,例如在专用文档page 中找到的方法。该方法必须放在 dataTable init 方法之前。这是我的方法的样子,记住我需要分析的 HH:MM 格式:
jQuery.fn.dataTableExt.aTypes.push(function (sData)
var sValidChars = "0123456789:";
var Char;
for (i = 1 ; i < sData.length ; i++)
Char = sData.charAt(i);
if (sValidChars.indexOf(Char) == -1)
return null;
if (sData.charAt(1) == ':' || sData.charAt(2) == ':')
return 'duration';
return null;
);
我相应地将我的数据类型命名为duration
。
其次,你需要实现升序和降序排序功能,例如我在问题中输入的(现在已正确编辑),它也应该放在init方法之前。
最后,您必须告诉 dataTable init 方法期望列内的数据类型。这是在aoColumns
数组中完成的。就我而言,这意味着:
"mDataProp": "AverageTime", "sTitle": "Reports.AverageTime", 'sType': 'duration'
一旦用户点击列的标题,asc
和desc
将被附加,这就是为什么我只在最后一行写了duration
。
【讨论】:
在您的情况下,使用正则表达式来检测所需的模式可能会更快、更容易。您还可以让服务器发送一个数值(分钟数)并使用mRender
将其解析为显示字符串。以上是关于为 jQuery 数据表实现自定义 sSortType 和排序函数的主要内容,如果未能解决你的问题,请参考以下文章