Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Column that contains dates in relative format is not sorted (using sugar.js and parser-date.js) #1402

Closed
darkred opened this issue May 18, 2017 · 6 comments

Comments

@darkred
Copy link

darkred commented May 18, 2017

I'm trying to make a userscript (for Greasemonkey 3.11 in FF 53)
to make the table results in e,g, https://www.ixirc.com/?q=Prey sortable.

The values of the search results in the above link
in columns 7 and 8 (which contain dates in relative format) are like this:

15 minutes ago
7 minutes ago
1 hours ago
25 minutes ago

So, following the documentation and this SO reply (by Mottie)
I wrote this script, which recreates a <thead> then calls the tablesorter plugin.
Unfortunately the columns 7 and 8 are not sorted when you click the header.
(all other columns are sortable alright)
Plus,when you sort by any other column, clicking the 7th or 8th column header a 2nd time it just restores the initial sorting for them.
I'm (almost) certain that it should work alright.

// ==UserScript==
// @name        ixIRC - make search results sortable
// @include     https://www.ixirc.com/?q=*
// @grant       none
// @require     http://code.jquery.com/jquery-3.2.1.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.28.10/js/jquery.tablesorter.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/sugar/2.0.4/sugar.min.js
// @require     https://rawgit.com/Mottie/tablesorter/master/js/parsers/parser-date.js
// ==/UserScript==

// jQuery fix for tables lacking a thead / http://aaron.jorb.in/blog/2010/03/jquery-fix-for-tables-lacking-a-thead/
$('#results-table').prepend($('<thead></thead>').append($('#results-table tr:first').remove()));

// replace hr --> hours and min --> minutes
var timestamps = document.querySelectorAll('tr > td:nth-child(8), tr > td:nth-child(9)');
for (let i = 0; i < timestamps.length; i++) {
	timestamps[i].innerText = timestamps[i].innerText.replace('hr', 'hours').replace('min', 'minutes').replace('sec', 'seconds');;
}

//  http://stackoverflow.com/a/26343716/3231411
$('#results-table').tablesorter ( { 
	headers: {
		7: { sorter:'sugar'},
		8: { sorter:'sugar'}
	},

} );
@darkred darkred changed the title Column that contains dates in relative format is not sorted (using sugar and parser-date.js) Column that contains dates in relative format is not sorted (using sugar.js and parser-date.js) May 18, 2017
@Mottie
Copy link
Owner

Mottie commented May 18, 2017

Hi @darkred!

I think the problem is that sugar.js modifies the prototype and was causing a javascript error. I did the following:

  • Switch to using date.js, which accepts "min" and "sec" so you don't need to modify those strings. But you do need to convert "hr" into "hour".
  • jQuery is already available on the page, so I removed the @require
  • Included the datejs parser inline and modified it to replace "hr" with "hour". Removed that @require.
  • Added @run-at document-idle

And it started working:

// ==UserScript==
// @name        ixIRC - make search results sortable
// @include     https://www.ixirc.com/?q=*
// @grant       none
// @run-at      document-idle
// @require     https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.28.10/js/jquery.tablesorter.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/datejs/1.0/date.min.js
// ==/UserScript==
(() => {
 // jQuery fix for tables lacking a thead / http://aaron.jorb.in/blog/2010/03/jquery-fix-for-tables-lacking-a-thead/
 $('#results-table').prepend($('<thead></thead>').append($('#results-table tr:first').remove()));

 $.tablesorter.addParser({
  id: "datejs",
  is: function() {
   return false;
  },
  format: function(s) {
   var str = s.replace('hr', 'hour');
   var date = Date.parse ? Date.parse(str) : s ? new Date(str) : s;
   return date instanceof Date && isFinite(date) ? date.getTime() : s;
  },
  type: "numeric"
 });

 // http://stackoverflow.com/a/26343716/3231411
 $('#results-table').tablesorter ({
  headers: {
   7: { sorter:'datejs'},
   8: { sorter:'datejs'}
  }
 });

})();

