This is as days pass by, by Stuart Langridge

And this is Sorttable v2: making your tables even more sortable, written , and concerning JavaScript and the DOM, Howtos

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.

Comments

dsas

Oh..you're where I got that code from. Thanks!

sil

dsas: no problem. :)

margiex

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

sil

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.

mrben

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 ;)

sil

mrben: daresay it would, but that would mean caching the table structure, which I'd like to avoid :) If you want that, hit refresh.

mrben

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?

sil

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.

mrben

Ah. Point taken. Shame ;)

sil

mrben: hence "hit refresh" to get that order back.

log @ Make Data Make Sense » Sortable Tables with Totals and Averages

[...] 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 [...]

tommie

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.

sil

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").

Anonymous Coward

In Netscape 8 this script close the window. There is a solution for this?

GaryF

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.

ScottW

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

ScottW

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.

ScottW

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

ScottW

Change 1

var tables = document.getElementsByTagName("table");

for (var i=0; i

ScottW

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

sil

GaryF: that's what it's for. :)

sil

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.)

robert Lee

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

Varun

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)

robert Lee

To Varun:

I have used sorttable.js. it does indeed work in IE.

Jason Friesen

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!

sil

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.

Jason Friesen

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. :)

Varun

I was wondering if there is any way to have the table sorted (instead of default) onload

Rhonda

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!

sil

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.

Jason Friesen

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;';

Jason Friesen

(please note that I added spaces to the above comment; they shouldn't be included in the original js, of course.)

Jai

How can i get default sort on particular column on page load?

Mike

Is there a quick way to change the color of the column that you are sorting?

This would be very usefull for big tables.

Scott

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.

sil

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.

Scott

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.

sil

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.

jimbo

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.

sil

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 ;-)

jimbo

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...

j

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.

Erich Bakx

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

Mike

Is there a quick way to change the color of the column that you are sorting?

This would be very usefull for big tables.

Sydney

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

Carlos

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

Johnny Moon

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.

Max

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...

Rich G

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

Rich G

submission seems to have shredded part of the post

order is A1 then B1/2/3 then A1 = Error

Matt H

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));

Rich G

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!

sil

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.

Matt H

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!

Rich G

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 ? '&nbsp<font face="webdings">5</font>' : '&nbsp;▴';

            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 ? '&nbsp<font face="webdings">6</font>' : '&nbsp;▾';

            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 ? '&nbsp<font face="webdings">6</font>' : '&nbsp;▾';

          this.appendChild(sortfwdind);

Rich G

just realised that the last

sortfwdind.id = ”sorttable_sortfwdind”;

should have been commented out

Rich G

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]);

Matt H

Thanks Rich G!

Alex

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

Rich G

Ah thanks Alex I ran into that one last night and was about to look for a solution today and hey presto...

Jett

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.

sil

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.

Mike

In V2, how do I change the initial defualt sort direction from ascending to descending?

Thanks!

sil

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.

mike

Beautiful! That did work! Thank you very much for all the help, you do excellent work!

Mike

Dan

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

mark

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

Rich G

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

mark

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!

Rich G

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 :-(

j

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.

Ilya

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

sil

Ilya: sorttable won't do that; it'd need some fairly hefty modifications to the script, I'm afraid.

Johnnie

Great great code! Many thanks!

http://eep2.vox.com/

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.

sil

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.

Eep²

Well, how else to know the details of the table than to analyze the table prior to sorting?

Rich G

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?

Eep²

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.

Rich G

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)

Eep²

Er, so increase the text size in your web browser and override the colors if you don't like them...

Rich G

Sorry, inaccessibility of content is one of my pet hates, if i can't read it I'm already browsing away

Rich G

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 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,

Eep²

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.

Rich G

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 ;-)

Eep²

test

Eep²

Dunno why my comments aren't being posted (aside from short ones--assuming this one will work). This is the third time now...

Eep²

Need a way to edit/delete comments...

Eep²

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).

Eep²

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.

