如何使用DataTables jQuery插件按日期排序?

51
我正在使用datatables jquery插件,并且想按日期排序。
我知道他们有一个插件,但我找不到从哪里实际下载它。

http://datatables.net/plug-ins/sorting

我相信我需要这个文件:dataTables.numericComma.js,但是我无法在任何地方找到它,而且当我下载datatables时,它似乎不在压缩文件中。
我也不确定是否需要自己制作自定义日期排序器来传递给这个插件。
我正在尝试对这个格式进行排序:MM/DD/YYYY HH:MM TT(AM |PM)。
谢谢。
编辑:
我如何将其更改为按照MM/DD/YYYY HH:MM TT(AM |PM)进行排序,并将其更改为美国日期?
jQuery.fn.dataTableExt.oSort['uk_date-asc']  = function(a,b) {
    var ukDatea = a.split('/');
    var ukDateb = b.split('/');

    var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
    var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1;

    return ((x < y) ? -1 : ((x > y) ?  1 : 0));
};

jQuery.fn.dataTableExt.oSort['uk_date-desc'] = function(a,b) {
    var ukDatea = a.split('/');
    var ukDateb = b.split('/');

    var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
    var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1;

    return ((x < y) ? 1 : ((x > y) ?  -1 : 0));
};

只是想感谢您提供的这段代码。我在处理英国日期排序时遇到了一些问题,而我找到的许多线程都有不起作用的代码,但是这个可以,所以再次感谢您! - 1DMF
1
我知道这是一个非常老的问题,答案也很老。在撰写本评论时,@RenRen提供的解决方案完美地运作,并且似乎是最干净的方法。 - maxx777
13个回答

136

带有隐藏元素的日期排序

将日期转换为格式YYYYMMDD并在实际值(MM/DD/YYYY)之前添加,将其包装在一个元素中,并将<td>的样式设置为display:none;。现在日期排序将像普通排序一样工作。同样的方法也可以应用于日期时间排序。

HTML

<table id="data-table">
   <tr>
     <td><span>YYYYMMDD</span>MM/DD/YYYY</td>
   </tr>
</table>

CSS

#data-table span {
    display:none; 
}

9
如果导出到 Excel,这些隐藏元素仍会显示。FYI。 - Waxi
1
@Anulal,在YYYY附近有一个额外的闭合标签。请在你的答案中修复代码。 - Lucky
3
有没有避免在打印、Excel、PDF等中生成YYYYMMDD的解决方法?请给出建议。 - Amit
1
@amit 请尝试使用媒体查询在打印时隐藏YYYYMMDD <link rel="stylesheet" type="text/css" media="print" href="print-hide.css"> - Anulal S
有没有人对@waxi的问题有解决方案?我也遇到了同样的问题。 - Shanmugapriyan
显示剩余3条评论

128

你应该使用HTML5数据属性。 https://www.datatables.net/examples/advanced_init/html5-data-attributes.html

只需在td元素中添加data-order元素即可。
无需插件。

<table class="table" id="exampleTable">
    <thead>
        <tr>
            <th>Firstname</th>
            <th>Sign Up Date</th>
        </tr>
    </thead>

    <tbody>

        <tr>
            <td>Peter</td>
            <td data-order="2015-11-13 12:00">13. November 2015</td>
        </tr>
        <tr>
            <td>Daniel</td>
            <td data-order="2015-08-06 13:44">06. August 2015</td>
        </tr>
        <tr>
            <td>Michael</td>
            <td data-order="2015-10-14 16:12">14. October 2015</td>
        </tr>
    </tbody>
</table>


<script>
    $(document).ready(function() {
        $('#exampleTable').DataTable();
    });
</script>

假设这个可行,我认为这是一个很好的解决方案。 - dsmith63

18

点击Date (dd/mm/YYY)下面的“显示详情”链接,然后您就可以复制粘贴提供的插件代码。


更新:我认为您只需交换数组的顺序即可,如下所示:

jQuery.fn.dataTableExt.oSort['us_date-asc']  = function(a,b) {
    var usDatea = a.split('/');
    var usDateb = b.split('/');

    var x = (usDatea[2] + usDatea[0] + usDatea[1]) * 1;
    var y = (usDateb[2] + usDateb[0] + usDateb[1]) * 1;

    return ((x < y) ? -1 : ((x > y) ?  1 : 0));
};

