我正在使用一个名为datatables的Jquery插件
太棒了,但是我无法根据 dd/mm/yyyy 格式正确排序日期。
我已经查看了它们的支持格式,但这些修复程序似乎都不起作用。
这里有人可以帮我吗?
2020 年更新:HTML 解决方案
由于HTML 5非常发达,几乎所有主要的浏览器都支持它。所以现在一个更干净的方法是使用HTML5数据属性(maxx777提供了一个PHP解决方案,我正在使用简单的HTML)。对于非数字数据,如我们的场景,我们可以使用data-sort
或data-order
属性并为其分配可排序的值。
.HTML
<td data-sort='YYYYMMDD'>DD/MM/YYYY</td>
这是有效的HTML解决方案
j查询解决方案
这是有效的jQuery解决方案。
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"date-uk-pre": function ( a ) {
var ukDatea = a.split('/');
return (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
},
"date-uk-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"date-uk-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
} );
将上面的代码添加到脚本中,并使用带有 { "sType": "date-uk" }
的日期值设置特定列,并将其他列为 null,如下所示:
$(document).ready(function() {
$('#example').dataTable( {
"aoColumns": [
null,
null,
null,
null,
{ "sType": "date-uk" },
null
]
});
});
日期排序 - 带有隐藏元素
将日期转换为 YYYYMMDD 格式,并在<td>
中预置实际值 (DD/MM/YYYY),将其包装在一个元素中,为元素设置样式display:none;
。现在,日期排序将作为正常排序工作。这同样适用于日期时间排序。
.HTML
<table id="data-table">
<tr>
<td><span>YYYYMMDD</span>DD/MM/YYYY</td>
</tr>
</table>
.CSS
#data-table span {
display:none;
}
这是一个古老的问题,答案也很旧。最近,我遇到了一种简单而干净的日期排序方法。它可以通过HTML5 data-order
属性<td>
元素来完成。
这是我在PHP中所做的:
<?php
$newdate = date('d M Y', $myDateTime); // Format in which I want to display
$dateOrder = date('Y-m-d', $myDateTime); // Sort Order
?>
<td data-order="<?php echo $dateOrder; ?>" >
<?php echo $newdate; ?>
</td>
试试这个插件。
如此处所述,您需要包含 Moment.js 和 datatable-moment 插件,然后只需声明您正在使用的日期格式即可。该插件将自动检测您的日期列并按应有的方式对其进行排序。有关目前.js格式说明,请查看此处。
例:
$(document).ready(function() {
$.fn.dataTable.moment('DD/MM/YYYY HH:mm');
$('#example').DataTable();
});
这样它对我有用。
<td data-order="@item.CreatedOn.ToString("MMddyyyyHHmmss")">
@item.CreatedOn.ToString("dd-MM-yyyy hh:mm tt")
</td>
data-order
属性中的此日期格式应采用数据表支持的此格式。
如果不想使用 momentum.js 或任何其他日期格式,则可以在日期值中预置以毫秒为单位的日期格式,以便排序将根据其毫秒进行读取。并隐藏毫秒日期格式。
示例代码:
var date = new Date();
var millisecond = Date.parse(date);
.HTML
<td>'<span style="display: none;">' + millisecond + "</span>" + date + </td>
就是这样。
您可以使用 php 解决此问题。
$mydate = strtotime($startdate);
$newformat = date('d-m-Y',$mydate);
echo '<tr>';
echo ' <td data-sort="'. $mydate .'">'.$newformat .'</td>';
另一种解决方案:https://datatables.net/blog/2014-12-18
有 2 个 JavaScript 库:
- cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js
- cdn.datatables.net/plug-ins/1.10.15/sorting/datetime-moment.js
那么只有这个:
$(document).ready(function() {
$.fn.dataTable.moment( 'DD/MM/YYYY' );
$('#example').DataTable();
});
虽然这个问题有很多答案,但我认为数据排序仅在"YYYYMMDD"中需要排序时才有效,并且在有小时/分钟时不起作用。使用数据排序时过滤器无法正常工作,至少我在尝试使用 React JS 时遇到了这个问题。
在我看来,最好的解决方案是使用数据排序,因为可以动态提供值以进行排序,并且在显示时格式可以不同。该解决方案功能强大,适用于任何日期格式,包括"DD/MM/YYYY HH:M"。
例如:
<td data-order={obj.plainDateTime}>{this.formattedDisplayDate(obj.plainDateTime) }</td>
我从这里找到了这个解决方案 - 如何按数据表中的隐藏列排序?
我试过这个并为我工作。
https://github.com/sedovsek/DataTables-EU-date-Plug-In
我使用了格式模式.ToString("dd/MM/yyyy");
然后在我的jQuery.Datatable中工作正常。
jQ 下面
oTable = $('#grid').dataTable({
"sPaginationType": "full_numbers",
"aoColumns": [
{ "sType": "eu_date" },
null
]
});
});
你有日期的列,你应该像上面的代码一样用sType定义。
在 PHP 或 js 中只需传递一个数组并使用正交,例如:
$var[0][0] = "like as u wish, 30/12/2015 or something else";
$var[0][1] = strtotime($your_date_variable);
并且,在数据表中...
$('#data-table-contas_pagar').dataTable({
"columnDefs": [
{"targets":[0],"data": [0],"render": {"_": [0],"sort": [1]}}
]
});
Zaheer Ahmed' 解决方案工作正常,如果您必须处理已经英国格式化的日期。
我对此解决方案有问题,因为我必须管理美国格式的日期。
我通过这个微小的变化想通了:
function parseDate(a) {
var ukDatea = a.split('/');
return (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
}
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"date-uk-pre": function ( a ) {
return parseDate(a);
},
"date-uk-asc": function ( a, b ) {
a = parseDate(a);
b = parseDate(b);
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"date-uk-desc": function ( a, b ) {
a = parseDate(a);
b = parseDate(b);
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
});
然后是您的"aoColumns"定义。
这个解决方案是完全错误的。不能仅将日期的每个组成部分相加即可将日期转换为数字。例如,如果您尝试使用此逻辑,例如使用以下日期,您会发现它无法正确匹配:
2014/01/20 = 203515/02/2014 = 2031
女巫日期在先,升序? 1月20日?不按照这个逻辑:P
执行 parsedate 方法的正确方法是将字符串转换为有效的日期时间,它们使用 getTime 函数对表进行正确排序。
var day = a.split('/')[0]
var month = a.split('/')[1]
var year = a.split('/')[2]
var date = new Date(month + "/" + day + "/" + year)
return date.getTime()
我想指出的是,当通过 Ajax 使用来自服务器的数据时,解决方案非常简单,但可能不会立即显而易见。
当返回排序顺序数组时,数据表将发送(在$_POST
中)一个 2 元素数组,该数组等效于:
$_POST['order'][0] =array('column'=>'SortColumnName', 'dir'=>'asc');
// 2nd element is either 'asc' or 'desc'
因此,您可以以所需的任何格式显示日期;只需让您的服务器仅根据sortColumnName
返回排序标准即可。
例如,在PHP(使用MySQL)中,我使用以下内容:
if (isset($_POST['order'])) {
switch ($_POST['order'][0]['column']) {
case 0:// sort by Primary Key
$order = 'pkItemid';
break;
case 1:// Sort by reference number
$order = 'refNo';
break;
case 2://Date Started
$order = 'dOpen';
break;
default :
$order = 'pkItemid';
}
$orderdir = ($_POST['order'][0]['dir'] === 'desc') ? 'desc' : 'asc';
}
请注意,由于$_POST
中的任何内容都不会传递给$order
或$orderdir
,因此不可能进行跨脚本攻击。
现在,只需附加到 MySQL 查询:
$sql ="SELECT pkItemid, refNo, DATE_FORMAT(dOpen,'%b %e, %Y') AS dateStarted
FROM tblReference
ORDER BY $order $orderdir;";
运行查询,并仅将 JSON 中的 dateStarted
值返回到数据表。
使用此片段!
$(document).ready(function() {
$.fn.dataTable.moment = function ( format, locale ) {
var types = $.fn.dataTable.ext.type;
// Add type detection
types.detect.unshift( function ( d ) {
return moment( d, format, locale, true ).isValid() ?
'moment-'+format :
null;
} );
// Add sorting method - use an integer for the sorting
types.order[ 'moment-'+format+'-pre' ] = function ( d ) {
return moment( d, format, locale, true ).unix();
};
};
$.fn.dataTable.moment('DD/MM/YYYY');
$('#example').DataTable();
});
MOMENT JS适用于所有日期和时间格式,请在初始化数据表之前添加此狙击手,就像我之前所做的那样。
还要记住加载 http://momentjs.com/
我也遇到了同样的问题。
我在 td 中使用 span,例如 03/21/2017,通过这样做,datatable 将其视为字符串并且排序不起作用。
我删除了 td 内部的跨度,它得到了修复。比如,03/21/2017<</p>
我在其余调用中使用
**日期变量为:创建**
var call = $.ajax({
url: "../_api/Web/Lists/GetByTitle('NewUser')/items?$filter=(Created%20ge%20datetime'"+FromDate+"')%20and%20(Created%20le%20datetime'"+ToDate+"' and Title eq '"+epf+"' )&$top=5000",
type: "GET",
dataType: "json",
headers: {
Accept: "application/json;odata=verbose"
}
});
call.done(function (data,textStatus, jqXHR){
$('#example').dataTable({
"bDestroy": true,
"bProcessing": true,
"aaData": data.d.results,
"aLengthMenu" : [
[50,100],
[50,100]
],
dom: 'Bfrtip',
buttons: [
'copy', 'csv', 'excel'
],
"aoColumnDefs": [{ "bVisible": false }],
"aoColumns": [
{ "mData": "ID" },
{ "mData": "Title" },
{ "mData": "EmployeeName" },
{ "mData": "Department1" },
{ "mData": "ServicingAt" },
{ "mData": "TestField" },
{ "mData": "BranchCode" },
{ "mData": "Created" ,"render": function (data, type, row) {
data = moment(data).format('DD MMM YYYY');
return data;
}
解决这个问题的最简单方法
只需像这样稍微修改您的设计
//Add this data order attribute to td
<td data-order="@item.CreatedOn.ToUnixTimeStamp()">
@item.CreatedOn
</td>
Add create this Date Time helper function
// #region Region
public static long ToUnixTimeStamp(this DateTime dateTime) {
TimeSpan timeSpan = (dateTime - new DateTime(1970, 1, 1, 0, 0, 0));
return (long)timeSpan.TotalSeconds;
}
#endregion
似乎对我有用的是
在数据集中推送使用从我的数据库中的 SELECT 查询获取的完整日期时间对象,该对象将按数据表格式"2018-01-05 08:45:56"绘制
然后
$('#Table').DataTable({
data: dataset,
deferRender: 200,
destroy: true,
scrollY: false,
scrollCollapse: true,
scroller: true,
"order": [[2, "desc"]],
'columnDefs': [
{
'targets': 2,
'createdCell': function (td, cellData, rowData, row, col) {
var datestamp = new Date(cellData);
$(td).html(datestamp.getUTCDate() + '-' + (datestamp.getMonth()+1) + '-' + datestamp.getFullYear());
}
}
],
"initComplete": function(settings, json) {
$($.fn.dataTable.tables(true)).DataTable()
.columns.adjust();
}
});
行排序正确,然后我在行中得到我想要的html
因为我发现在这种情况下最简单的排序方法是在 JS 中添加"aaSorting"选项。
例如:
$(document).ready(function() {
$('#contacts-table').dataTable({
"aaSorting": [0, 'desc']
});
这里的问题是,此示例将像 STRING 一样对第 1-st 列中的条目进行排序,但不像日期。如果源代码允许您将日期格式从 dd/mm/yyyy 更改为 yyyy/mm/dd,"aaSorting"将为您正常工作。
在 <td>
标签上使用 data-order
属性,如下所示(Ruby 示例):
<td data order='<%=rentroll.decorate.date%>'><%=rentroll.decorate.date%></td>
您在此处的装饰器功能将是:
def date
object.date&.strftime("%d/%m/%Y")
end
如果您从数据库中获取日期并为每一行执行 for 循环,并将其附加到字符串以在 javascript 中用于自动填充数据表,它将需要如下所示。请注意,使用隐藏跨度技巧时,您需要考虑日期的个位数,例如如果是第 6 小时,您需要在它之前添加一个零,否则跨度技巧在排序中不起作用。代码示例:
DateTime getDate2 = Convert.ToDateTime(row["date"]);
var hour = getDate2.Hour.ToString();
if (hour.Length == 1)
{
hour = "0" + hour;
}
var minutes = getDate2.Minute.ToString();
if (minutes.Length == 1)
{
minutes = "0" + minutes;
}
var year = getDate2.Year.ToString();
var month = getDate2.Month.ToString();
if (month.Length == 1)
{
month = "0" + month;
}
var day = getDate2.Day.ToString();
if (day.Length == 1)
{
day = "0" + day;
}
var dateForSorting = year + month + day + hour + minutes;
dataFromDatabase.Append("<span style=u0022display:none;u0022>" + dateForSorting +
</span>");
试试这个:
"aoColumns": [
null,
null,
null,
null,
{"sType": "date"}, // "sType": "date" TO SPECIFY SORTING IS APPLICABLE ON DATE
null
]
对于您要排序的列,请保留"sType":"date-uk"例如:- "data": "OrderDate", "sType": "date-uk"
在 ajax 中完成数据表脚本后,保留以下代码
jQuery.extend(jQuery.fn.dataTableExt.oSort, {
"date-uk-pre": function (a) {
var ukDatea = a.split('/');
return (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
},
"date-uk-asc": function (a, b) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"date-uk-desc": function (a, b) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
});
然后,您将获得此格式的日期为22-10-2018
问题来源是日期时间格式。
错误的样本:"MM-dd-yyyy H:mm","MM-dd-yyyy"
正确的样本:"MM-dd-yyyy HH:mm"
最简单的方法是在列的每个TD标签的日期之前添加一个隐藏的时间戳,例如:
<td class="sorting_1">
<span class="d-none">1547022615</span>09/01/2019 09:30
</td>
使用默认字符串排序时,时间戳将按您想要的方式对列进行排序,并且在浏览器中呈现时不会显示。
任何在 UTC 格式或其他人方面苦苦挣扎的人都可以阅读这篇文章
假设您有这种格式的日期
周二 10月 15 2019 08:41:35 GMT+0000 (UTC)
首先,我们可以使用矩将其转换为毫秒
例如,在我的情况下,我使用的是HandleBar.js。所以我创建了一个帮助程序函数来简化它
hbs.registerHelper('dateformat', function (datetime) {
return moment(datetime).valueOf(); })
否则
只需以这种方式转换它
moment("Tue Oct 15 2019 08:41:35 GMT+0000 (UTC)").valueOf();
完成后,只需将这些值传递到表中即可
现在这里的诀窍是将它们都传递并在毫秒内隐藏一个并以 UTC 格式显示一个
<td >
<span class="hideThisDate">{{DATA IN MILLISECONDS}}</span>
{{YOUR DATE IN NORMAL FORMAT}}</td>
现在只需通过CSS在几毫秒内隐藏一个
.hideThisDate {
display:none;
}
你应该很高兴去!
我在使用Doctrine时遇到了同样的问题。我的数据是用orderBy('p.updatedAt', 'DESC')
从数据库中正确排序的,但是当DataTable处理它们时,最终结果完全不同。
我发现解决此问题的最可靠方法是在我的表中添加一个隐藏的列时间戳,然后在按日期排序时按此列排序。完整的功能示例在这里。
<table>
<thead>
<th>Some column<th>
<th>Visible date<th>
<th>Timestamp<th>
</thead>
<tbody>
<td>Example with Twig</td>
<td>{{ product.updatedAt ? time_diff(product.updatedAt) : '' }}</td>
<td>{{ product.updatedAt ? product.updatedAt.getTimestamp() : '' }}</td>
</tbody>
</table>
$(document).ready(function() {
let dateColumn = 1;
let timestampColumn = 2;
let currentColumn = timestampColumn;
let currentDirection = "desc";
let table = $("#dataTable").DataTable({
"order": [
[ timestampColumn, "desc" ],
// If you want to keep the default order from database
// just set "order": [] so DataTable wont define other order
],
"columnDefs": [
{
"targets": [ timestampColumn ],
"visible": false, // Hide the timestamp column
},
]
});
/**
* @var e: Events
* @var settings: DataTable settings
* @var ordArr: Current order used by DataTable
* example: [{"src":8,"col":8,"dir":"asc","index":0,"type":"string"}]
*/
table.on("order.dt", function (e, settings, ordArr) {
currentColumn = ordArr[0].col;
currentDirection = ordArr[0].dir;
if(currentColumn === dateColumn) {
table.order([timestampColumn, currentDirection]).draw();
// Without this line you'll get an unexpected behaviour
table.order([dateColumn, currentDirection]);
}
})
});
如果有人在服务器端排序方面遇到问题,只需确保visual
列索引对应于响应中的索引
<thead>
<th>Column0</th>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
</thead>
$columns = array(
array( 'db' => 'Column0', 'dt' => '0', 'field' => 'Column0' ),
array( 'db' => 'Column1', 'dt' => '4', 'field' => 'Column1' ),// looks ad 'dt' value
array( 'db' => 'Column2', 'dt' => '2', 'field' => 'Column2' ),
array( 'db' => 'Column3', 'dt' => '3', 'field' => 'Column3' ),
array( 'db' => 'HelperColumn', 'dt' => '1', 'field' => 'HelperColumn' )
);
在这种情况下,如果您单击以对column1
进行排序,在这种情况下,它可能会根据helperColumn
对表进行排序,因为在请求索引中列是 passet order
参数order: [{column: "1", dir: "asc"}]
至少这对我来说是问题
第一个答案是正确的,但不太清楚,人们会困惑我也是
但现在我找到了逻辑,在一个带有我使用的示例日期的示例元素下方
<td data-sort="2023-04-20">
20-04-2023
</td>
这将起作用,逻辑是:-
年份 - 第一优先级
月 - 第二优先级
日 - 第三优先级
用于对日期数据进行排序