为 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】:

您应该同时提供&lt;type&gt;-asc 方法和&lt;type&gt;-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' 

一旦用户点击列的标题,ascdesc 将被附加,这就是为什么我只在最后一行写了duration

【讨论】:

在您的情况下,使用正则表达式来检测所需的模式可能会更快、更容易。您还可以让服务器发送一个数值(分钟数)并使用mRender 将其解析为显示字符串。

以上是关于为 jQuery 数据表实现自定义 sSortType 和排序函数的主要内容,如果未能解决你的问题,请参考以下文章

JQuery Validate插件如何自定义验证方法(结合ajax实现数据库的查重)

jquery 表格控件怎么使用

jquery表单验证 自定义函数使用

怎样更改jquery mobile的样式

如何使用jquery数据表自定义按钮导出水晶报告pdf

不为空的自定义数据属性上的 jQuery 选择器