jQuery.fn.dataTableExt.oSort['us_date-desc'] = function(a,b) {
    var usDatea = a.split('/');
    var usDateb = b.split('/');

    var x = (usDatea[2] + usDatea[0] + usDatea[1]) * 1;
    var y = (usDateb[2] + usDateb[0] + usDateb[1]) * 1;

    return ((x < y) ? 1 : ((x > y) ?  -1 : 0));
};

我所做的只是交换了__date_[1](天)和__date_[0](月)的位置,并将uk替换为us,以便您不会感到困惑。我认为这应该可以解决您的问题。


更新 #2:您应该可以直接使用日期对象进行比较。请尝试以下方法:

jQuery.fn.dataTableExt.oSort['us_date-asc']  = function(a,b) {
 var x = new Date(a),
     y = new Date(b);
 return ((x < y) ? -1 : ((x > y) ?  1 : 0));
};

jQuery.fn.dataTableExt.oSort['us_date-desc'] = function(a,b) {
 var x = new Date(a),
     y = new Date(b);
 return ((x < y) ? 1 : ((x > y) ?  -1 : 0));
};

我会在几分钟内检查你的答案。我之前使用的是tablesorter,但因为需要使用搜索插件,所以我切换了。据我所知,在使用搜索插件时,动态添加行到tablesorter中非常困难。 - chobo2
那么我该如何将小时和分钟添加到这个方程式中呢? - chobo2
尝试我的新更新...我还没有测试过,但应该可以工作。 - Mottie

10

我知道这是一个两年前的问题,但我仍然觉得它很有用。最终我使用了Fudgey提供的示例代码,并进行了一些小的修改。帮我节省了一些时间,谢谢!

jQuery.fn.dataTableExt.oSort['us_date-asc']  = function(a,b) { 
  var x = new Date($(a).text()),
  y = new Date($(b).text());
  return ((x < y) ? -1 : ((x > y) ?  1 : 0)); 
}; 

jQuery.fn.dataTableExt.oSort['us_date-desc'] = function(a,b) { 
  var x = new Date($(a).text()),
  y = new Date($(b).text());
  return ((x < y) ? 1 : ((x > y) ?  -1 : 0)); 
}; 

5
截至2015年,我认为在DataTable中对日期列进行排序的最方便的方法是使用必需的排序插件。由于我的日期格式是dd/mm/yyyy hh:mm:ss,所以我最终使用了date-euro插件
只需要执行以下步骤: 步骤1:包含排序插件JavaScript文件或代码; 步骤2:像下面展示的添加columnDefs以定位适当的列。
$('#example').dataTable( {
    columnDefs: [
       { type: 'date-euro', targets: 0 }
    ]
});

2
请注意,此插件已被弃用datetime插件提供了增强的功能和灵活性。 - Thiago C. S Ventura

5

仅适用于预加载的HTML表格,如果您使用Ajax,则不是答案

Datatables只能按照“ ISO-8601”格式中的日期时间排序,因此您需要将“日期顺序”中的日期转换为此格式(以下是使用Razor的示例):

<td data-sort="@myDate.ToString("o")">@myDate.ToShortDateString() - @myDate.ToShortTimeString()</td>

3

如果您在日期值或单元格中有空白空间的情况下遇到问题,您需要处理这些部分。有时,来自html的trim函数不能处理空格,就像"$nbsp;"一样。如果您不处理这些内容,您的排序将无法正常工作,并且会在任何空格处中断。

我从这里的jquery扩展中获取了这段代码,并稍微更改以适应我的要求。您也应该这样做:)干杯!

function trim(str) {
    str = str.replace(/^\s+/, '');
    for (var i = str.length - 1; i >= 0; i--) {
        if (/\S/.test(str.charAt(i))) {
            str = str.substring(0, i + 1);
            break;
        }
    }
    return str;
}