Eep²

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...)

sil

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...

Rich G

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

Eep²

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)...

Rich G

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!

Eep²

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.

Rich G

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.

Eep²

Right...more coding...blech.

Rich G

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

opus27

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, ...

opus27

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

Eep²

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.

Eep²

opus, what is "stable sort"?

Eep²

Hello? Anyone? Beuler, Beuler?

sil

That's "Bueller". You might get a patch if you asked a touch more nicely about it...

Eep²

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!

sil

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".

Eep²

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...

sil

Single-digit date handling is on the list for sorttable v3.

Rich G

"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.

Mark G

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?

sil

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?

Rich G

Mark G, All my table have checkboxes and work fine so I can't say I've found a problem with it sorry :-(

Mark G

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

EngDian

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]

EngDian

(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.

sil

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.

Jonas Elfström

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.

Anonymous Coward

i would like to order the table by binding 2 row together

Ryan

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.

sil

Ryan: I'm afraid not. This is a known bug, though; see http://kryogenix.org/bugs/sorttable/left-hand-headers.html for details.

josh

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!

Kathy

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!

sil

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.

sil

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.

phillipW

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

Fabrice C

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,

sil

Fabrice: oops. Added to my bug list. Thanks.

Jared

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!

sil

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.

Niklas

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);

sil

Niklas: what was wrong with http://www.kryogenix.org/code/browser/sorttable/#stablesort ?

Jared

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?

sil

Jared: sorry, replied now!

Niklas

> 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).

lau

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!

gee

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

sil

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; }


gee

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.

gee

doh... th won't work unless you use <th></th>

sil

gee: ah, yeah, you should be using th inside a thead :)

Hana

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!!!

Martial

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 ?

sil

Martial: that's certainly a good way to solve your specific problem, and I'm glad sorttable could help you!

Brimosoft » Blog Archive » Sortable Tables

[...] 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 [...]

Russ

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

Maneesh

Thanx,

It is a beautiful script works like charm in my scripts without much changes

Vinnie

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???

sil

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.

bastien

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!

sil

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 :))

Hatch

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...

sil

Hatch: no problem Glad you liked the script. :)

Hannes

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.

Table Sorta Guy

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... ;^)

Table Sorta Guy

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)...

sil

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.

Table Sorta Guy

Awesome! Thank you !!!

Sandy

whatever

Stephanie

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?

sil

Stephanie: I'm not sure what you mean by "visible" rows? Sorttable doesn't make rows visible or invisible.

Henrik

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>

Henrik

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;

  },

Scott Jilek

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;

  }

Jason

Is there an equivalent to "sortbottom" that will keep a row at the top? (e.g. "sorttop")

Thanks.

sil

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).

kris

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?

Tobias

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.

Philip

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?

DanD

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 ??

sil

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.

Articfox

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

sil

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. :)

Articfox

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

Barbara

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?

Barbara

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’);


}


Tom Brown

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]);

}

Andrew Hood

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!

Velja Radenkovic

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

sil

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.

Velja Radenkovic

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

sil

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.

Max

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.

Max

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.

sil

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.

Max

Ok. I did not know about this bug report. Thanks, you were quick with answers!

SusanB

[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.

Henry j.

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!

Henry j.

(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!

sil

Henry: cor, I've never tried that. Can you drop me a mail with more details and (ideally) a URL to an example?

Ryan

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!

sil

Ryan: you should investigate http://www.imaputz.com/cssStuff/bigFourVersion.html.

Ryan

I made it! thanks...

Crispy

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 ;) )

sil

Crispy: see http://www.kryogenix.org/bugs/sorttable/https-secure-content.html for a record of this bug and a possible workaround.

Seb

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 !

sil

Seb:

table.sortable th { cursor: hand; }

in your CSS file.

Greg Kontos

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]);

}

Mick

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

sil

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!

Yura

No matter how great is `sorttable`, it doesn't work in IE7/IE8.

