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

时间:2013-12-24 11:06:21

标签: jquery sorting datatables

我很难按照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

});

以下是 I ASSUME 是将新的排序函数和新的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并将这种排序函数和数据类型集成到其中?表本身正确呈现,但是当我尝试对相关列进行排序时,它会按字典顺序排序,就像它是一个字符串一样。 有什么想法吗?

2 个答案:

答案 0 :(得分:21)

您应该提供<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示例。

答案 1 :(得分: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