6

I'm writing a greasemonkey user.js for a page with a table in it. (Table is 100 rows by 18 columns.) Now what I want to do is to make it sortable on column, and also have it run in both Chrome and Firefox.

All searches for answers so far resulted in suggestions to use jquery/dojo or something alike.

Can I be done without any external code? Ofter all it's just a matter of replacing the row's in a different order, right? or is that a silly thing to say?

The thing is that I'm already using dojo for some query needs but since I want it to run in both Firefox and Chrome, I just copy paste the whole dojo thing in my script..

Also, most of the solutions I found so far seem to be more for use when building a table, not for altering an existing one.

Any help is appreciated.

EDIT: All cells in the table contain numbers.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
plastic cloud
  • 241
  • 1
  • 4
  • 12

2 Answers2

3

The smart way is to use a tool like tablesorter.
But, since you don't want to use external code (for now), it can be done the hard way.

Here's how to do it the semi-hard way. Note that I AM using jQuery. You'd be smart to incorporate at least that into your script.

Go ahead and use the // @require directive. You can still run the GM script in Chrome using the Tampermonkey extension.
(There are other ways of including jQuery in GM scripts under Chrome, as well.)

Anyway, code like so: will do the trick:

//--- Get the table we want to sort.
var jTableToSort    = $("table#myTable");

//--- Get the rows to sort, but skip the first row, since it contains column titles.
var jRowsToSort     = jTableToSort.find ("tr:gt(0)");

//--- Sort the rows in place.
jRowsToSort.sort (SortByFirstColumnTextAscending).appendTo (jTableToSort);

function SortByFirstColumnTextAscending (zA, zB)
{
     var ValA_Text  = $(zA).find ("td:eq(0)").text ();
     var ValB_Text  = $(zB).find ("td:eq(0)").text ();

     if      (ValA_Text  >  ValB_Text)
        return 1;
     else if (ValA_Text  <  ValB_Text)
        return -1;
     else
        return 0;
}


You can see it in action at jsFiddle.


Update:

To sort numbers, you would use a sorting function like:

function SortBy2ndColumnNumber (zA, zB)
{
   var ValA = parseFloat ($(zA).find ("td:eq(1)").text () );
   var ValB = parseFloat ($(zB).find ("td:eq(1)").text () );

   return ValA - ValB;
}

See number sorting in action at jsFiddle.

Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • many thanks! but, i forgot to mention i have numbers in the table only. how to sort those with your code-technique? I will try tampermonkey to get to work again later. so far no good. – plastic cloud Jan 11 '11 at 16:56
  • @plastic cloud: I've updated my answer to show number sorting, also. – Brock Adams Jan 11 '11 at 21:13
2

I'm trying not to answer these "can I have some code please" questions, but since Anders needled me. Here is a simple answer with no libraries. Some big assumptions though:

  1. Only integers in the column to be sorted
  2. Only sort on one column
  3. No indication of the sorted state
  4. No IE since it can't do the Array.prototype.slice.call trick.

You could improve getRowValue to get past assumption #1 pretty easily though.

function sortTable(table, col) {
  var rows = Array.prototype.slice.call(table.getElementsByTagName('tr'), 0);
  rows.sort(function(a,b) {
    return getRowValue(a, col) - getRowValue(b, col);
  });

  for (var i=0, row; row = rows[i]; i++) {
    table.appendChild(row);
  }

  function getRowValue(row, col) {
    return parseInt(row.cells[col].innerHTML, 10);
  }
}​

DEMO: http://jsbin.com/akexe4

Hemlock
  • 6,130
  • 1
  • 27
  • 37