@darkred
Copy link
Author

darkred commented May 18, 2017

Thanks a lot for replying @Mottie !

Two notes:

jQuery is already available on the page

  • I think jQuery is not available,
    because when I run the script, tablesorter shows an jQuery is not defined error in Browser Console.
    Also, when I search for !jquery in Debugger devtool in that page it doesnt't show anything.

  • With your code (after re-adding the jQuery @require ) now the column is indeed sortable but the results are not correct:
    screenshot from the last column, after clicking the header once:
    2017-05-18_234607

@Mottie
Copy link
Owner

Mottie commented May 19, 2017

Sorry for now getting back to you until now... it took me a while to find the problem. Apparently datejs doesn't support "ago" properly, it parses the time oddly.... if I enter 12 minutes ago versus 13 minutes ago, the 12 minutes ago will parse correctly, but 13 will end up being 1 minute ago - (see datejs/Datejs#102).

Since Datejs does support -12 minutes and -13 minutes, I modified the parser to remove the "ago" and add a negative sign in front.

And you were right about jQuery... I was messing around with it and probably forgot to reload the page. Anyway, here is the updated userscript:

// ==UserScript==
// @name        ixIRC - make search results sortable
// @include     https://www.ixirc.com/?q=*
// @grant       none
// @run-at      document-idle
// @require     http://code.jquery.com/jquery-3.2.1.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.28.10/js/jquery.tablesorter.min.js
// @require     http://www.datejs.com/build/date.js
// ==/UserScript==
(($) => {
  // jQuery fix for tables lacking a thead
  // http://aaron.jorb.in/blog/2010/03/jquery-fix-for-tables-lacking-a-thead/
  $('#results-table')
    .prepend($('<thead></thead>')
    .append($('#results-table tr:first').remove()));

  $.tablesorter.addParser({
    id: "datejs",
    is: function() {
      return false;
    },
    format: function(s) {
      var str = s
        .replace('hr', 'hour')
        .replace('min', 'minute')
        .replace('sec', 'seconds')
        .replace('ago', ''),
      date = Date.parse ? Date.parse('-' + str) : s ? new Date(str) : s;
      return date instanceof Date && isFinite(date) ? date.getTime() : s;
    },
    type: "numeric"
  });

  // http://stackoverflow.com/a/26343716/3231411
  $('#results-table').tablesorter ({
    headers: {
      // 7: { sorter:'datejs'},
      8: { sorter:'datejs'}
    }
  });

})(jQuery.noConflict(true));

@darkred
Copy link
Author

darkred commented May 19, 2017

Update:

I've noticed in the test form here http://www.datejs.com/
that DateJS doesn't correctly parse relative dates, when they refer to more than 12 hours ago,,
e.g. now is Friday, May 19, 2017 6:28:00 PM,
then 12 hours ago will become converted as: Saturday, May 20, 2017 6:28:00 AM
but for any larger interval it will parse it as 1 hour ago:
13 hours ago ---> Friday, May 19, 2017 5:28:00 PM,
14 hours ago ---> Friday, May 19, 2017 5:28:00 PM, etc.


On the other hand SugarJS parses alright these date cases.
Test form: https://sugarjs.com/dates/#/Parsing


I noticed that DateJS is no longer maintained since early 2010/

I found that there is a fork of it that it's actively maintained: DateJS Evolved.
But when I tested it e.g. Date.parse('13 hours ago') it parsed it as "6 days and 1 hour ago!",
i.e. Date 2017-05-13T15:28:00.000Z (+0300) !!!

And MomentJS unfrotunatey doesn't parse dates in relative format..

@Mottie
Copy link
Owner

Mottie commented May 19, 2017

Hehe

@darkred
Copy link
Author

darkred commented May 19, 2017

Hehe

We posted simultaneously 😃

Your solution works great!
So, thanks a lot for your time! I really appreciate this!
I'm a big fan of tablesorter and all your work, but you already know that!

@darkred darkred closed this as completed May 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants