Sorttable, the JavaScript table sorting library, is pretty much the most popular thing I’ve ever written. (Top hit for “javascript sort table” on Google, too.) Over the four years or so since I first released it, there’s been a steady trickle of thanks, feature requests, and bug fixes to it. I’ve finally got around to releasing a new version of the script that hopefully covers everything that people were looking for. You can get it at the same place as it ever was, sorttable: Make all your tables sortable.
What’s changed in version 2
The most important thing that’s changed is that sorttable now has a much much clever automatic column typer. You still can just drop sorttable in place and not have to do any configuration, but it’s quite a bit cleverer about working out whether your columns are numeric or dates or currency or text. It skips blank lines, it can tell the difference between English and American format dates, it understands numbers with commas in and negative numbers. This is the number one feature request.
Secondly, you can now use custom sort keys for those columns that sorttable can’t work out for itself. See the page for details, but this should allow anyone to make anything work with sorttable v2.
It’s also a bit more compliant with HTML standards. To add a “totals” row you should add the row to a <tfoot> section in your table. Sorttable v1 used a class of “sortbottom” on totals rows; for backwards compatibility this is still supported, but you really should be using <tfoot> instead.
In a similar way, sorttable now uses <thead> as your column headers if you have it. If you do not have it then it will create a <thead> and put the first row of your table in it. This is a backwards incompatible change: to apply style to your table headers, you should now style table.sortable thead, not table.sortable a.sortheader as in v1.
Input elements are now supported in table cells! If your table cells contain input elements then sorttable will use the value in the input element.
Sorttable is now quite a lot faster than it used to be, owing to various little tweaks. It’s especially fast at resorting the table by the column you’ve already sorted by (but reversed), because now it just reverses the table rather than doing the sort.
Stable sorting is supported but commented out in the code (because the stable sort is implemented in JavaScript, not using the native list sorter, and so it’s a lot slower). You can change this by editing one line in sorttable.js if stable sorting is important; see the page for details.
Thanks
Lots of people (really, really lots) have contributed code suggestions, feature requests, bug reports, and compliments about sorttable. Here’s my chance to say thankyou. So: thankyou to…
Eric Chang, Mehmet Kut, Dan Synder, Jeff Bradley, Eric Holstege, Victor Kryukov, Nikola Ivanov, Geoff Clevenger, Mikko Suniala, Scott Reynen, Justin Meyer, Leonardo Kenji Shikida, Ben Ostrowsky, Daniel Berlin, Richard Snazell, Mark James, Eric Rizzo, Garve, Andreas Rehm, Scott Kingdon, Marcus Månsson, Bill Barry, Michael Rumpler, Avi Rogers, Kevin Wu, Espen Hovlands, Petronel Laviniu Malutan, John M. Pierre, opus27, Brendan Bowles, Marty O’Brien, Alex Rubin, Chris Gay, Jack Vanhan, Guy Rosen, John Dawson, Ryan Korczykowski, Carl Forde, Pete K, Glenn Haser, Richard Grassy, Olivier Briat, Bob Hanson, Alex Z, Narayana Rao Kankipati, Rey Hernandez, Eric Moriztz, Marco Valk, Marcus Daniel, David Dockhorn, Angela Weise, Aneel Nazareth, Jeremy Hulford, Thomas K. Weinstock, Edward, Matthew Egbers, Anton Berezin, Moustafa Elqabbany, Justin Williams, Daniel Chace, Inigo Surguy, Vladimir Kornea, John Mund, Pablo, David Golden, Brad Kemper, Brian Schott, Christian Robottom Reis, Justin Haygood, C. David Eagle, Simon Willison, and Dean Edwards.
Phew! All those people have contacted me asking for new features or have sent me patches or have provided code that I was able to reuse in v2 of sorttable. Thankyou: for those of you who wanted sorttable to do something new, I hope you like it.
Oh..you’re where I got that code from. Thanks!
Posted by dsas on April 7th, 2007.
dsas: no problem. :)
Posted by sil on April 7th, 2007.
if i have more than one row in header, I want to do sort by the last header row, how can I set it?
thx
Posted by margiex on April 8th, 2007.
margiex: you can’t, I’m afraid. Sorttable doesn’t support tables with more than one header row, because it gets a bit confused by them.
Posted by sil on April 8th, 2007.
It would be nice if a third click on a header would revert the table back to the original sort, rather than just toggling ascending and descending on that column.
Just a thought ;)
Posted by mrben on April 8th, 2007.
mrben: daresay it would, but that would mean caching the table structure, which I’d like to avoid :) If you want that, hit refresh.
Posted by sil on April 8th, 2007.
Why would it mean caching the table structure? Surely you could define the default sort somewhere, and then re-run that particular sort on every third click of a header? Or have I over-simplified?
Posted by mrben on April 8th, 2007.
mrben: there isn’t a “default sort”; there’s just “what the table looked like when it got served from the server”, which could be in any order at all or even no order.
Posted by sil on April 8th, 2007.
Ah. Point taken. Shame ;)
Posted by mrben on April 9th, 2007.
mrben: hence “hit refresh” to get that order back.
Posted by sil on April 9th, 2007.
[...] Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback: Trackback URL. « Discussion List, Crossdomain.xml forFlash [...]
Posted by log @ Make Data Make Sense » Sortable Tables with Totals and Averages on April 10th, 2007.
Would it be possible to add some extra variables to the makeSortable() function, like:
makeSortable($(’table’), ‘header’, ‘ASC’);
Where the last two can the name of the header and sorting order you’d like to use for sorting immediately instead of just adding the event listeners.
Posted by tommie on April 11th, 2007.
tommie: Sorttable doesn’t support sorting the table as soon as the page is loaded. There are some notes as to why not in the old sorttable documentation (see “Sorting a table the first time the page is loaded”).
Posted by sil on April 11th, 2007.
In Netscape 8 this script close the window. There is a solution for this?
Posted by Anonymous on April 13th, 2007.
Stuart: I’ve just had the inevitable “client-side sorting” request on a new project I’m working on. Less than 5 minutes later, we had it working. Thanks a lot for this script, I owe you a drink.
Posted by GaryF on April 14th, 2007.
Nice job! If I could only get it to work :(
When I include your script file in my Asp.net AJAX site I get the following error.
Error Sys.ArgumentTypeException: Object of type ‘Object’ cannot be converted to type ‘Array’
Parametername:array
This occurs even if I don’t have any sortables defined.
Any Ideas?
The error is occuring in a file calse ResourceScript.axd
Here is the function
Array.forEach = function Array$forEach(array, method, instance) {
///
///
///
var e = Function._validateParams(arguments, [
{name: "array", type: Array, elementMayBeNull: true},
{name: "method", type: Function},
{name: "instance", mayBeNull: true, optional: true}
]);
if (e) throw e;
for (var i = 0, l = array.length; i
Posted by ScottW on April 16th, 2007.
I’ve narrowed it down further and the code below in the sorttable init function is causing the error.
forEach(document.getElementsByTagName(’table’), function(table) {
if (table.className.search(/\bsortable\b/) != -1) {
sorttable.makeSortable(table);
}
});
I’m not as versed in Javascript as you are so any help would be appreciated.
Posted by ScottW on April 16th, 2007.
Got it working. It took 2 code changes. Basically it was erroring on function(table) and onsort it error on function(Cell). I’ve include my new code in case it helps someone else.
// forEach(document.getElementsByTagName(’table’), function(table) {
var tables = document.getElementsByTagName(”table”);
for (var i=0; i
Posted by ScottW on April 16th, 2007.
Change 1
var tables = document.getElementsByTagName(”table”);
for (var i=0; i
Posted by ScottW on April 16th, 2007.
Sorry guys, this forum keeps cutting off my post when I include the code.
I basically changed each foreach loop into an index loop and accessed each table and cell using the appropriate array index.
I also had the problem that my tables are loaded via AJAX after page initialization. A simple call to sorttable.makeSortable(MyNewTable) worked like a charm.
Thanks again for the code!
Scott
Posted by ScottW on April 16th, 2007.
GaryF: that’s what it’s for. :)
Posted by sil on April 16th, 2007.
ScottW: glad you got it sorted! I’d like to talk over this in more detail; could you drop me a mail? (See the contact link for my address.)
Posted by sil on April 16th, 2007.
you are very appreciated for you good job at sorttable.js.
And i also have a question.
To have the function ” when the table is loaded, one column is sorted”, how can i do it?
thanks very much!
RobertLee
From Peking of China
Posted by robert Lee on April 19th, 2007.
Hey, I was tryin out the script, great job :) although having a few a problems, I think it is similar to ScottW’s problem, if you could somehow please provide me with the fix, I would be really thankful. I dont know if this is another problem when your table is in a javascript variable, and calling the html contents of the variable through innerHTML, but the script doesnt work on the tables then. (I think it works in IE, but not firefox and mozilla, really being odd like that)
Posted by Varun on April 20th, 2007.
To Varun:
I have used sorttable.js. it does indeed work in IE.
Posted by robert Lee on April 20th, 2007.
Fantastic tool, thanks so much!
I’m curious why you chose to use the non-standard
sorttable_customkey="2"rather than a class attribute? I’m loath to use invalid markup. ;)That said, I can see myself using this in many places, particularly at my workplace, a community college in British Columbia, Canada. I’ve been creating complicated workarounds in my custom CMS but this is a far better solution all around. Well done!
Posted by Jason Friesen on April 20th, 2007.
Jason: two reasons. Firstly, a custom sortkey is emphatically not a class :) I feel a bit guilty about using class atrributes for things like column type overrides, but they are *sort of* appropriate. If you use a class of “2″ as a sortkey, then you’re suggesting that that table cell is like other cells with a class “2″, which it ain’t; it contains (something that maps to) the value 2, which is not the same thing. That’s the academic ivory-tower argument. The other argument is that if you’ve got more than one class applied to the cell then it won’t know which one to use as the sortkey, and setting class=”sorttable_sortkey_2″ seemed very silly :) I didn’t like the invalid markup either, I have to admit it, but it seemed the lesser of the evils.
Posted by sil on April 20th, 2007.
Fair enough. I’m working tangentially with Moodle that does all sorts of your second example to attempt to be fully compliant. I admit it’s a bit crazy to look at
class="course_47 subsection_cheese_danish_12". I think I’d still prefer that, but I definitely see your point.Nevertheless, I sure appreciate the code. :)
Posted by Jason Friesen on April 20th, 2007.
I was wondering if there is any way to have the table sorted (instead of default) onload
Posted by Varun on April 21st, 2007.
Thank you so much for your script! Is there anyway to have the script ignore strings that start with “the”, “a”, and “an” when sorting? I have a list of movie titles, and it would be great if the sort ignored these words. I can use the custom sort keys, but it would be great if the script did this automatically. Thanks!
Posted by Rhonda on April 22nd, 2007.
Rhonda: it’s not possible to do that easily, I’m afraid. I’d recommend using the custom keys to get this; I won’t make sorttable do it automatically because some people may want A or The to be included.
Posted by sil on April 22nd, 2007.
FYI, I noticed there were some lines that included a conditional statement to use
font face ="webdings"for IE. There seems to be semicolon missing after the & nbsp. I also had some trouble with some Windows boxes that didn’t have webdings installed, so I replaced them with images (ie only). I’ll try to put the code in below.original code:
sortfwdind.innerHTML = stIsIE ? '& nbsp<font face="webdings">6</font>' : '& nbsp;& #x25BE;';my replacement:
sortfwdind.innerHTML = stIsIE ? '& nbsp;<img src=\'res/i/interface/arrow-down.gif\' alt=\'\' />' : '& nbsp;& #x25BE;';Posted by Jason Friesen on April 23rd, 2007.
(please note that I added spaces to the above comment; they shouldn’t be included in the original js, of course.)
Posted by Jason Friesen on April 23rd, 2007.
How can i get default sort on particular column on page load?
Posted by Jai on May 2nd, 2007.
Is there a quick way to change the color of the column that you are sorting?
This would be very usefull for big tables.
Posted by Mike on May 3rd, 2007.
My application uses dates in the form ‘Jan 1, 2007′. Be default, sorttable treats this as alpha. I’ve managed to override this in my page with class=”sorttable_mmdd” which seems to sort chronologically instead and I thought this fixed my problem. The problem arrises when there are blank values in the list however. Instead of having all the blank values go to the beginning like I would have expected (and how the alpha and date sorts work), there are various dispersed blank values in the list. Is this a bug? Any suggestions would be welcome.
Thanks.
Posted by Scott on May 4th, 2007.
Scott: I advise you, in that situation, to use custom sortkeys. Instead of
<td>Mar 1, 2007</td>
<td></td>
use
<td sorttable_customkey=”20070301″>Mar 1,2007</td>
<td></td>
and then sorttable will happily sort them all correctly.
Posted by sil on May 4th, 2007.
My dates are being pulled from a database. How do I set up these custom keys when the output is variable? I’d need to translate 356 possible values. Many of these fields have timestamps as well. I’m not sure if what I’m trying to do is possible with this utility.
Thanks.
Posted by Scott on May 4th, 2007.
Scott: is you data stored in the database as the string “May 02 2007″, or is it stored as a date which you then format in the output? Most languages have something that will let you output ISO date format, which is designed for this sort of thing. Failing that, if sorttable isn’t good enough then don’t let m eprevent you writing your own, of course.
Posted by sil on May 4th, 2007.
I really like this. I was using v1 for some time and just happened to come back here (to look up something) and see v2 was put up. Great!
One question; if the table (which is querie’d from a db) has no rows, i get some javascript errors. I tried to fix this myself, but got into hot water quite quickly. Not that javascript errors are terrible perse; but I know people around my company will come telling me about them.
Posted by jimbo on May 5th, 2007.
jimbo: hrm. I may patch sorttable to cope with this, but to be honest the answer to “sorttable doesn’t sort a table with no rows” is “don’t do that, then”, I think ;-)
Posted by sil on May 5th, 2007.
heheh, well, i do agree.
of course, my data is coming from a mysql query, so i don’t really know how many rows are getting returned. of course, i guess i could just not display the table at all if there are no rows to display.
hmmm.. not sure why i didn’t think of that before, actually. i guess i’ll do that.
thanks. i really like this…
Posted by jimbo on May 7th, 2007.
I realize that you don’t support any ’sort on load’ function. I get lots of requests to restore a particular sort order when a page is loaded / refreshed though. In an ideal world I would create a cookie whenever a header is clicked and look for that when a page is loaded and sort accordingly. That would make my life much easier than having to pass a special ‘order by’ query value back each time.
Just my $0.02.
Thanks for the excellent script.
Posted by j on May 8th, 2007.
My solution to the “sort dates with blanks” problem: (line 271)
sort_ddmm: function(a,b) {
mtch = a[0].match(sorttable.DATE_RE);
if(mtch==null) {dt1=0};
else { y = mtch[3];
Regards
Posted by Erich Bakx on May 9th, 2007.
Is there a quick way to change the color of the column that you are sorting?
This would be very usefull for big tables.
Posted by Mike on May 11th, 2007.
jimbo, I use a function to check if there are rows come back from the db, if not I display a row, in the 1st column that says No Results. This will tell the user there is nothing, rather than just leaving it empty, and also solves your problem
Sydney
Posted by Sydney on May 16th, 2007.
I have a table with styles which shows odd rows with one colour and even rows with another. The problem comes up when I sort the table, then styles keep in the same row and the table is shown with unordered colours. Please, let me know if you have a solution for this.
Madrid, Spain
Posted by Carlos on May 21st, 2007.
A good way to deal with alternating rows is to use a modulo in the Append Child area. (There are two locations, the 2nd is for reversing the sort)
Search for tb.appendChild(row_array[j][1]); and tbody.appendChild(newrows[i]); and add the follow above them (make sure to stay inside the for loop)
if(j % 2)
row_array[j][1].className = “tRowA”;
else
row_array[j][1].className = “tRowB”;
– and –
if(i % 2)
newrows[i].className = “tRowB”;
else
newrows[i].className = “tRowA”;
Note: You hafto swap the order in the second function.
Posted by Johnny Moon on May 24th, 2007.
Hi there, Is there a solution for begin the sort in a particular row?, for example I have other kind of information in the first row, and the header begin in the second row, I’ve tried to fix it but I dont found the solution…
Posted by Max on June 4th, 2007.
Hi,
Love the script as it’s saved me a whole load of grief! I think I might have found a small bug though :-( When there is more than a single table on the page, say tables A and B, and each has columns, say 1, 2 & 3, when alternate table headers are clicked for sorting, with the third click on the same as the first header to reverse, I get an error on page and the sorting arrow appears in the wrong table. Using the table notation this would be:
click B1/2/3 -> click A1 = Error>>.
Does this relate at all to ScottW’s posts?
Thanks
Rich
Posted by Rich G on June 5th, 2007.
submission seems to have shredded part of the post
order is A1 then B1/2/3 then A1 = Error
Posted by Rich G on June 5th, 2007.
When I attempt to use more than one table I am having the same issue as Rich G . The browser displays an “invalid argument” message. Debugging shows that this is being thrown from on of the following code segments depending upon the sort: this.removeChild(document.getElementById(’sortable_sortrevind)); and this.removeChild(document.getElementById(’sortable_sortfwdind));
Posted by Matt H on June 5th, 2007.
Nice to know I haven’t gone mad ;-)
I’ve come to the conclusion this is because the element found by document.getElementById does not have to be part of the same table as the calling cell and hence cannot be removed from its children in this case.
I’m now working out how to ensure that:
a: the element name is unique and known (or work outable) per table.
b: only the cell’s siblings are searched and have the element removed as I want the sorting indicator to be possible on each table.
Any thoughts?
Cheers!
Posted by Rich G on June 5th, 2007.
Yes, more than one table on a page is broken, because I’m a bit of an idiot. It’s on the list for sorttable 3.
Posted by sil on June 5th, 2007.
Hey Rich G – I have to switch to another project for the next couple of days. If you come up with some possible ideas or dead-ends can you post them? If I can find some time, I will do the same. Thanks!
Posted by Matt H on June 5th, 2007.
Hi,
Have a solution to this, the logic behind it is that the search by id is not necessary if the table head element is searched for children of a new sort_span type and any existing ones stripped. This ensures that the spans that have the arrows are removed for that table only.
I’ve taken the liberty of using the same forEach method for the three cases for clarity.
Hope that is all clear ;-)
Changed code is:
dean_addEvent(headrow[i],”click”, function(e) {
if (this.className.search(/\bsorttable_sorted\b/) != -1) {
// if we’re already sorted by this column, just
// reverse the table, which is quicker
sorttable.reverse(this.sorttable_tbody);
this.className = this.className.replace(’sorttable_sorted’,
’sorttable_sorted_reverse’);
//get the thead for this cell
theadrow = this.parentNode;
forEach(theadrow.childNodes, function(cell) {
if (cell.nodeType == 1) { // an element
//get the spans in each cell
theNodes = cell.getElementsByTagName(’sort_span’);
//and remove them
for(var z = 0; z < theNodes.length; z++)
{
cell.removeChild(theNodes[z]);
}
}
});
sortrevind = document.createElement(’sort_span’);
//sortrevind.id = ”sorttable_sortrevind”;
sortrevind.innerHTML = stIsIE ? ’ <font face=”webdings”>5</font>’ : ’ ▴’;
this.appendChild(sortrevind);
return;
}
if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
// if we’re already sorted by this column in reverse, just
// re-reverse the table, which is quicker
sorttable.reverse(this.sorttable_tbody);
this.className = this.className.replace(’sorttable_sorted_reverse’,
’sorttable_sorted’);
//get the thead for this cell
theadrow = this.parentNode;
forEach(theadrow.childNodes, function(cell) {
if (cell.nodeType == 1) { // an element
//get the spans in each cell
theNodes = cell.getElementsByTagName(’sort_span’);
//and remove them
for(var z = 0; z < theNodes.length; z++)
{
cell.removeChild(theNodes[z]);
}
}
});
sortfwdind = document.createElement(’sort_span’);
//sortfwdind.id = ”sorttable_sortfwdind”;
sortfwdind.innerHTML = stIsIE ? ’ <font face=”webdings”>6</font>’ : ’ ▾’;
this.appendChild(sortfwdind);
return;
}
// remove sorttable_sorted classes
theadrow = this.parentNode;
forEach(theadrow.childNodes, function(cell) {
if (cell.nodeType == 1) { // an element
cell.className = cell.className.replace(’sorttable_sorted_reverse’,”);
cell.className = cell.className.replace(’sorttable_sorted’,”);
//get the spans in each cell
theNodes = cell.getElementsByTagName(’sort_span’);
//and remove them
for(var z = 0; z < theNodes.length; z++)
{
cell.removeChild(theNodes[z]);
}
}
});
this.className += ’ sorttable_sorted’;
sortfwdind = document.createElement(’sort_span’);
sortfwdind.id = ”sorttable_sortfwdind”;
sortfwdind.innerHTML = stIsIE ? ’ <font face=”webdings”>6</font>’ : ’ ▾’;
this.appendChild(sortfwdind);
Posted by Rich G on June 6th, 2007.
just realised that the last
sortfwdind.id = ”sorttable_sortfwdind”;
should have been commented out
Posted by Rich G on June 6th, 2007.
Also fixed/tweaked the code for alternate table row styling in the reverse function suggected by Johnny Moon, as this didn’t take into account the fact that the mod of the last row number (and hence the first row) for the reversed table was not the same as the mod of the first row in the normal table if there were an even number of rows, which meant that the styling would be swapped on the first reverse sort click for the row and this would persist until another column was chosen for sorting or the page refreshed, a very minor bug but visually distracting. The fix checks whether the table has an odd or even number of lines and then allocates styling accordingly, note that only the reverse function was affected by this:
for (var i=newrows.length-1; i>=0; i–) {
//begin inserted statement
if(i % 2)
{
if(newrows.length % 2) //odd number of rows so start with tRowB
newrows[i].className = (’tRowB’);
else
newrows[i].className = (’tRowA’);
}
else
{
if(newrows.length % 2) //odd number of rows so start with tRowA
newrows[i].className = (’tRowA’);
else
newrows[i].className = (’tRowB’);
}
//end of inserted statement//
tbody.appendChild(newrows[i]);
Posted by Rich G on June 6th, 2007.
Thanks Rich G!
Posted by Matt H on June 6th, 2007.
A bug in IE 6 causes a security warning when loading the script over https
A fix is to replace this line:
document.write(”<script id=__ie_onload defer src=javascript:void(0)><\/script>”);
With:
document.write(”<script id=__ie_onload defer src=’dummy.html’><\/script>”);
The bug is documented all over the place. The html page given doesn’t even need to exist.
—Alex
Posted by Alex on June 6th, 2007.
Ah thanks Alex I ran into that one last night and was about to look for a solution today and hey presto…
Posted by Rich G on June 7th, 2007.
Any plans to add scrollability to the code? Ideally, headers and footer stay fixed, body is scrollable. We have the first part worked out (IE6), but not the second.
Posted by Jett on June 8th, 2007.
Jett: I’m not planning on adding that to sorttable; it’s just for sorting tables. http://www.imaputz.com/cssStuff/bulletVersion.html might be useful.
Posted by sil on June 8th, 2007.
In V2, how do I change the initial defualt sort direction from ascending to descending?
Thanks!
Posted by Mike on June 17th, 2007.
Mike: this requires editing sorttable.js. After the line:
row_array.sort(this.sorttable_sortfunction);
add a new line:
row_array.reverse();
Let me know if this works.
Posted by sil on June 18th, 2007.
Beautiful! That did work! Thank you very much for all the help, you do excellent work!
Mike
Posted by mike on June 18th, 2007.
Hi Stuart,
Just to say thanks for making the code available to everyone, it saved me quite some time from writing my own.
Thanks again,
Dan
Posted by Dan on June 24th, 2007.
Hi everyone, hi Rich G!
You said you fixed the problem with multiple tables, but I really don’t know where to place the code you posted a few days ago. Could you be as kind as to post your full working code (or a link to it) here? I’d be very thankful!
mark
Posted by mark on June 26th, 2007.
Hi mark,
It replaces the dean_addEvent part of the
existing makeSortable: function(table) function and starts from about line 93ish in my editor, the rest of the code is unchanged so I wont bother clogging up the rest of this page with it ;-)
Let me know if you have any further probs
Rich G
Posted by Rich G on June 28th, 2007.
Hi Rich,
Thank you very much for your help! I%27ve finally got it!!
I always just looked at the bottom of the source where the dean_addEvent() function is defined…
Thanks for fixing this multiple table problem. It was quite important for me!
Posted by mark on June 28th, 2007.
No worries it solved quite a few probs for me too, and I only really tweaked the stuff that was already there, which made my life a whole lot easier ;-)
BTW just got the spam blocking maths question wrong which is a little worrying :-(
Posted by Rich G on June 28th, 2007.
Here’s a kludge for ’sort on load’:
<body onload=’loader();>
function loader()
{
if (!document.all)
{
var fireOnThis = document.getElementById(’TH id value’);
var evObj = document.createEvent(’MouseEvents’);
evObj.initEvent( ‘click’, true, true );
fireOnThis.dispatchEvent(evObj);
}
else
{
var fireOnThis = document.getElementById(’TH id value’);
fireOnThis.fireEvent(”onclick”);
}
}
now put some unique ‘id=’ value in the <th> element for the column that you want to have sorted when the page loads. This works with FF and IE7.
Posted by j on June 29th, 2007.
Great script! One question though.. Would it be possible to sort rows in pairs? Essentially, i have the following structure:
tr > td.price , td.date, td.blah
tr > td.description
.. repeat
Unfortunately I need two rows to fit all of the information about one product, but this creates a number of problems when trying to sort the table – namely, the second row gets all out of order, any ideas, suggestions?
Best,
Ilya
Posted by Ilya on July 1st, 2007.
Ilya: sorttable won’t do that; it’d need some fairly hefty modifications to the script, I’m afraid.
Posted by sil on July 1st, 2007.
Great great code! Many thanks!
Posted by Johnnie on July 1st, 2007.
I just added this script to my 3D game comparison table but the script seriously screws the table up. I’d like to be able to sort by game name (top row) and feature (first, middle, and last columns). Any ideas? The table is very complex with nested col/row spans.
Posted by http://eep2.vox.com/ on July 1st, 2007.
eep2: sorttable can’t handle tables with colspans or rowspans, because working out how to sort a table like that is pretty close to impossible without knowing the details of the table.
Posted by sil on July 1st, 2007.
Well, how else to know the details of the table than to analyze the table prior to sorting?
Posted by Eep² on July 1st, 2007.
perhaps the best way would be to rethink the table structure :-(
I’ve had a look at your page and it looks interesting but hard to follow from a first encounter (ie without knowing the background as to why you chose to do it that particular way)
How is your table populated? Manually or via a db?
Posted by Rich G on July 2nd, 2007.
Manually. I chose the layout (with the games across the top) because that reduces how much horizontal scrolling is necessary (since vertical scrolling is more common and easier). I tried to get it into a database but it’s just too complicated for me (not being much of a programmer)–check the main page and news/updates for more info. I’d be happy just to use a flat-file system with some kind of character-delimited list that PHP can sort and tabularize (allowing x games and x features/sections to be displayed only, etc), too.
Posted by Eep² on July 2nd, 2007.
Sorry, the introduction was unreadable for me due to the colour scheme and font size :-( (and that’s on a 24″ widescreen at 1920 x 1200)
Posted by Rich G on July 3rd, 2007.
Er, so increase the text size in your web browser and override the colors if you don’t like them…
Posted by Eep² on July 3rd, 2007.
Sorry, inaccessibility of content is one of my pet hates, if i can’t read it I’m already browsing away
Posted by Rich G on July 3rd, 2007.
just realised that sounded very critical of your site sorry, it wasn’t personal, I was just trying to explain why I rarely bother resetting my system to cope with a specific designers decision, have a look at sites such as http://www.csszengarden.com to see what clear and accessible design can achieve, its a good principle to design so that everyone can view your site rather than having to change their browser settings,
Posted by Rich G on July 3rd, 2007.
So where’s the option on that site to have a dark layout? I don’t like bright white–it hurts my eyes… If I knew how to set cookies and allow people to choose/design their own color scheme, I would, but I don’t.
Posted by Eep² on July 4th, 2007.
in the zen garden each scheme has a different layout but the same content (supplied by the site), its an exercise in separating style from content and allows you to see what layouts you like and what you don’t, you may well have a valid reason for choosing your scheme I was merely commenting that it’s very hard to read ;-)
You could use alternative stylesheets to have a selector for viewing your site as white on black or black on white for example or completely change the layout for people with rotated widescreen monitors, css is both fun and amazingly irritating to play with!
to get slightly back towards the original start of our discussion, you could make your table into xml and then style that using css thus making it easy to add new content (by changing the xml only) or new layouts (by changing the css only) it might conceivably help your sorting table layout issues too!
Hopefully I’m being slightly helpful and you don’t feel too criticised by my random thoughts ;-)
Posted by Rich G on July 4th, 2007.
test
Posted by Eep² on July 4th, 2007.
Dunno why my comments aren’t being posted (aside from short ones–assuming this one will work). This is the third time now…
Posted by Eep² on July 4th, 2007.
Need a way to edit/delete comments…
Posted by Eep² on July 4th, 2007.
Blah…my last comment didn’t show up, for some reason (maybe cuz I had “a href” HTML links in it. Anyway, I had the thought of doing CSS hiding via this script (minus the animation) but I’m not sure if it works with tables (without them having to be separate tables per game, which defeats the purpose of having multiple games in a single table to compare, in the first place).
Posted by Eep² on July 4th, 2007.
But then there’s this sortable table script which has a filter, which might be configurable as a checkbox above each column/game field (and perhaps even each row/feature) to hide/show it. I don’t know XML but maybe HTML+CSS+Javascript will suffice.
Posted by Eep² on July 4th, 2007.
Oh and there’s a stylesheet switcher that I’ll look into adding to my site(s).
Anyway, thanks for the replies.
(OK, one link per comment is stupid…)
Posted by Eep² on July 4th, 2007.
They got moderated, which is why they didn’t show up. The one-link-per-comment thing is Wordpress, not me specifically, but the huge majority of comments I get with more than one link in are spam…
Posted by sil on July 4th, 2007.
if you know the column class in a table you can hide the entire column and the same for rows so you could have a separate class for each game and switch them on or off as you like
Posted by Rich G on July 4th, 2007.
But is that only for columns that don’t span multiple rows (and vice versa)? Cuz, ideally, I’d like to consolidate cells that have the same content (developer, “yes”, “no”, etc)…
Posted by Eep² on July 5th, 2007.
I’m taking rubbish of course! there is no concept of a column in a html table definition, just rows and cells (hangs head in shame). Styling rows with a unique css class will allow easy turning on and off but doing this by hand will become a bit more tedious each time you add stuff and for columns like you have with multiple cell spanning, you would have to know something like each cell location in the parent row -> child cells tree and to find this you would have the same problem as what you have already encountered :-(
I think for a table like this it might be easier to have the duplication for the sake of easier coding as you would be able to rely on knowing the same number of cells per row etc.
I would do it in ASPX myself and so would avoid the problem entirely by generating the table on the fly each time things were clicked on but that might be using a sledgehammer to avoid the nut!
Hmm I might have just talked you back to where you were a few days ago :-( sorry!
Posted by Rich G on July 5th, 2007.
Of course there’s a column concept in HTML tables, otherwise there wouldn’t be a col element and colspan attribute, for one. For two, there’s a colgroup element. I don’t know ASPX (whatever that is) either. I’m looking into various content management systems but am not having much luck (trying Drupal right now–I’d post a link but stupid WordPress is too paranoid about “spam links” ). Anyway, I’m more informed than I was a few days ago but still pretty much stuck on what to do and how to implement it.
Posted by Eep² on July 5th, 2007.
I’ve learn’t something new too, never come across col attribute before, will have a play could be very useful!
ASPX is basically dynamic server side generated webpages ie you code how you want to generate the page and when the user browses to it the page is generated for them.
Posted by Rich G on July 5th, 2007.
Right…more coding…blech.
Posted by Eep² on July 5th, 2007.
you know you enjoy it really, join us on the dark side:
“Don’t be so proud of this technological terror you’ve created. The ability to destroy a planet is insignificant next to the power of the force.”
- Darth Vader
Posted by Rich G on July 5th, 2007.
Patch for stable sort :
sort_alpha: function(a,b) {
if (a[0]<b[0]) return -1;
if (a[0]>b[0]) return 1;
// when equals keep previous order (=row index)
if (a[1].rowIndex<b[1].rowIndex) return -1;
else return 1
}
Apply similar rule to sort_numeric, sort_ddmm, …
Posted by opus27 on July 6th, 2007.
Patch to show ’wait’ cursor while sorting :
Insert this :
dean_addEvent(headrow[i],”mouseover”, function(e) {
this.style.cursor=’pointer’;
});
dean_addEvent(headrow[i],”mousedown”, function(e) {
this.style.cursor=’wait’;
});
just before that :
dean_addEvent(headrow[i],”click”, function(e) {
…
});
and add this line :
this.style.cursor=’pointer’;
before each return
and after : delete row_array;
in the same function
Posted by opus27 on July 6th, 2007.
I need a patch to sort single-digit dates (days, months, and even years) correctly, and not always in DD/MM/YY format either but MM/DD/YY, MM/D/YY, MM/D/Y, M/D/Y, M/DD/Y, etc.
Posted by Eep² on August 31st, 2007.
opus, what is “stable sort”?
Posted by Eep² on August 31st, 2007.
Hello? Anyone? Beuler, Beuler?
Posted by Eep² on September 9th, 2007.
That’s “Bueller”. You might get a patch if you asked a touch more nicely about it…
Posted by sil on September 9th, 2007.
Uh, how much more nicely can I ask “what is ’stable sort’”? Geez…too many damn overhypersensitive people online–I fucking swear it’s ridiculous!
Posted by Eep² on September 10th, 2007.
The definition is a google search away. The sorttable page itself links to the Wikipedia description of stable sorting.
And I wasn’t talking about stable sorting, anyway, I was talking about you just saying “I need a patch to do X, Y, and Z”.
Posted by sil on September 10th, 2007.
Er, it’s not like I wrote “I demand a patch NOW!*($#” or something… I was being quite neutral about it, actually. Besides, why should I need to ask nicely for something that the script should already be able to do inherently? <buh-link> Anyway, stable sorting isn’t what I need…
Posted by Eep² on September 11th, 2007.
Single-digit date handling is on the list for sorttable v3.
Posted by sil on September 11th, 2007.
“Besides, why should I need to ask nicely for something that the script should already be able to do inherently?”
Well thats how to win friends!
“Anyway, stable sorting isn’t what I need…”
Nope, quite right, what you need is to look through the code and fix it then share the fix with everyone else.
Posted by Rich G on September 11th, 2007.
Wondering if anybody has used sortable with checkboxes. I have a table with a column of checkboxes and labels set to sorttable_nosort. If I sort the table, check some boxes and submit the form, all the form elements get passed except for the checked boxes. If I submit the form without sorting the table,everything works as expected.
Any ideas?
Posted by Mark G on September 13th, 2007.
Mark G: you’re not the first person to report this problem, but I’ve not been able to replicate it. Do you have a URL that demonstrates the problem? Which browser are you using?
Posted by sil on September 13th, 2007.
Mark G, All my table have checkboxes and work fine so I can’t say I’ve found a problem with it sorry :-(
Posted by Rich G on September 13th, 2007.
It’s an internal project so I don’t have a URL for you to look at.
I’ve been able to replicate the problem on Firefox and Opera. It works fine on Safari.
Thanks
Posted by Mark G on September 13th, 2007.
Thanks for the great script ! It help a lots.
I have a minor problem, my table with 3 header rows (i understand it doesn’t work for this version) so I decided to change the script. But afetr some hard works, :o( I am wondering will I be able to achieve it ?
I change like:
headrow = table.tHead.rows[table.tHead.rows.length - 1]
Posted by EngDian on September 19th, 2007.
(oops, sorry, haven’t finish my typing… )
and make changes to row_array (to make it start from table.tbody, not counting the header…)
Can I know am I in right direction ? or I am totally talking nonsense ?
Thanks.
Posted by EngDian on September 19th, 2007.
EngDian: that’s certainly one approach to take. I haven’t yet decided how best to make sorttable support multiple header rows, which is why sorttable doesn’t do it yet. It’s planned for version 3.
Posted by sil on September 19th, 2007.
Sortable and AJAX.NET both has an Array.forEach function it’s just that they do not work the same way.
To fix that just put a prefix before all the ForEach-functions in sorttable.js. Don’t forget to also change the
resolve.STforEach(object, block, context); // ST is the prefix
in the base forEach function.
ScottW has another solution above but I think this one might be simpler.
Posted by Jonas Elfström on September 25th, 2007.
Jonas: quite right, and added to the bug list.
Posted by sil on September 25th, 2007.
i would like to order the table by binding 2 row together
Posted by Anonymous on November 6th, 2007.
Is there a way to skip a column from sorting?
I have a first column with ranking (1 to whatever), and I want that to stay the same when sorting the table.
Posted by Ryan on January 3rd, 2008.
Ryan: I’m afraid not. This is a known bug, though; see http://kryogenix.org/bugs/sorttable/left-hand-headers.html for details.
Posted by sil on January 3rd, 2008.
Hi Stuart. Great code, very useful.
I’m running into a problem using your sorttable v2 with BarelyFitz’s Tabber.js (http://www.barelyfitz.com/projects/tabber/), such that when I include a sorttable table, all tabs vanish (standard tabs w/cookies). When I use sorttable v1, it works fine. While I realize that its likely to be much to ask, I was wondering if you had any suggestions? (I’ve tried the prefix fix mentioned above to no avail)
Also, does anyone have any advice for sorting a street address field, already merged into one field of Street # + Street Name? (where not all properties have a #?)
Thanks a lot!
Posted by josh on January 7th, 2008.
Sadly, sorttable doesn’t seem to work if your doctype is XHTML 1.0 versus HTML 4.01. If you do upgrade the library, let me know!
Posted by Kathy on January 11th, 2008.
Kathy: that’s not supposed to happen. Do you have an example of a page that it doesn’t work on, so I can test? Feel free to contact me by email if you prefer.
Posted by sil on January 11th, 2008.
josh: have you got a page that exhibits the problem, so I can take a look?
For sorting oddly-formatted fields, you’ll want to use sorttable’s custom sort keys.
Posted by sil on January 14th, 2008.
I spent some time searching for a solution to this until I came back and reread the whole thread. The bugfix link isn’t by the error message tha caused it.
sys.argumenttypeexception object of type object cannot be converted to type array
http://kryogenix.org/bugs/sorttable/foreach-collide.html
I fixed mine by doing a replace on forEach to STforEach
Posted by phillipW on January 17th, 2008.
Your script doesn’t work on IE7.
Great with FF2.
As an exemple, you tables on this page are not active with IE7 but are on FF2.
Chears,
Posted by Fabrice C on February 29th, 2008.
Fabrice: oops. Added to my bug list. Thanks.
Posted by sil on February 29th, 2008.
Thanks for the script. I use it at work for sorting off of an
Indexing Server with ASP. Is there any way to manipulate the script to allow for date modified? Since this is a search I cant simply alter the cell. I need to sort in the format
mm/dd/yyyy HH:MM:SS AM/PM
Thanks again for sharing this great script!
Posted by Jared on March 3rd, 2008.
Jared: if you can’t use custom keys, then the script will need to be modified, as you mention. It can be done; you’ll need to edit the date-parsing functions and the date regular expression. If you want me to do it, contact me and we can talk about rates and so on.
Posted by sil on March 3rd, 2008.
Here is a patch to make the sort stable.
The modification is to set id to the original row index and sort by row.id when rows are equal (one drawback is that existing id:s on tr-elements are removed).
The added code starts with ”+”:
forEach(document.getElementsByTagName(’table’), function(table) {
if (table.className.search(/\bsortable\b/) != -1) {
sorttable.makeSortable(table);
+ if (table.className.search(/\bstablesort\b/) != -1)
+ sorttable.setrowids(table);
}
});
},
+ setrowids: function(table) {
+ // Set id=rownumber, makes the sorting stable with the help of sort_by_id
+ sortfn = sorttable.sort_alpha;
+ for (var i=0; i<table.tBodies[0].rows.length; i++)
+ table.tBodies[0].rows[i].id = i+100000;
+ },
+ sort_by_id: function(a,b) {
+ if (a[1].id==b[1].id) return 0;
+ if (a[1].id<b[1].id) return -1;
+ return 1;
+ },
sort_numeric: function(a,b) {
aa = parseFloat(a[0].replace(/[^0-9.-]/g,”));
if (isNaN(aa)) aa = 0;
bb = parseFloat(b[0].replace(/[^0-9.-]/g,”));
if (isNaN(bb)) bb = 0;
+ if (aa==bb)
+ return sorttable.sort_by_id(a,b);
+ else
return aa-bb;
},
sort_alpha: function(a,b) {
if (a[0]==b[0])
+ return sorttable.sort_by_id(a,b);
if (a[0]<b[0]) return -1;
return 1;
},
sort_ddmm and sort_mmdd:
+ if (dt1==dt2) return sorttable.sort_by_id(a,b);
Posted by Niklas on March 10th, 2008.
Niklas: what was wrong with http://www.kryogenix.org/code/browser/sorttable/#stablesort ?
Posted by sil on March 10th, 2008.
I sent you an email as requested about sorting mm/dd/yyyy hh:mm:ss AM/PM but I never heard back from you. Just wanted to make sure you got the message?
Posted by Jared on March 11th, 2008.
Jared: sorry, replied now!
Posted by sil on March 11th, 2008.
> Niklas: what was wrong with http://www.kryogenix.org/code/browser/sorttable/#stablesort ?
Differences:
shaker_sort:
* Uses custom sort function
* multi-level sorting of data (when two rows are equal the previous sort order is used)
My patch:
* Uses JavaScript sort (sorting should be faster, but initial setup is slower)
* When two rows are equal the original order is used
* If you sort with sort_by_id, or on a column with all the same values, the result is the original order.
So you could quite easily add a third state when clicking a third time on the column header – unsorted (i.e. remove the arrow and sort with sort_by_id)
Note:
To make my patch behave like shaker_sort (general way of making any sort stable):
1. skip setrowids (not needed)
2. add j as the third element in row_array
for (var j=0; j<rows.length; j++)
row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j], j];
3. Modify the sort_by_id function (or replace all “sort_by_id” with “a[2] – b[2]“):
sort_by_id: function(a,b) {
return a[2] – b[2];
},
4. Use row_array.sort(this.sorttable_sortfunction); as normal
Should give the same result (not tested though).
Posted by Niklas on March 13th, 2008.
hi great script!!
i need to know how to do this:
I have one column that I don’t want to be sorted at all, how do I do that? Thanks in advance!
Posted by lau on March 24th, 2008.
lau: see the documentation.
Posted by sil on March 24th, 2008.
Hi, just updated to v2. The speed increase is excellent.
is there any documentation on any additional css stuff to interact with sortable.. I was thinking along the lines of a:hover.sortable but cant get anything to work.
in v1 when you would hover over the heading the pointer would change… in v2 it doesn’t & it shows no obvious signs of being a “link” or sortable, or do I have mine incorrectly setup?
many thanks
Posted by gee on March 31st, 2008.
gee: to style links in a sortable table, you want
table.sortable a { styles }
and to style your headers, use
table.sortable th { cursor: hand; }
Posted by sil on March 31st, 2008.
Hi,
Many thanks for the response.. I think I worded the question badly but it gave me some ideas for future use.
just to check did you mean
table.sortable thead {}
rather than
table.sortable th {}
as I can’t get anything out of th
….
what I have done though is this
table.sortable thead {
padding:3px;
background-color:#52418C;
color:white;
font-weight: bold;
text-decoration: none;
height: 12.75pt;
}
table.sortable thead:hover {
text-decoration: underline;
background:#A5DD29;
cursor: pointer;
}
note pointer rather than hand as I found out hand don’t work in ff
what happens isn’t exactly what I’d expect in that when you hover over one header cell is the whole header row changes colour & underlines… which makes me think I’ve got something wrong & it’s where ’th’ comes in?
off to research css a bit more, but any pointers much appreciated.
Posted by gee on April 1st, 2008.
doh… th won’t work unless you use <th></th>
Posted by gee on April 1st, 2008.
gee: ah, yeah, you should be using th inside a thead :)
Posted by sil on April 1st, 2008.
Awesome script!! It works in IE7 with Tabber.js (which Josh reported) for me.
I have a display problem however. When the column header string is shorter than its values in tbody, adding the unicode triangle when sorting on the header works great. See example below.
Name
Employee A
Employee B
But when the column header string is longer than any of its text in tbody, the added triangle increases the th length and messes up my table format. The right table border is gone, and the tbody formatting (background color) doesn’t apply to the increased thead/th length. For example,
Name
A
B
Can you give me some tips on how to work around this?
Thanks!!!
Posted by Hana on April 10th, 2008.
Hi, thanks for this script !
I use striped-tables, and I see that is in the wish list.
As I did not want to wait, I have to add this to script :
1/ a new function
striped: function(table){
for (var i=0; i<table.tBodies[0].rows.length; i++) {
table.tBodies[0].rows[i].style.backgroundColor=(i%2==0)?table.getAttribute(’R1BgColor’):table.getAttribute(’R2BgColor’);
}
},
2/ I call it in init just before makeSortable
…
sorttable.striped(table);
sorttable.makeSortable(table);
…
3/Another call before sort function
…
delete row_array;
sorttable.striped(this.sorttable_tbody.parentNode);
…
4/ I add two attributes to the table
Note: Class instead og Bgcolor would be better, I think.
What are you thinking about this ?
Posted by Martial on May 3rd, 2008.
Martial: that’s certainly a good way to solve your specific problem, and I’m glad sorttable could help you!
Posted by sil on May 3rd, 2008.
[...] have a sortable sub folder structure and sortable images per folder. Searching the web, I found an excellent javascript solution for sorting tables. The script works very well and I have adapted it for use in the Lazyest Gallery Manage page with [...]
Posted by Brimosoft » Blog Archive » Sortable Tables on May 9th, 2008.
Is there any “onsorted” event that gets fired after a sort is complete? If not, any recommendation on how to add support for that? I need to make an Ajax call after a sort to store the new order on the server. I’m thinking it would be most convenient if I could just add an onsorted=”myjsfunc();” to the table.
Thanks,
Russ
Posted by Russ on May 30th, 2008.
Thanx,
It is a beautiful script works like charm in my scripts without much changes
Posted by Maneesh on June 2nd, 2008.
hey…
i am trying to get sortable to work for textbox inputs…the values are entered dynamically each time for some further validations… the text i am entering is of a certain format eg. ‘PP_VER-RE_908′ the innerText code in the sorttable.js considers this as numeric…after that it just inverts the rows in the table…sort doesnt happen..any suggestions???
Posted by Vinnie on June 4th, 2008.
Vinnie: what you’re talking about will, I think, require some custom (thus paid-for) enhancements to sorttable. Drop me an email (http;//www.kryogenix.org/contact) and we can talk about it.
Posted by sil on June 4th, 2008.
i need to know how to do this:
I have one line not a column that I don’t want to be sorted at all (some ads), how do I do that? Thanks in advance!
Posted by bastien on June 17th, 2008.
Bastien: if you mean that you’d like that column to stay in the same order even if the rest of the table is sorted, then that’s http://www.kryogenix.org/bugs/sorttable/left-hand-headers.html which is a known request for enhancement. I’m not sure when I’ll have time to get to it, though. (You can get it up my list with money: see http://www.kryogenix.org/code/browser/sorttable/#payforwork for details :))
Posted by sil on June 17th, 2008.
Oh my God! I can’t believe it! All that functionality and it took me 5 seconds to drop it in and it just works! AWESOME!!! You just saved me a ton of time in dinking with database query strings.. You are the man! THANK YOU!!!
-Hatch in Costa Rica…
Posted by Hatch on June 20th, 2008.
Hatch: no problem Glad you liked the script. :)
Posted by sil on June 20th, 2008.
It seems I ran into a bug with the date format dd.mm.yy. At least the sorting does not work properly and I cannot figure out why. It sorts in a very weird way.
You can see it at http://www.quaddicted.com/spmaps.html
The script seems to loaded right as sorting the other columns works fine.
Unfortunately I am rather “code-blind” so I can’t see why it does work so wrongly. Tried Firefox 2.0.0.14 and Opera.
Posted by Hannes on June 20th, 2008.
I love it, it’s da bomb.
Is there any way to sort an image column? No, I don’t mean sort them by what they contain (!), just if there’s an icon there or not. For instance, if there’s a star for “Featured” something or other, and a camera icon for “Has a Photo”, etc. it would be nice to be able to just bring all these to the top.
I know, I know, give ‘em an inch… ;^)
Posted by Table Sorta Guy on June 28th, 2008.
ps: I mean besides inserting a number “1″ in front of the icons and giving them a css font size of 1 and a color the same as the background ;^) Because that works! (but it’s a little wacked)…
Posted by Table Sorta Guy on June 29th, 2008.
Table Sorta Guy: add a custom sort key of 1 or 0 to the cells in question. See http://kryogenix.org/code/browser/sorttable/#customkeys for details.
Posted by sil on June 29th, 2008.
Awesome! Thank you !!!
Posted by Table Sorta Guy on June 29th, 2008.
whatever
Posted by Sandy on July 3rd, 2008.
I love this script, however, I have a checkbox that allows one to select certain records for processing via a post of the form information.
I am trying to add an option to select or unselect all but I would like the select or unselect to select or unselect only visible rows, not all rows.
Is there any easy way to do this that anyone knows of?
Posted by Stephanie on July 25th, 2008.
Stephanie: I’m not sure what you mean by “visible” rows? Sorttable doesn’t make rows visible or invisible.
Posted by sil on July 31st, 2008.
Hi, more stuff:
<pre>
* Sort detect empty as lowest ”value”
</pre>
Great job - rgds. Henrik at Lassen dot dk
Solutions proposed
==================
<pre>
//* Sort detect empty as lowest ”value”
sort_numeric: function(a,b) {
aa = parseFloat(a[0].replace(/[^0-9.-]/g,”"));
bb = parseFloat(b[0].replace(/[^0-9.-]/g,”"));
return sorttable.sort_NaN(aa) - sorttable.sort_NaN(bb);
},
</pre>
Posted by Henrik on August 11th, 2008.
Hi, here is what i am looking for (resend):
* Embed script (One page HTML)
* Sort detect IP addresses
Great job - great speed - rgds. Henrik at Lassen dot dk
PS. Never understod the difference between ”Submit comment” and ”Post comment”
Solutions proposed
==================
//Embed script: Use double qoutes
//Sort detect IP addresses
if (text != ”") {
if (text.match(/^(\d{1,3}\.){3}\d{1,3}$/)) return sorttable.sort_ip;
if (text.match(/^-?[£$¤]?[\d,.]+%?$/ )) return sorttable.sort_numeric;
…
sort_ip: function(a,b) { // Rgds HL
aa = a[0].split(”.”); aaa = 0; for(i in aa) aaa = aaa*256+parseInt(aa[i]);
bb = b[0].split(”.”); bbb = 0; for(i in bb) bbb = bbb*256+parseInt(bb[i]);
return sorttable.sort_NaN(aaa) - sorttable.sort_NaN(bbb);
},
sort_NaN: function (a) {
if (isNaN(a)) return -Number.MAX_VALUE; return a;
},
Posted by Henrik on August 11th, 2008.
I just wanted to submit my tweak to enable the correct sorting of negative numbers that are denoted by enclosing them in parenthesis like (10.39) = -10.39
What I do is have it replace the opening parenth with a negative sign before stripping all other non-number chars. That way it retains the negative and sorts in true numeric rather than as an absolute value when using parenths.
sort_numeric: function(a,b) {
aa = parseFloat(a[0].replace(/\(/g,’-').replace(/[^0-9.-]/g,”));
if (isNaN(aa)) aa = 0;
bb = parseFloat(b[0].replace(/\(/g,’-').replace(/[^0-9.-]/g,”));
if (isNaN(bb)) bb = 0;
return aa-bb;
}
Posted by Scott Jilek on October 27th, 2008.
Is there an equivalent to “sortbottom” that will keep a row at the top? (e.g. “sorttop”)
Thanks.
Posted by Jason on November 5th, 2008.
Jason: I’m afraid not. You’d need to make a custom enhancement to sorttable to do that (or talk to me about rates for custom JavaScript work by dropping me a mail).
Posted by sil on November 6th, 2008.
Hey! I’ve implemented this script but am having trouble getting it to work.
http://phpfi.com/384613
is my code,
When I click on the header column titles an arrow comes, and if I repeatedly click it the arrow points up / down, but the column isnt actually sorting.. any idea why?
Posted by kris on December 12th, 2008.
Here’s a complete solution for the empty cell problem with dates. Thanks to Erich Bakx!
Just add a check for each mtch-variable. After doing this it should look like the following code:
sort_ddmm: function(a,b) {
mtch = a[0].match(sorttable.DATE_RE);
if(mtch==null) dt1=0;
else {
y = mtch[3]; m = mtch[2]; d = mtch[1];
if (m.length == 1) m = ’0′+m;
if (d.length == 1) d = ’0′+d;
dt1 = y+m+d;
}
mtch = b[0].match(sorttable.DATE_RE);
if(mtch==null) dt2=0;
else {
y = mtch[3]; m = mtch[2]; d = mtch[1];
if (m.length == 1) m = ’0′+m;
if (d.length == 1) d = ’0′+d;
dt2 = y+m+d;
}
if (dt1==dt2) return 0;
if (dt1<dt2) return -1;
return 1;
},
sort_mmdd: function(a,b) {
mtch = a[0].match(sorttable.DATE_RE);
if(mtch==null) dt1=0;
else {
y = mtch[3]; d = mtch[2]; m = mtch[1];
if (m.length == 1) m = ’0′+m;
if (d.length == 1) d = ’0′+d;
dt1 = y+m+d;
}
mtch = b[0].match(sorttable.DATE_RE);
if(mtch==null) dt2=0;
else {
y = mtch[3]; d = mtch[2]; m = mtch[1];
if (m.length == 1) m = ’0′+m;
if (d.length == 1) d = ’0′+d;
dt2 = y+m+d;
}
if (dt1==dt2) return 0;
if (dt1<dt2) return -1;
return 1;
},
Now the sort-functionality also works with dates and empty cells.
Posted by Tobias on December 18th, 2008.
I just came across the bug with https as described earlier. I tried the solution:
A fix is to replace this line:
document.write(””);
With:
document.write(””);
but although the page loads securely – the table doesn’t sort any more!
Am I missing something?
Posted by Philip on January 6th, 2009.
while doing the following perl ( very parred down example to save space )
#!/usr/bin/perl
use CGI qw(:standard);
$sy = 2009 ;
$sm = ‘02′;
$sd = 13 ;
$st = ‘CIMIS’ ;
print header;
print start_html(-title=>”WeatherTRAK Climate Database Output”, -script=>{-src=>”sorttable.js”} );
print ”;
print “”;
open(OUT, “/data/www/pgm-bin/ete_rpt $sy$sm$sd $st |”);
while()
{
print $_;
}
close OUT;
exit;
I GET THE FOLLOWING ERROR
[Thu Feb 19 03:01:17 2009] [error] [client 10.0.0.8] (8)Exec format error: exec of ‘/var/www/cgi-bin/sorttable.js’ failed, referer: http://10.0.0.240/cgi-bin/d1.psql
[Thu Feb 19 03:01:17 2009] [error] [client 10.0.0.8] Premature end of script headers: sorttable.js, referer: http://10.0.0.240/cgi-bin/d1.psql
yet if I redirect the perl to a file wiht the > and then use the web browser on that file it always works..
IDEAS PLEASE ??
Posted by DanD on February 19th, 2009.
DanD: you have sorttable.js in your cgi-bin folder, and Apache is therefore trying to execute it as a CGI, which doesn’t work. MOve it somewhere else.
Posted by sil on February 20th, 2009.
Hi there, great script works like a bomb. I was wondering how I can set the alternating row colors with sorttable. Is there a simple way to do this. thanks
Posted by Articfox on February 23rd, 2009.
Articfox: currently there isn’t. This is a known issue (http://www.kryogenix.org/bugs/sorttable/striped-tables.html). If you’re interested in having it fixed and want to pay me to do it, drop me a line. :)
Posted by sil on February 23rd, 2009.
Hi there, this is a really great script. I just had one uestion if i have alternating row colors how can i get them to stay alternating with this script cause mine colors stay with the sorteed data and the row colors get mixed up
Posted by Articfox on February 23rd, 2009.
Hello,
For the alternating table row styles, I copied the code provided by Johnny Moon as such:
above tb.appendChild(row_array[j][1]); (within the for loop) I placed:
tb.appendChild(row_array[j][1]);
above tbody.appendChild(newrows[i]); (within the for loop) I placed (tweaked from Rich G):
if(i % 2) { if(newrows.length % 2) //odd number of rows so start with tRowB newrows[i].className = (’tRowB’); else newrows[i].className = (’tRowA’); } else { if(newrows.length % 2) //odd number of rows so start with tRowA newrows[i].className = (’tRowA’); else newrows[i].className = (’tRowB’); }
This made the table sort not work for me. Did I do this correctly?
Posted by Barbara on February 27th, 2009.
Oop….correction to the above comment:
above tb.appendChild(row_array[j][1]); (within the for loop) I placed:
if(j % 2)
row_array[j][1].className = “tRowA”;
else
row_array[j][1].className = “tRowB”;
above tbody.appendChild(newrows[i]); (within the for loop) I placed (tweaked from Rich G):
if(i % 2)
{
if(newrows.length % 2) //odd number of rows so start with tRowB newrows[i].className = (’tRowB’);
else
newrows[i].className = (’tRowA’);
}
else
{ if(newrows.length % 2) //odd number of rows so start with tRowA newrows[i].className = (’tRowA’);
else
newrows[i].className = (’tRowB’);
}
Posted by Barbara on February 27th, 2009.
I trimmed down the fix to make alternating row styles down to a single added line (prefixed with + below). Hopefully this doesn’t get reformatted too much.
tb = this.sorttable_tbody;
for (var j=0; j<row_array.length; j++) {
+ row_array[j][1].className = j%2 ? “oddrow” : “evenrow”;
tb.appendChild(row_array[j][1]);
}
Posted by Tom Brown on March 4th, 2009.
You have reinforced my faith in human good nature (and skill). Thank you so much for putting your wonderful work in the public domain. It has saved me literally hours of menial work… and I probably would have indeed used a querystring and another call to SQL to generate a far less elegant solution to my problem.
Actually, that would have been difficult because some of the columns were being generated from results from previous columns (which came from various sql tables, some incomplete)…
Dude, you are a legend!
Posted by Andrew Hood on March 4th, 2009.
Hello,
Are you planning to include fix suggested by ScottW that prevents script working with asp.net ajax. I did and it looks like working.
You would save some time to others.
Thanks,
Velja Radenkovic
Posted by Velja Radenkovic on March 6th, 2009.
Velja: I can’t test that the fix works. I’m loath to include a fix that I myself haven’t tested. Besides, it’s in my bug list, which means it’s on my radar to fix.
Posted by sil on March 6th, 2009.
sil,
You can’t test it? Yes you can. The fix is to replace foreach iteration with plain for loop and access the element of array using index.
When I think better I think the problem is not in foreach iteration implementation but rather in ‘table’, ‘cell’ etc. variable names. Replacing iteration solved the problem because it eliminates variable named ‘table’ from js and uses tables[i] instead which is not in collision with asp.net ajax scripts.
Generally speaking using table, cell, layer and similar as variable names is always bad idea in java script because it doesn’t have namespaces or packages or any other method of code separation.
I have my piece of code working so don’t understand that I am pushing you because I need something. Its a good script and it works flawlessly with asp.net GridView. It would be a pity to discourage people from using it because of minor problem.
Also alternating row colors is common thing in html tables and script doesn’t take care of that. That can be fixed easily too.
Thanks,
Velja
Posted by Velja Radenkovic on March 8th, 2009.
Velja: no, no, I meant that I can’t test that it no longer breaks ASP.NET because I can’t run any ASP.NET sites.
The whole forEach implementation is going away in sorttable v3 anyway.
Posted by sil on March 8th, 2009.
Simply great script, and very useful. Used it for a company in an effort to minimize load on servers where tables where retrieved and likely to be sorted on different fields. One modification I made to the script though, I will suggest. This minor mod has worked quite well and have found no errors yet. Since I live in Iceland and our character set is a bit different, e.g. we have letters like ‘á’, ‘ð’,'þ’ and script did not give correct results. So what I tried is this with the sort_alpha method:
sort_alpha: function(a,b) {
a[0]=a[0].toLowerCase();b[0]=b[0].toLowerCase();
var regexp=/á/g;var regexp2=/ð/g;var regexp3=/é/g;var regexp4=/í/g;
var regexp5=/ó/g;var regexp6=/ú/g;var regexp7=/ý/g;var regexp8=/æ/g;var regexp9=/ö/g;
var regArray=new Array([regexp,'a{'],[regexp2,'d}'],[regexp3,'e~'],
[regexp4,'i~'],[regexp5,'o¡'],[regexp6,'u¢'],[regexp7,'y£'],
[regexp8,'þ¤'],[regexp9,'þ¥']);
for ( var i=0; i<regArray.length; i++)
{
a[0]=a[0].replace(regArray[i][0],regArray[i][1]);
b[0]=b[0].replace(regArray[i][0],regArray[i][1]);
}
if (a[0]==b[0]) return 0;
if (a[0]<b[0]) return -1;
return 1;
},
Also I made an extra function to sort the names since they are sorted by the first name and last, anything in between is less important. Like to hear what you think and any comments are appreciated. In all, great script that works well, thanks Stuart.
Posted by Max on March 14th, 2009.
OOps, sorry! I forgot to explain the idea. The ‘unique’ characters were replaced with others, e.g. ‘¤’ that are not likely to be part of any name. Then finally, is the sort used.
Posted by Max on March 14th, 2009.
Max: the best way to do that is to use localeCompare, as described in the outstanding bug report http://www.kryogenix.org/bugs/sorttable/non-english-chars.html which I plan to implement in sorttable v3.
Posted by sil on March 14th, 2009.
Ok. I did not know about this bug report. Thanks, you were quick with answers!
Posted by Max on March 15th, 2009.
[Tried emailing Stuart to no effect; here is the message]
I have used your sorttable scripts on sites that I design and develop for The Nature Conservancy to good effect, and I thank you for making them available.
In redoing one site, I have run into a problem in IE (6 and 7) on WinXP. I have not tested in Vista. This problem does *not* occur in FF or Safari or Google Chrome.
In this new version, I have wrapped my sortable in a tag whose display is alternately “none” or “block” (Close/Open), controlled by another script. This does not affect the sort function in any browser or system besides IE. I have tested it now with the simplest possible show/hide script directly in the file head
, with no luck, but I have the following observation (I think):
(1) When I load the page into a new tab in IE, and Open the table, it does NOT sort
(2) when I click on another page, then return to my page and Open the table, it DOES sort
(3) Opening and Closing the table without reloading does not change the sortability
(4) When I Reload the page without going elsewhere and returning, and Open the table, it does NOT sort
[test and live site URLs deleted; please email me]
Thanks for any help. I have several tables of this type.
Posted by SusanB on March 16th, 2009.
Great scripts. I got one problem. When my table uses and to specify the column widths, the sorting becomes very slow for a table with 600 rows. It is like 10 seconds vs. 2 seconds without colgroup.
Can you shed some light if this is solvable?
Thanks!
Posted by Henry j. on March 25th, 2009.
(Sorry to post again. HTML tags in my previous post have been removed by the page)
Great scripts. I got one problem. When my table uses tags “colgroup” and “col width=xx” to specify column widths, the sorting becomes very slow for a table with 600 rows. It is like 10 seconds vs. 2 seconds without colgroup.
Can you shed some light if this is solvable?
Thanks!
Posted by Henry j. on March 25th, 2009.
Henry: cor, I’ve never tried that. Can you drop me a mail with more details and (ideally) a URL to an example?
Posted by sil on March 27th, 2009.
Wonderful scripts. It’s really helpful. I have one concern, I made a table inside a div that when query reaches 20 items, the div scrolls. But I want the table header to be excluded from the scrolling part so when the user scrolls down to the last item, the table head would still remain on top, that way the sorting would still be visible. How do i do that with your script?
Thanks!
Posted by Ryan on April 15th, 2009.
Ryan: you should investigate http://www.imaputz.com/cssStuff/bigFourVersion.html.
Posted by sil on April 15th, 2009.
I made it! thanks…
Posted by Ryan on April 15th, 2009.
This is a great script! Very usable.
FYI.
I discovered that IE 6 & 7 does not like this script under SSL though. It complains that there are insecure items when using it.
I have recently discovered that there is some detection of removeChild() as being erroneously detected as “unsafe”, but by replacing those with outerHTML=” it still detects this script as insecure.
If anyone solves this issue (other than using a different browser ;) )
Posted by Crispy on April 30th, 2009.
Crispy: see http://www.kryogenix.org/bugs/sorttable/https-secure-content.html for a record of this bug and a possible workaround.
Posted by sil on April 30th, 2009.
Hi,
Is it possible to make the small hand symbol appear each time we roll the mouse over the headers. Makes it more intuitive.
Thanks! and great code !
Posted by Seb on May 6th, 2009.
Seb:
table.sortable th { cursor: hand; }
in your CSS file.
Posted by sil on May 6th, 2009.
I was having a problem with IE7 on an XP machine. When the table headers were clicked to sort the rows, the entire table would disappear. In order to fix this problem I changed the behavior of sorttable.js to copy the table rows instead of reference the existing rows. Sorttable is great. I especially like the version 2 options to not sort some rows, and the custom sort keys.
Here is the function to copy the rows.
,
copyTableRow: function(tableRow) {
var tr = document.createElement(’tr’);
columns = tableRow.getElementsByTagName(’td’);
for (var i=0; i<columns.length; i++) {
var td = document.createElement(’td’);
td.innerHTML = columns[i].innerHTML;
if (columns[i].getAttribute(”sorttable_customkey”) != null) {
td.setAttribute(”sorttable_customkey”,columns[i].getAttribute(”sorttable_customkey”));
}
tr.appendChild(td);
}
return tr;
}
——
I added it to the makeSortable function and reverse function…
(In makeSortable, just before the shakersort option)
for (var j=0; j<rows.length; j++) {
var tr = sorttable.copyTableRow(rows[j]);
row_array[j] = [sorttable.getInnerText(rows[j].cells[col]), tr];
}
(and the beginning of the amended reverse function)
reverse: function(tbody) {
// reverse the rows in a tbody
newrows = [];
for (var i=0; i<tbody.rows.length; i++) {
newrows[newrows.length] = sorttable.copyTableRow(tbody.rows[i]);
}
Posted by Greg Kontos on June 15th, 2009.
Any release date for Version 3 ?
I’m sure it’s been suggested, but sorting by multiple columns would be very useful.
My company would pay $$$ for Version 3, since it is the least process intensive script for sorting we have come accross.
Cheers once again for the great work
Mick
Posted by Mick on June 16th, 2009.
Mick: I’d be happy to talk about custom paid enhancements to sorttable; those custom enhancements can go into sorttable v3, certainly. Do please drop me a line (http://www.kryogenix.org/contact) to talk about the enhancements you’d like!
Posted by sil on June 16th, 2009.