为jQuery dataTables实现自定义sSortType和sort函数

我很难按照文档页面上的说明操作 。 我有一个表格,显示一列中的平均持续时间,采用HH:MM格式,例如10:45表示十小时四十五分钟。 我希望能够按照此列中的值对整个表进行排序。

这是我的初始化代码:

var aoTable = $("#TableStatistic").dataTable({ "bDestroy": true, "sDom": "<'row-fluid dt-header'>t<'row-fluid dt-footer'>", "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 : 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 : 0)); }); 

我想有一个更好的方法来提取分钟数而不是我的方式,但我们假设我的算法是有效的。 我该怎么做才能正确初始化我的dataTable并将这种排序函数和数据类型集成到其中? 表本身正确呈现,但是当我尝试对相关列进行排序时,它会按字典顺序排序,就像它是一个字符串一样。 有任何想法吗?

您应该同时提供-asc方法和-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示例。

为了扩展MasterAM在之前的答案中所说的内容,以下是我完全解决了我的问题的方法:

  • 首先 ,在处理自定义数据类型时,需要一种类型检测方法,如专用文档页面上的方法 。 该方法必须放在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; }); 

    我相应地命名了我的数据类型。

  • 其次 ,你需要实现升序和降序排序function,例如我在问题中输入的那个(现在编辑正确),它也应该放在init方法之前。

  • 最后 ,您必须告诉dataTable init方法以期望您希望的列内的数据类型。 这是在aoColumns数组中完成的。 就我而言,这意味着:

     { "mDataProp": "AverageTime", "sTitle": "Reports.AverageTime", 'sType': 'duration' } 

    一旦用户点击列的标题,就会附加ascdesc ,这就是我只在最后一行写入duration原因。