When moving site from one 'IE security zone' to another - it's possible to make it work once.

Moreover, under some unknown circumstances, it's possible to make 'Internet Explorer cannot open the Internet site - Operation aborted' with probability 50+%

yogesh

Hi,

Thanks for the script.

I am using IE 7 and i am having textbox controls inside the table. So for this implementation, i am facing a problem. To sort, I have to click the header column twice.

Please helo me out..,

Fred Warnken

Sorttable for AJAX developers:

Since this code was so well-written (congratulations), the solution to have it working for AJAX based pages is very easy.

Problem:

There is only one. The "sorttable" object is initialized when the main page is loaded (via onload) and, at this time, your target table is not loaded yet. Once initialized, one flag is set

for otimization reasons and so,

the initialization can not be done again. This way, AJAX based pages can't use this great code.

Solution:

Have the control over "when the 'sorttable' will initialize" and

reset de initialization flag when necessary.

Recoding (5 steps):

(WARNING! LINE NUMBERS REFERS TO ORIGINAL UNTOUCHED CODE!)

(KEEP ONE COPY OF ORIGINAL CODE TO FOLLOW LINE REFERENCES)

This applies to dynamic table loading only.

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

(1) - Remove lines from line 334 to line 367:

------------------------------------------------- >8 (cut start)