jQuery.fn.dataTableExt.oSort['uk-date-time-asc'] = function(a, b) {
    if (trim(a) != '' && a!="&nbsp;") {
        if (a.indexOf(' ') == -1) {
            var frDatea = trim(a).split(' ');
            var frDatea2 = frDatea[0].split('/');
            var x = (frDatea2[2] + frDatea2[1] + frDatea2[0]) * 1;
        }
        else {
            var frDatea = trim(a).split(' ');
            var frTimea = frDatea[1].split(':');
            var frDatea2 = frDatea[0].split('/');
            var x = (frDatea2[2] + frDatea2[1] + frDatea2[0] + frTimea[0] + frTimea[1] + frTimea[2]) * 1;
        }
    } else {
        var x = 10000000; // = l'an 1000 ...
    }

    if (trim(b) != '' && b!="&nbsp;") {
        if (b.indexOf(' ') == -1) {
            var frDateb = trim(b).split(' ');
            frDateb = frDateb[0].split('/');
            var y = (frDateb[2] + frDateb[1] + frDateb[0]) * 1;
        }
        else {
            var frDateb = trim(b).split(' ');
            var frTimeb = frDateb[1].split(':');
            frDateb = frDateb[0].split('/');
            var y = (frDateb[2] + frDateb[1] + frDateb[0] + frTimeb[0] + frTimeb[1] + frTimeb[2]) * 1;
        }
    } else {
        var y = 10000000;
    }
    var z = ((x < y) ? -1 : ((x > y) ? 1 : 0));
    return z;
};

jQuery.fn.dataTableExt.oSort['uk-date-time-desc'] = function(a, b) {
    if (trim(a) != '' && a!="&nbsp;") {
        if (a.indexOf(' ') == -1) {
            var frDatea = trim(a).split(' ');
            var frDatea2 = frDatea[0].split('/');
            var x = (frDatea2[2] + frDatea2[1] + frDatea2[0]) * 1;
        }
        else {
            var frDatea = trim(a).split(' ');
            var frTimea = frDatea[1].split(':');
            var frDatea2 = frDatea[0].split('/');
            var x = (frDatea2[2] + frDatea2[1] + frDatea2[0] + frTimea[0] + frTimea[1] + frTimea[2]) * 1;
        }
    } else {
        var x = 10000000;
    }

    if (trim(b) != '' && b!="&nbsp;") {
        if (b.indexOf(' ') == -1) {
            var frDateb = trim(b).split(' ');
            frDateb = frDateb[0].split('/');
            var y = (frDateb[2] + frDateb[1] + frDateb[0]) * 1;
        }
        else {
            var frDateb = trim(b).split(' ');
            var frTimeb = frDateb[1].split(':');
            frDateb = frDateb[0].split('/');
            var y = (frDateb[2] + frDateb[1] + frDateb[0] + frTimeb[0] + frTimeb[1] + frTimeb[2]) * 1;
        }
    } else {
        var y = 10000000;
    }

    var z = ((x < y) ? 1 : ((x > y) ? -1 : 0));
    return z;
};

2
关于更新#1,存在2个问题:
  • 日期格式为1天(d/MM/YYYY),而不是2天(dd/MM/YYYY)
  • 日期为空
以下是避免这些问题的解决方案:
jQuery.fn.dataTableExt.oSort['uk_date-asc'] = function (a, b) {
            var ukDatea = a.split('/');
            var ukDateb = b.split('/');

            //Date empty
             if (ukDatea[0] == "" || ukDateb[0] == "") return 1;

            //need to change Date (d/MM/YYYY) into Date (dd/MM/YYYY) 
            if(ukDatea[0]<10) ukDatea[0] = "0" + ukDatea[0]; 
            if(ukDateb[0]<10) ukDateb[0] = "0" + ukDateb[0];

            var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
            var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1;

            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        };

        //Sorting by Date 
        jQuery.fn.dataTableExt.oSort['uk_date-desc'] = function (a, b) {
            var ukDatea = a.split('/');
            var ukDateb = b.split('/');

             //Date empty
             if (ukDatea[0] == "" || ukDateb[0] == "") return 1;

            //MANDATORY to change Date (d/MM/YYYY) into Date (dd/MM/YYYY) 
            if(ukDatea[0]<10) ukDatea[0] = "0" + ukDatea[0]; 
            if(ukDateb[0]<10) ukDateb[0] = "0" + ukDateb[0];

            var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
            var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1;

            return ((x < y) ? 1 : ((x > y) ? -1 : 0));
        };

2

将列的type指定为type: 'date'

{title: '过期日期', data: 'ExpirationDate', type: 'date'}


2

请点击链接https://datatables.net/blog/2014-12-18

一种非常简单的整合按日期排序的方法。

<script type="text/javascript" charset="utf8" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/plug-ins/1.10.19/sorting/datetime-moment.js"></script>

将此代码放在初始化数据表之前:
$(document).ready(function () {
    // ......
    $.fn.dataTable.moment('DD-MMM-YY HH:mm:ss');
    $.fn.dataTable.moment('DD.MM.YYYY HH:mm:ss');
    // And any format you need
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接