Fix timestamps not sorting in datatables
Timestamps retrieved from the API were always converted to a browser
local format. The format specified for moment.js added in
5160eff294
did not work because of this.
Additionally, the format specified used `dd` which looks for two letter
days, such as "Mo", "Tu", "We", etc. Furthermore, `mm` is used for
minutes, not months.
Because the locale formatted datetime can vary a lot, it is not easy to
get this into moment.js to enable the sorting of datetimes in the
datatables. In other words, there is no conversion from an
`Intl.DateTimeFormat` specifier string to moment.js. Adding many
`$.fn.dataTable.moment(format);` with different `format`s is not useful.
I have fixed this rewriting how the timestamps from the API are added
to the tables. It still uses the locale of the browser, because not
everyone wants to use ISO 8601, but no longer requires moment.js (which
has been removed).
Two data attributes are added to the `td`s of the timestamps:
- `data-order`
- `data-sort`
The values of these are the timestamps as returned by the server, which
are very easily sorted (as they are just UNIX timestamps). Then, when
creating the cell in the table, it will be converted to what the locale
of the browser specified (this has not changed).
This commit is contained in:
parent
55d57c552d
commit
240b2c63f6
7
data/web/js/build/004-moment.min.js
vendored
7
data/web/js/build/004-moment.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* This plug-in for DataTables represents the ultimate option in extensibility
|
|
||||||
* for sorting date / time strings correctly. It uses
|
|
||||||
* [Moment.js](http://momentjs.com) to create automatic type detection and
|
|
||||||
* sorting plug-ins for DataTables based on a given format. This way, DataTables
|
|
||||||
* will automatically detect your temporal information and sort it correctly.
|
|
||||||
*
|
|
||||||
* For usage instructions, please see the DataTables blog
|
|
||||||
* post that [introduces it](//datatables.net/blog/2014-12-18).
|
|
||||||
*
|
|
||||||
* @name Ultimate Date / Time sorting
|
|
||||||
* @summary Sort date and time in any format using Moment.js
|
|
||||||
* @author [Allan Jardine](//datatables.net)
|
|
||||||
* @depends DataTables 1.10+, Moment.js 1.7+
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* $.fn.dataTable.moment( 'HH:mm MMM D, YY' );
|
|
||||||
* $.fn.dataTable.moment( 'dddd, MMMM Do, YYYY' );
|
|
||||||
*
|
|
||||||
* $('#example').DataTable();
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function (factory) {
|
|
||||||
if (typeof define === "function" && define.amd) {
|
|
||||||
define(["jquery", "moment", "datatables.net"], factory);
|
|
||||||
} else {
|
|
||||||
factory(jQuery, moment);
|
|
||||||
}
|
|
||||||
}(function ($, moment) {
|
|
||||||
|
|
||||||
function strip (d) {
|
|
||||||
if ( typeof d === 'string' ) {
|
|
||||||
// Strip HTML tags and newline characters if possible
|
|
||||||
d = d.replace(/(<.*?>)|(\r?\n|\r)/g, '');
|
|
||||||
|
|
||||||
// Strip out surrounding white space
|
|
||||||
d = d.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
$.fn.dataTable.moment = function ( format, locale, reverseEmpties ) {
|
|
||||||
var types = $.fn.dataTable.ext.type;
|
|
||||||
|
|
||||||
// Add type detection
|
|
||||||
types.detect.unshift( function ( d ) {
|
|
||||||
d = strip(d);
|
|
||||||
|
|
||||||
// Null and empty values are acceptable
|
|
||||||
if ( d === '' || d === null ) {
|
|
||||||
return 'moment-'+format;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 ) {
|
|
||||||
d = strip(d);
|
|
||||||
|
|
||||||
return !moment(d, format, locale, true).isValid() ?
|
|
||||||
(reverseEmpties ? -Infinity : Infinity) :
|
|
||||||
parseInt( moment( d, format, locale, true ).format( 'x' ), 10 );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
}));
|
|
@ -274,11 +274,10 @@ $(document).ready(function() {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
// Jquery Datatables, enable responsive plugin and date sort plugin
|
// Jquery Datatables, enable responsive plugin
|
||||||
$.extend($.fn.dataTable.defaults, {
|
$.extend($.fn.dataTable.defaults, {
|
||||||
responsive: true
|
responsive: true
|
||||||
});
|
});
|
||||||
$.fn.dataTable.moment('dd:mm:YYYY');
|
|
||||||
|
|
||||||
// tag boxes
|
// tag boxes
|
||||||
$('.tag-box .tag-add').click(function(){
|
$('.tag-box .tag-add').click(function(){
|
@ -1,3 +1,13 @@
|
|||||||
|
const LOCALE = undefined;
|
||||||
|
const DATETIME_FORMAT = {
|
||||||
|
year: "numeric",
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
second: "2-digit"
|
||||||
|
};
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// Parse seconds ago to date
|
// Parse seconds ago to date
|
||||||
// Get "now" timestamp
|
// Get "now" timestamp
|
||||||
@ -7,14 +17,7 @@ $(document).ready(function() {
|
|||||||
if (typeof started_s_ago != 'NaN') {
|
if (typeof started_s_ago != 'NaN') {
|
||||||
var started_date = new Date((ts_now - started_s_ago) * 1000);
|
var started_date = new Date((ts_now - started_s_ago) * 1000);
|
||||||
if (started_date instanceof Date && !isNaN(started_date)) {
|
if (started_date instanceof Date && !isNaN(started_date)) {
|
||||||
var started_local_date = started_date.toLocaleDateString(undefined, {
|
var started_local_date = started_date.toLocaleDateString(LOCALE, DATETIME_FORMAT);
|
||||||
year: "numeric",
|
|
||||||
month: "2-digit",
|
|
||||||
day: "2-digit",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit",
|
|
||||||
second: "2-digit"
|
|
||||||
});
|
|
||||||
$(this).text(started_local_date);
|
$(this).text(started_local_date);
|
||||||
} else {
|
} else {
|
||||||
$(this).text('-');
|
$(this).text('-');
|
||||||
@ -25,14 +28,7 @@ $(document).ready(function() {
|
|||||||
$('.parse_date').each(function(i, parse_date) {
|
$('.parse_date').each(function(i, parse_date) {
|
||||||
var started_date = new Date(Date.parse($(this).text()));
|
var started_date = new Date(Date.parse($(this).text()));
|
||||||
if (typeof started_date != 'NaN') {
|
if (typeof started_date != 'NaN') {
|
||||||
var started_local_date = started_date.toLocaleDateString(undefined, {
|
var started_local_date = started_date.toLocaleDateString(LOCALE, DATETIME_FORMAT);
|
||||||
year: "numeric",
|
|
||||||
month: "2-digit",
|
|
||||||
day: "2-digit",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit",
|
|
||||||
second: "2-digit"
|
|
||||||
});
|
|
||||||
$(this).text(started_local_date);
|
$(this).text(started_local_date);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -75,6 +71,13 @@ jQuery(function($){
|
|||||||
var table_name = $(this).data('table');
|
var table_name = $(this).data('table');
|
||||||
$('#' + table_name).DataTable().ajax.reload();
|
$('#' + table_name).DataTable().ajax.reload();
|
||||||
});
|
});
|
||||||
|
function createSortableDate(td, cellData) {
|
||||||
|
$(td).attr({
|
||||||
|
"data-order": cellData,
|
||||||
|
"data-sort": cellData
|
||||||
|
});
|
||||||
|
$(td).html(convertTimestampToLocalFormat(cellData));
|
||||||
|
}
|
||||||
function draw_autodiscover_logs() {
|
function draw_autodiscover_logs() {
|
||||||
// just recalc width if instance already exists
|
// just recalc width if instance already exists
|
||||||
if ($.fn.DataTable.isDataTable('#autodiscover_log') ) {
|
if ($.fn.DataTable.isDataTable('#autodiscover_log') ) {
|
||||||
@ -100,9 +103,8 @@ jQuery(function($){
|
|||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
responsivePriority: 1,
|
responsivePriority: 1,
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -157,9 +159,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -200,9 +201,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -247,9 +247,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -306,9 +305,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -393,9 +391,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -481,9 +478,9 @@ jQuery(function($){
|
|||||||
title: lang.login_time,
|
title: lang.login_time,
|
||||||
data: 'datetime',
|
data: 'datetime',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data.replace(/-/g, "/"));
|
cellData = Math.floor((new Date(data.replace(/-/g, "/"))).getTime() / 1000);
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
createSortableDate(td, cellData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -513,9 +510,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -551,9 +547,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -594,9 +589,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -637,9 +631,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -740,9 +733,8 @@ jQuery(function($){
|
|||||||
title: lang.time,
|
title: lang.time,
|
||||||
data: 'time',
|
data: 'time',
|
||||||
defaultContent: '',
|
defaultContent: '',
|
||||||
render: function(data, type){
|
createdCell: function(td, cellData) {
|
||||||
var date = new Date(data ? data * 1000 : 0);
|
createSortableDate(td, cellData)
|
||||||
return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1531,3 +1523,8 @@ function parseGithubMarkdownLinks(inputText) {
|
|||||||
|
|
||||||
return replacedText;
|
return replacedText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertTimestampToLocalFormat(timestamp) {
|
||||||
|
var date = new Date(timestamp ? timestamp * 1000 : 0);
|
||||||
|
return date.toLocaleDateString(LOCALE, DATETIME_FORMAT);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user