/* ***********************************************************

Supporting functions: bundled here to avoid depending on a

.

. (other lines)

.

window.onload = sorttable.init;

------------------------------------------------- >8 (cut end)

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

(2) - Change lines 24 and 26 from:

if (arguments.callee.done) return;

// flag this function so we don't do the same thing twice

arguments.callee.done = true;

to:

if (sorttable.initialized) return;

// flag this function so we don't do the same thing twice

sorttable.initialized=true;

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

(3) - Remove lines 27 and 28:

// kill the timer

if (_timer) clearInterval(_timer);

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

(4) - Insert a new "reset" method after line 40:

reset: function() {

sorttable.initialized=false;

},

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

(5) - Anywhere outside de "sorttable" declaration (if you don't know where is it, try after the last line), include these two functions:

function startSortable() {

sorttable.init();

}

function resetSortable() {

sorttable.reset();

}

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Recoding is done!

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Now you can have the control to start and reset "sorttable".

Changing your code to use "sorttable":

At the point where your AJAX implementation finishes the table loading, insert these two function calls:

resetSortable();

startSortable();

Example:

function getTable(tablename, place) {

var tablePlace=document.getElementById(place);

var myrequest = (navigator.appName == 'Microsoft Internet Explorer')? new ActiveXObject('Microsoft.XMLHTTP'): new XMLHttpRequest();

myrequest.open('GET', 'readtable.php?t='+(new Date()).getTime()+ '&tablename='+ escape(tablename), false);

myrequest.send(null);

if ( myrequest.status == 200 ) {

var resp = myrequest.responseText;

tablePlace.innerHTML = resp;

resetSortable(); // LINE INCLUDED

startSortable(); // LINE INCLUDED

return true;

} else return false;

}

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Currency:

To have the sort running fine on currency columns for countries where currency format is N.NNN,NN do the following (3 steps):

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

(1) - Change line 172 from:

if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {

to:

if (text.match(/^-?[£$¤]?[\d.,]+%?$/)) {

(or change ,. to .,)

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

(2) - Change line 260 from one line:

aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));

to three lines:

aa = a[0].replace(/\.+/g,'');

aa = aa.replace(/\,+/g,'.');

aa = parseFloat(aa.replace(/[^0-9.-]/g,''));

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

(3) - Change line 262 from one line:

bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));

to three lines:

bb = b[0].replace(/\.+/g,'');

bb = bb.replace(/\,+/g,'.');

bb = parseFloat(bb.replace(/[^0-9.-]/g,''));

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Notes:

Tested and working fine with:

- Google Chrome version 2.0.172.43

- Firefox version 3.5.2

- Internet Explorer version 7.0.5730.13

- Safari version 4.0 (530.17)

- Opera version 9.27 build 8841

Thank you very much for sharing this great work with us.

(Sorry about my weak english language knowledge.)

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Ajang

Can I change the thousand and decimal separator character?

sil

Ajang: not without editing the script, I'm afraid.

Daniel

I just want to say that this is a fantastic product! My son criticized me for not making all of my table columns sortable (I already had done it for 2 of them that do not sort real well - restaurant names and addresses). I was able to put in this change in 5 minutes. Thank you so much for sharing this so generously.

-Daniel

irina

I read all about "Sorting the table when the page is loaded",

and I agree a table should come already sorted from the database.

However, it should be an arrow showing what column and in what direction it was sorted

initially.

Can you please, help me with this?

Other than this, it works absolutely wonderfull.

Thank you a lot.

sil

irina: this bug is known and tracked as http://www.kryogenix.org/bugs/sorttable/initial-sort-indicators.html

irina

I am sure you've got the same question many times.

Please, is there any quick fix for this?

Any leads, tips.

Thank you in advance.

sil

irina: there isn't, really. You can bodge it by writing:

<span id="sorttable_sortfwdind"> ▾</span>

into the header of the sorted column on the server side.

irina

Thank you very much for the response.

It is not as simple as I hoped.

On the server side, I don't know which browser I am dealing with, so it is shown correct only in IE or the others.

And it is shown always. I need to filter innerHTML to change - to delete the one from the server side on any column click.

sil

irina: that's why I said this was a bodge. To fix it properly would require editing the script to accept an already-sorted-by parameter somehow. Let me know if you want me to look at that in detail and we can talk about rates and so on.

Guna

Hi

I have a table with input boxes in td's to fill in dates through calendar or manually.

I tried to sort after filling in the dates. it does not work. do you have any workaround for this.

Please help me

Guna

Hi

I have a table with input boxes in td's to fill in dates through calendar or manually.

I tried to sort after filling in the dates. it does not work. do you have any workaround for this.

Robert

I was encountering the same issues that Yura mentioned in his post (quoted below).

I disagree with "it doesn't work in IE7/8", as I find it very useful! However, in IE7 it worked fine most of the time, but in IE6 I was getting the error "Internet Explorer cannot open the Internet site [...]" almost every time I loaded the page I was using sorttable on.

I discovered IE6 was calling the sorttable.init function when the "document.readyState" was still returning "interactive" instead of "complete." IE7 however was loading sorttable.init in the "complete" readyState most of the time, but a few times I would get the error as it was sometimes in the "interactive" readyState longer than usual.

All in all, I modified the sorttable init function as follows:

sorttable = {

init: function() {

// quit if this function has already been called

if (arguments.callee.done) return;

if (!document.createElement || !document.getElementsByTagName) return;

sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;

if (document.readyState == "complete") { // make sure the readyState is complete

forEach(document.getElementsByTagName('table'), function(table) {

if (table.className.search(/\bsortable\b/) != -1) {

sorttable.makeSortable(table);

}

});

arguments.callee.done = true; // init function already ran = true

}

},

And also I added the following piece of code after window.onload (or anywhere in the global scope):

document.onreadystatechange = new Function("if (document.readyState == 'complete')sorttable.init();");

I no longer get the "...cannot open..." errors.

Note: I use this only in IE6/7 which are my only target browsers for a browser specific local intranet application. Other browsers such as FireFox will not define document.readyState.

---- Yura (Jul 28, 2009 at 8:59 am)

No matter how great is `sorttable`, it doesn’t work in IE7/IE8.

When moving site from one ‘IE security zone’ to another – it’s possible to make it work once.

Moreover, under some unknown circumstances, it’s possible to make ‘Internet Explorer cannot open the Internet site – Operation aborted’ with probability 50+%

Mike

I am using IE8 with Windows7 and I notice that the little up and down arrows that appear in the table heading of the sorted column have been replaced with either a "5" or a "6", corresponding to up and down. Anyone else seen that? Using Chrome on the same machine displays the arrows correctly.

Suggestions for a fix?

Mike

sil

Mike: edit the script to directly embed Unicode characters for the up and down arrows, rather than using Webdings font tags.

Mike

Thanks. Turns out I really meant IE8, not 7. Anyway, not being much of a programmer, I have a question.

I assume the following line is the one you are referring to and it means "if it's IE, then use webdings character 5, otherwise use the unicode character &#x25B4". (I could be way off here.)

sortrevind.innerHTML = stIsIE ? '&nbsp5' : ' ▴';

If that is the case, then don't I need to ask whether it it IE7 or IE8? IE7 displays the unicode thing incorrectly (thus the webdings hack I assume) and IE8 displays webdings incorrectly. Perhaps all this goes away if I upgrade to v2?

Mike

The browser interpreted the javascript line. Here's what I meant to paste in:

//sortrevind.innerHTML = stIsIE ? '&nbsp5' : ' ▴';

Mike

can't seem to paste in the line of code and have it show up! grrrr. hopefully you know what I mean.

Byron

Thanks Robert for your information about this issue: "When moving site from one ‘IE security zone’ to another – it’s possible to make it work once.

Moreover, under some unknown circumstances, it’s possible to make ‘Internet Explorer cannot open the Internet site – Operation aborted’ with probability 50+%".... Yura.

I spent a lot of time in give a temporary solution for that issue, but with your code now it works fine in a more condensed solution.

Regards

Fab

Something good will be to add an external link to order a column. A trigger link. Will be so usefull for me. lol

So, thanks to share your work, it's a very good script.

Fab

Pete

Firstly, thank you for this code! It is extremely helpful with a site I have been developing.

With regards to multiple header rows, I have a bunch of tables with multiple header rows, but only want the last (bottom) row to be sortable, so here is how I compensated:

I changed this line:

if (table.tHead.rows.length != 1) return; // can't cope with two header rows

to this:

var headerRow = 0;

if (table.tHead.rows.length != 1) headerRow = table.tHead.rows.length-1;

Then I changed

headrow = table.tHead.rows[0].cells;

to

headrow = table.tHead.rows[headerRow].cells;

So far, it appears to work fine in IE6, IE7 and FF3. I will be checking other browsers soon.

John

Your script is great, however I want to use it in a secure HTTPS environment. It works well in everything except IE8, in which it gives a "Do you want to view only the webpage content that was delivered securely?" Security Warning before the table displays on the screen. Regardless of whether or not you choose Yes or No on the dialog, the grid loads as it should. I just don't want the users freaking out thinking the page isn't secure when it really is. I know its the script, because if I simply include the script on an https page I get this message regardless of whether I show a sort table or not. I've looked at the script and really couldn't find anything that might be doing this. Got any ideas?

sil

John: see http://www.kryogenix.org/bugs/sorttable/https-secure-content.html for a workaround.

Macinville

great script!

I have a question, sir. What if I want to "freeze" the first column of my table? According to your documentation, i need to put

class=""sorttable_nosort"

in the column which I dont want users to click on. But whenever I click on other columns, the leftmost column (which contains the item numbers like 1,2,etc..) also got affected by the sorting. What I need is for the values for the said column to retain its values,regardless of the sorting the users want.

I apologize if this issue has been already posted in this forum. I'm honestly in a hurry today.

Again, thanks for this great code. More power!

sil

Macinville: sorttable_nosort doesn't freeze a column; it just means that the head of that column won't be clickable. Sorttable doesn't currently do frozen columns; if you'd like it to, drop me an email and we can talk about crates for custom work and so on :)

This website belongs to Stuart Langridge. Contact details are available. Don't eat yellow snow. Valid HTML5, at least in theory, except for the bits that aren't because I'm that futuristic that I'm ahead of the spec, oh yes. HTML5 help from Bruce Lawson, among others. Fonts from the superb FontSquirrel. End.