Table Sorting with Prototype

Thursday, November 16, 2006

Here's my latest labour of love: a table column sorting script using Prototype. I tried to make it as painless as possible to use while retaining a good measure of customisability. As it turned out the damn thing has more features than an echidna has spikes! It's got multiple sorting types, automatic data type detection, row striping, it handles empty or spanned cells, optional fixed header and scrolling body, you can extend it with your own sort types and much more! This is also sponsored open source development. So even though it is free to you, under the MIT license, it was sponsored by the very nice people at Pixeline Web Design. Jump straight to the demo , or read on for the details.

Simple Usage

Installation

Reference the script in your HTML and give your tables a class of "sortable", sit back and watch the magic happen.

<script type="text/javascript" src="scriptaculous/lib/prototype.js"></script>
<script type="text/javascript" src="fastinit.js"></script>
<script type="text/javascript" src="tablesort.js"></script>

Prototype and tablesort.js are required of course; Fastinit is optional.

If the table has a thead then the last row of the thead (the one closest to the body) will be used as the header row to add the sorting 'onclick' event listeners - one to each header cell. If there is no thead the first table row will be used. Only rows in the table body are sorted, all other cells (in the thead or tfoot) are ignored.

Sorting Types

The table will attempt to automatically detect the sorting type for your columns (text, number, date...etc) by analysing the first cell. If you don't want it to do that you can specify the exact sorting by adding a class to your header cell for example class="number". Available ones are:

A special notes about dates: By default the script's automatic sort type detection will favour Australian dates, dd/mm/yyyy. If you want it to favour US dates, mm/dd/yyyy, then either add the class "date-us" to the header cell on the date column or read Advanced Usage below.

No Sort columns

If you don't want a column to be sorted then give the header cell a class of "nosort"

Sort First Column

If you want a column to be sorted when the page loads then add a class to the header cell of that column; "sortfirstasc" for ascending and "sortfirstdesc" for descending.

Other CSS Hooks

header cells will be given the class "sortcol", and when sorted they will be given the class "sortasc" for ascending and "sortdesc" for descending.

Body rows will also be given the alternating classes "rowodd" and "roweven" on load and after each sort as an added bonus.

You can see the CSS in the demo for an example of what to do with them.

Advanced Usage

Detectors

Automatic detection is handled by an array of regular expressions. The script will take the inner text of the cell and pass it through the array from start to finish, the first one that matches is the sort type used. You can add a detector to the array by using SortableTable.addDetector(regexp, name). The regular expression is used to detect a match. If the match is successful the sort type identified by the name is used. For example here's the detector for European Dates:

SortableTable.addDetector(/^d{2}-d{2}-d{4}/i, 'date-eu');

Sorting Types

An associative array of sort types is maintained by the script. Each sort type has a key which matches the classname and the detector name.

The sort type is a function that takes 2 arguments, the 2 values being compared, and returns either 1, 0 or -1. 1 if a is greater than b, -1 if b is greater than a and 0 if they are equal. The default comparison function, SortableTable.compare(a,b) looks like this:

function(a,b) {
return a < b ? -1 : a == b ? 0 : 1;
}

Sort type functions can make use of this function for the final comparison. Usually thought you have to normalise the 2 values to get a useful comparision. For example the standard text sort type function looks like this:

function(a,b) {
return SortableTable.compare(a ? a.toLowerCase() : '', b ? b.toLowerCase() : '');
}

Important: sort type functions need to be able to cope with an empty string (in situations where a cell is empty or part of a spanned cell). Here's another example - the sort function for numbers:

function(a,b) {
// This will grab the first thing that looks like a number from a string, so you can use it to order a column of various srings containing numbers.
var calc = function(v) {
v = parseFloat(v.replace(/^.*?([-+]?[d]*.?[d]+(?:[eE][-+]?[d]+)?).*$/,"$1"));
return isNaN(v) ? 0 : v;
}
return SortableTable.compare(calc(a),calc(b));
}

Look through the in-built sort types for more examples. You can add them using the function: SortableTable.addSortType(name, function)

for example:

SortableTable.addSortType('text', function(a,b) {
var calc = function(v) {
v = parseFloat(v.replace(/^.*?([-+]?[d]*.?[d]+(?:[eE][-+]?[d]+)?).*$/,"$1"));
return isNaN(v) ? 0 : v;
}
return SortableTable.compare(calc(a),calc(b));
});

Wrapping it up

So when adding the ability to handle a new sort type consider adding a detector as well as a sort type function. For adding multiple types and detectors see options below.

Options

To change any of the defaults you must use the SortableTable.setup({options}) function and call it before the page loads and the script is initialised.

the default options are:

autoLoad : true

Initialises table sorting automatically, use Fastinit for a speed boost!

tableSelector : ['table.sortable']

This can be changed to any other CSS selector, or mupltiple selectors (it's an array) so you can apply table sorting as you require.

columnClass : 'sortcol'
descendingClass : 'sortdesc'
ascendingClass : 'sortasc'
nosortClass : 'nosort'
sortFirstAscendingClass : 'sortfirstasc'
sortFirstDecendingClass : 'sortfirstdesc'
rowEvenClass : 'roweven'
rowOddClass : 'rowodd'

if you need to you can change the CSS classes used.

tableScroll : 'class'
tableScrollClass : 'scroll'

See table scrolling below

You can also add multiple types and detectors like this:

SortableTable.setup({
detectors : [
{re: /a RegExp/, name : 'type name'},
{re: /another RegExp/, name : 'type name'},
],
types : {
atype : function(a,b){
//comparison function
},
anothertype : function(a,b){
//comparison function
}
}
});

API

SortableTable.load();

If you don't want it auto-loaded you can instead call SortableTable.load(); at any time to load via the table selectors specified.

SortableTable.init(table);

Or you can specifically initialise a table by using SortableTable.init(table); where table is a table element reference or ID.

SortableTable.sort(table, index, order);

To sort a specific table column (for example if you want to use an external control) you can call the sort function manually.

Table Scrolling

Optionally you can make the table have a fixed header and a fixed height (and/or width), scrolling body. By default if the table also has a class of 'scroll' it will attempt to make this happen.

It does require some CSS to make it work. The minimum CSS required is the following:

.scroll-table-head {
width: 800px;
}
.scroll-table-body {
width: 800px;
height: 400px;
}

The table head is appended to a div element with the class of 'scroll-table-head', and similarly the table body is appended to a div element with the class of 'scroll-table-body'. Both will need identical widths and the body will need an appropriate height.

Also because scrolling seperates the head from the table body, the column widths become fixed and the script writes inline styles to each header cell and body cell to specify the width in pixels. If you are finding the columns don't match up then you should check anything in your CSS that might effect the widths of the column, for example padding on some cells and not on others.

Options

There are two options for table scrolling, these can be changed in your SortableTable.setup() function call if desired.

tableScroll : 'class'

off | on | class : off = scrolling disabled, on = every sortable table has a fixed header and scrolling body, class = only tables with the class name and made scrollable

tableScrollClass : 'scroll'

if tableScroll above is set to class, this is the class name used. Also this class name is added to all scrollable tables regardless.

Demo & Download

You can check out a demo here, or download it .

It was created using Prototype v1.5.0_r obtainable via Scriptaculous and included in the .zip file.


Sponsored by Pixeline

Support

Please submit your questions, suggestions, patches, bugs and such to the Dexgogo group on Google Groups .

Change Log

Version 1.0

100 Comments

#1
On the November 23, 2006, Brij wrote:

Hi,
Thanks a lot for the excellent tutorial and the code, it works like a charm! Although, I'm having a small issue. The first time the user loads a page with a table list the sorting works fine. I have a search box and based on the input the table is filtered and DIV is refreshed with an AJAX call. After this happens the sorting is lost of the columns, any ideas on how to fix this?

Thanks.

#2
On the November 24, 2006, Andrew Tetlaw wrote:

Hi Brij, in your case, because you are redrawing the table, you will have to re-apply the sorting after your AJAX call updates the table. Off the top of my head you could probably write a function that finds the head cell that has a class of 'sortasc' or 'sortdesc', and use that to do your own call to SortableTable.sort().

#3
On the November 30, 2006, John wrote:

YACN (yet another congratulatory note)! Thanks for the solid code you've written. I've integrated this with my RoR app and it works like a charm. Let me know if I can do anything to help.

Best Regards,
John

#4
On the December 1, 2006, Andrew Tetlaw wrote:

Hey thanks John!

#5
On the December 7, 2006, Brian wrote:

Great code! I made one small tweak... Line 191, where the code attempts to parse a number, I added a line to remove commas from the input value (for situations where a numeric column has commas -- they will otherwise be seen as strings, even when using class="number"):

v = v.replace(/,/gi,"");

#6
On the December 12, 2006, Tom wrote:

Many thanks for this! Just what I was looking for. Small problem I'm having though... one column contains numbers and text. Clicking the title once sorts correctly, the second time it reverses the order (correctly though), but the third and fourth times, the sorting goes haywire. This repeats (ie 5th, 6th clicks fine, 7th, 8th clicks wrong again). Can text and numbers be mixed in the column? Thanks. Tom

#7
On the December 12, 2006, Andrew Tetlaw wrote:

Hi Tom, nah it's not possible at the moment. The script assumes all cells in a column equal the data type of the first cell.

Sorting multiple data types can be done if you write your own sort type.

#8
On the December 13, 2006, John K wrote:

Wow, this is really great! There's only one small feature that I'd like to see though. Many times I will render a table that contains sequentially numbered rows (1 - n). However, I would like to preserve the ordering for this particular column (while ordering everything else). I might try to alter your code to allow for this functionality and will let you know what I come up with. Thanks again!

#9
On the December 15, 2006, Dhiraj Ramakrishnan wrote:

Hey,

Great code. Thanks for that. 

I have question though, in my application i am trying to expand and collapse some rows.
I want to sort based on the rows currently visible. Is it possible to do that? 

Thanks

Dhiraj

#10
On the December 16, 2006, Andrew Tetlaw wrote:

Hi Dhiraj, it doesn't as yet, but that's a good idea. I can see it'd be easy to add a 'rows' argument to the sort function, so that it only sorts specified rows.

#11
On the December 28, 2006, Andrew wrote:

This is great work. But I am stuck on a problem. I am using ajax to dynamically populate my table with streaming values and I want to sort the table only the first time on a specific column after it gets its first data. Since the ajax call is made after the page loads, using "sortfirstasc" will not work. I finally got it to work by making my ajax call to populate the table then executing SortableTable.sort($('TableData'),3,-1); But something weird happens when I add "scroll" to the table class since I also want a fixed header table that scrolls. One of the table cell turns blue with lots of the down arrow images. Any ideas as to what I can do?

#12
On the December 28, 2006, Andrew Tetlaw wrote:

Hi Andrew,
It sounds like the CSS rule for background-repeat: norepeat; is not being applied.

Check the CSS selector you are using to apply the rule. If you have the table ID in the selector it might explain it because on scrolling setup the header cells are moved to a new table. If you use the simple '.sortcol' selector it should work fine.

#13
On the December 29, 2006, meth wrote:

hi andrew, great work. i've a quick question for you.

the sortable table worked fine until i've tried to load the page containing the table (as a partial) using ror's ajax loader. the table then stop responding.

any idea what might be wrong? thanks a million.

#14
On the December 30, 2006, Andrew Tetlaw wrote:

Hi Meth, You'll prolly just need to initialise manually. The table sort script only initialises on the window load event. Check the API section above.

#15
On the January 3, 2007, meth wrote:

thanks andrew, you are spot on that i've to re-init the script. thanks again for the wonderful script and have a great day!

#16
On the January 13, 2007, seth wrote:

Hi,

I am wondering if SortableTable.sort($('Table'),1,-1) method work for any table with out any css class(sortable) mentioned in its definiton. I tried doing that but I get java script error saying table.rows undefined. so I am wondering if this is possible?

#17
On the January 15, 2007, Andrew Tetlaw wrote:

if you call SortableTable.sort($('Table'),1,-1) it means you are sorting the first column of the table element with an ID of 'Table' i.e. <table id="Table">.

#18
On the January 17, 2007, Joe wrote:

Hi, is it possible to set the default order for a type? (Desc seems to be the default for all...) For ex, I would like text to be sorted ascending while number descending (when the column is first selected).

Thanks!!

#19
On the January 25, 2007, Craig wrote:

This script is great! It makes it so easy to sort table data. One catch is that you can't have any proprietary attributes in a <TD> such as a rowspan attribute because once .sort is applied (rows.sort(function(a,b) {), that <td> gets moved around for some reason.  

I created a rowspan workaround if anyone needs help with this. It is assumed that the rowspan column resides under a "nosort" header.

#20
On the January 29, 2007, hebiryu wrote:

I just do these 3 simple task : 

1. copy tablesort & fastini.js
2. put the js in the html
3. change the table class to sortable

and it work like a magic. there's nothing simpler than this. thanks very-very much !! 

#21
On the February 2, 2007, Andrew Tetlaw wrote:

Joe, not yet but that should be a feature I agree.

Craig, thanks! Please post it to the google group if you like.

#22
On the February 12, 2007, Chris wrote:

Excellent script. I've been looking around for one for a while and this is by far the best I have found so far.
Just encountered one little problem though. One of my columns (cost) seems to sort perfectly in descending but is random is ascending... and I cannot work out why. It seemed to sort itself out once but has gone haywire again. It started fine but now I have added more rows its stopped working so well.
ummm

#23
On the February 12, 2007, Chris wrote:

Update further to my last comment.
The column sorts fine if all prices are £99 or less, any that are £100 or over it sorts incorrectly. Anybody have any ideas why or how I can correct this?
Thanks.

#24
On the February 23, 2007, Kit wrote:

Hi,

It's a great work and helps me a lot!

Thank you very much!

#25
On the April 3, 2007, arthemisia wrote:

Hi,
I would like to put an image in a row. Could I sort this with the name of the file in the url src ?
I try this but it doesn't work :
SortableTable.addSortType('img_pm', function(a,b) {
str_a = a ? a.toLowerCase() : '';
str_b = b ? b.toLowerCase() : '';
return SortableTable.compare(str_a.indexOf("parcours"),str_b.indexOf("parcours"));
});

#26
On the April 6, 2007, Sycorax wrote:

Hello, i have tried the demo example on IE7 and it is not working? Any idea, whats wrong up there? With IE6 and FireFox,Opera it is working... thanx

#27
On the April 12, 2007, Michael Johnston wrote:

I am curious why this is implemented as a singleton and not as an object attached to the table.

I want to refactor it to add caching of the sorted data, something which all the good non-protoype-based table-sorting scripts do because it is much faster on large tables. 

This is also a first step in another refactoring to support hierarchical data, which I thought to implement by creating a tree of the data in cells, using rowclass to identify hierarchy, then recursively sorting that data tree and appending rows based on their position in the data cache.

#28
On the April 12, 2007, Michael Johnston wrote:

I don't understand this construct:

table = table ? $(table) : table = cell.up('table');


what is the purpose of the extra = ? Why is it not just

table = table ? $(table) : cell.up('table');

#29
On the April 12, 2007, Andrew Tetlaw wrote:

http://www.millstream.com.au/view/code/tablekit

Hi Michael, you should check out TableKit , which was based on this script but is much more mature now. It already has caching and the sorting performance is much better.

#30
On the April 12, 2007, Andrew Tetlaw wrote:

Oh and that crazy code just looks like something I missed and should have corrected - like 2 lines became one and I neglected to fix the syntax.

#31
On the April 12, 2007, Michael Johnston wrote:

looking at the code of tablekit, it does not seem to have data caching, but only avoids sorting when only reversing a currently sorted column.

In any case, my patch can easily be adapted for tablekit, so I will do that and submit it there.

#32
On the April 12, 2007, Michael Johnston wrote:

...seems my patch did not get posted (because of link?)

it is:

http :// pastie.caboo.se/53178

#33
On the April 12, 2007, Michael Johnston wrote:

(this patch adds data-caching plus the ability to have hierarchically arranged data in the table, by giving rows a class indicating level)

#34
On the April 12, 2007, Andrew Tetlaw wrote:

Michael, you are mistaken. It does indeed cache cell data and it also caches the sort data type for each column. The data cache is also marked for refresh whenever someone edits a cell. You can see the cache in the 'getCellText' function. See if that meets your needs.

Regarding your patch, I'd be careful of adding the cache data to an expando property of a DOM element (like the table) as that leads to memory leaks.

#35
On the April 26, 2007, iwank wrote:

waw nice script i have been search for 3 day for script like this

cool script

#36
On the May 3, 2007, danny wrote:

Thanks for this script, its great and integrates really well!

Thanks alot.

@Brij asked about reinstating the script after an Ajax update to a table, can't he simply rerun SortableTable.load(); on the Ajax callback?

#37
On the May 3, 2007, danny wrote:

I just reused SortableTable.load(); successfully on an Ajax call in IE6, IE7, FF2 and Opera.

However for some reason when I do the same after using JS to modify other parts of the page (including tables) it causes IE6 & 7 to have an error and stop sorting. Will post back if I find a solution.

#38
On the May 14, 2007, FastJack wrote:

Fantastic work! One nitpick though. Euro dates usually are displayed as YYYY-MM-DD.

#39
On the May 18, 2007, bancbanus wrote:

I use your script on a SSL-secured website and the Internet Explored always showed me this warning: 

"This page contains both secure and non-secure items. Do you want to download the non-secure items?".

The reason of this problem was your fastinit script. After removing it the annoying warning never comes up.

Finally a feature request: could you add a detector for the german date format (eg 1.1.2007)?

Thank's a lot for your wonderful script!

#40
On the May 19, 2007, Andrew Tetlaw wrote:

Hi bancbanus, The latest version of FastInit has fixed this problem. I probably have an old version in the zip file.

#41
On the June 19, 2007, Krishna Kotecha wrote:

Great work. Thanks for sharing this.

#42
On the June 22, 2007, ak wrote:

Great script!!

I read someone needed help to sort the values ascending by default.

Open the tablesort.js

Change this:
order = order ? order : (cell.hasClassName(op.descendingClass) ? 1 : -1);

To this:
order = order ? order : (cell.hasClassName(op.ascendingClass) ? -1 : 1);

That should do the trick!

ak

#43
On the July 6, 2007, Roopa wrote:

Hi,
This is a great script - had been looking quite long for one like this.. I have a minor issue, though - is the width of the table adjustable? 

Example, I have only 3 columns, so I need a vertical scroll but not horizontal?

The vertical scroll does appear, but the acroll bar appears detached from the main table.

tried setting width attribute to both DIV and TABLE, didnt work - please help!! I am sure it is possible.. 

BTW, I am working with IE 6.

Thanks so much for sharing such a wonderful code!
-Roopa.

Code that I tried:

<div id="content" width="200px">
<h2>Table 6</h2>
<p>This one demonstrates fixed header scrolling</p>
<table class="sortable scroll" width="200px">
...
rest is the same as index.html

#44
On the July 13, 2007, Ron wrote:

I'm having trouble getting multiple rows in the <thead> of a scrollable table. Craig wrote that he got it to work but he didn't write anything up on google groups. Thanks for any help.

#45
On the July 20, 2007, master wrote:

The price sort is fine, place the currency (GBP (£)/ EUR AFTER the price.

#46
On the July 25, 2007, vacuum cleaner wrote:

Holy Buddha, amazing code! Thank you, thank you, thank you for sharing it! The tutorial is great, the code works perfectly without any problems, and suddenly, life is so much easier! Like others said, I also dumped the fastinit script to get rid of that annoying pop up box (sorry, but I hate that whole “secure / non-secure items” pop up). I’ve had users report some issues with IE7, but everything seems to go find on IE6 and Firefox 2, so I’m not that worried about it. I’m sure someone with more time (and knowledge) on their hands will figure out some fix for it – you guys seem much more in tune with the javascript than I am, thankfully. One question: any way to force the table to see numbers as text so as to get around the fact that numbers and text can’t be mixed?

#47
On the July 26, 2007, Andrew Tetlaw wrote:

Hello Mr Vacuum Cleaner,
The FastInit “secure / non-secure items” pop up problem was fixed a long time ago! Go and grab the lastest version here: http://tetlaw.id.au/view/javascript/fastinit

Also if you liked this table sorting script you'll also appreciate my next project: TableKit http://www.millstream.com.au/view/code/tablekit

The sorting in TableKit is much faster.

#48
On the August 4, 2007, ramjith wrote:

This is an excellent script .I have a problem when table retrieves more rows (>500 rows) of data from database.I am getting alert saying "A script on this page causes IE to run slowly.If it continues to run,your computer may be unresponsive. Do you want to abort?" .And after that the scroll bar is not displayed.Can you give a suggestion for this?
I really appreciate for sharing this wonderful script.Thank you very much.

#49
On the August 21, 2007, Manigandan wrote:

hi..

How to get current sorting order and column name.

#50
On the August 22, 2007, oil paintings art wrote:

Our tables on site are collapsible in nature. We designed it using CSS. Is it possible for us to use your script without destroying this collapsible look?

#51
On the August 22, 2007, Manigandan Govindaraj wrote:

Is there any way to select rows using CTRL+ key 
modifiers like spreed sheet.
Thanks in advance

#52
On the September 10, 2007, John W wrote:

I just spent two hours debugging a minor tweak I made to work with our JSP tag library.

In tablesort.js:
sortFirstDecendingClass : 'sortfirstdesc',

I was trying to figure out why it wasn't matching op.sortFirstDescending. It was because it's spelled as sortFirstDecending with no 's'. 

I don't know if this is a typo, or if it's a legitimate difference between the American and Australian spelling. Either way, something to look out for.

John

#53
On the September 10, 2007, Benjamin wrote:

very nice script. Thanks for sharing indeed!
I found a tiny little bug though that gave me a bit of a headache. parseInt(s) automatically interprets the provided string as "radix-8-number" (octal), if this string starts with character '0'.

For dates this may results in a wrong sorting order concerning months august and september or the days "08" and "09" of a month. This happens as "08" is interpreted as number 0 and "09" is interpreted as number 1.

This problem can be fixed by using parseInt(s,10), instead of parseInt(s) throughout the script.

#54
On the September 11, 2007, Andrew Tetlaw wrote:

Hey John W and Benjamin, all of the tablesort code was rolled into TableKit and is much improved:
http://www.millstream.com.au/view/code/tablekit/

#55
On the September 23, 2007, Loren wrote:

Hi, great code. Is there any way it can be modified to have the first column fixed as well as the header?

#56
On the October 10, 2007, John Smith wrote:

This is a great script. How hard would it be to incorporate paging?

#57
On the November 8, 2007, Andrew Tetlaw wrote:

Hi Sam, have a look for the TableKit.Sortable.reload function. You shoudl also post you questions to the Dexagogo group: http://groups.google.com/group/dexagogo

#58
On the November 27, 2007, Dennis wrote:

Excellent script, but I ran into a minor problem in IE that I do not know how to resolve. In IE 7, the table header and body cells all have the same width, whereas in Firefox the widths automatically adjust to fit the text. How can I apply this behavior to IE 7 also?

I also have another question, is the scroll portion of this script not available in TableKit?

Thanks for the help,

Dennis

#59
On the February 20, 2008, Perry Smith wrote:

In Firefox 2.0.0.9 without FastInit, the line:

if(FastInit) {

gets an error. I changed it to:

if(window.FastInit) {

but I'm not sure that is right.

#60
On the February 21, 2008, Nirbhay wrote:

Hi
Great piece of code!!
Although am having a minor issue.
I use AJAX calls and hence apply the sort after the table has been rendered.
After i apply the SortableTable.init('MyTable'), it adds an equivalent set of empty rows to the actual rows.
Any idea ??
Hence the sort doesn't work as expected.
Appreciate it

#61
On the March 19, 2008, Bastes wrote:

Awesome job. Thanks a lot.

#62
On the March 24, 2008, Tom wrote:

Nice job!But it doesn't work in Opera or IE 6.0.

#63
On the March 27, 2008, adult toys wrote:

The solution lies in looking for the little snippet of html in lin 65 of the code

#64
On the March 31, 2008, Tom wrote:

Is it code statement?
var w = table.getDimensions().width;
but how to modify it?

#65
On the March 31, 2008, Andrew Tetlaw wrote:

Sorry, Tom. Not sure what you're asking there...

#66
On the April 1, 2008, Tom wrote:

Andrew Tetlaw,
The tablesort.js doesn't work in Opera or IE 6.0.Can you help me?Thanks.

#67
On the April 1, 2008, Tom wrote:

Andrew,
I find that tablekit.js of http://www.millstream.com.au/view/code/tablekit/
is ok in IE or Opera,but tablesort.js doesn't work in IE or Opera,can you tell me why?
Thanks.

#68
On the April 1, 2008, Andrew Tetlaw wrote:

Well I've clicked the demo link above and it works on FF2, IE6, Safari 3 and Opera 9.5b.

That said, it hasn't been touched for a long time and if you're using the latest prototype I don't know what might happen.

#69
On the April 1, 2008, Tom wrote:

Andrew,
I have tried Demo in other's IE6,it is ok.
Maybe my IE have something wrong.Thanks.

#70
On the April 1, 2008, arulvel ss wrote:

My Table Values like 

123,456.10
123,222,345.23
606.10
67.10

But it is not arranged ? 

Thanks

#71
On the April 10, 2008, Mike wrote:

Thanks for the great code!

There is a typo in the Table 1 demo example. The class for the first column is labeled 'sortfirstdec' instead of 'sortfirstdesc'. The first column is not sorting by default because of this.

#72
On the April 26, 2008, Ramkumar wrote:

Hi,

I am using the tablekit 1.2.1 javascript for sorting the table data's.

now my problem is, i have the three rows of header's, i want to sort
the table using the second header.

there is any way to solve this problem,

#73
On the April 30, 2008, oil painting from photos wrote:

The three column theme is very popular in WP lately. I wanted to create one which can be used for social networking sites. Can I make use of this for the said purpose?

#74
On the May 6, 2008, Benoit wrote:

First, thanks for this great amount of work offered to us.

I think I've found a bug in sorting on date strings. It reproduces at least in Firefox (2.0.0.14), perhaps it has been fixed elsewhere (tablekit ?).

All date sorting funcions looks the same: proble is the javascript match function returns strings matched, not integers so the date may be incorrect if numbers are leaded by 0

here the fix I wrote, you can replace safely in all dates function (including hours/min)
Old code :
var r = v.match(/^(d{2})-(d{2})-(d{4})/);
var yr_num = r[3];
var mo_num = parseInt(r[2])-1;
var day_num = r[1];

Replaced with
var r = v.match(/^(d{2})-(d{2})-(d{4})/);
var yr_num = parseInt(r[3],10);
var mo_num = parseInt(r[2],10)-1;
var day_num = parseInt(r[1], 10);

#75
On the June 12, 2008, Souvik Mukherjee wrote:

tablekit sort by column option is not working in IE6 but working in IE7,please suggest. and I need an urgent response.

#76
On the June 12, 2008, Souvik Mukherjee wrote:

I am sorry,I just states my problem,and it should have been different, as follows:
tablekit sort by column option is working in IE6 but not working in IE7,please suggest. and I need an urgent response.

#77
On the June 14, 2008, David Lee wrote:

In accordance with Souvik Mukherjee's comment, I want to point out that tablesort does not work with IE7 only if you're using Prototype 1.6. Tablesort DOES work if you're using Prototype version < 1.6.

#78
On the October 16, 2008, MNor wrote:

Very good script indeed. works very fine ..

#79
On the October 16, 2008, Nandan pramanik wrote:

I am a RoR developer. I used it but i am not able to sort the table when ajax update the table. This is my code.
<%= observe_field 'query', :frequency => 2,
:loaded => "SortableTable.init('table');",
:update => 'table',
:before => "Element.show('spinner')",
:success => "Element.hide('spinner');SortableTable.sort();",
:url => {:action => 'list'},
:with => 'query' %>
please any body help me.

#80
On the October 24, 2008, Bubba G wrote:

Demo not working, forbidden access.  Please FIX!

#81
On the October 30, 2008, justin wrote:

when I change the cell on my installation it reverts back to the original data. I'm not sure how to change the URI in the php if I want to update my database with each changed cell. Could anyone offer an example I could work with that shows how I could have my database updated when I change the data in a cell. As of right now, it's not working for me, though I know nothing of what I'm doing...
thanks

#82
On the November 14, 2008, Teamforce wrote:

Any chance of updating the demo link, would be very helpful and much appreciated if you could.

#83
On the November 17, 2008, Ifosen wrote:

the download.zip doesn't work, I mean serious. It doesn't work in both IE6 and FF2,
you can try to download it and run it again, the error occur in line 323!

#84
On the November 22, 2008, Lift chair wrote:

I get the same error :(

#85
On the January 6, 2009, Upendra wrote:

Hello,

Thank you for the script.

There is a bug in the code when you sort the data with dates starting with months 08 & 09 . Try to sort the following dates 08-04-2008,09-07-2008, 08-10-2008, 09-25-2008.
You can see that sorting is not happening as expected.

Root Cause:
In the date-us & all other date types,

the code
var mo_num = parseInt(r[1])-1; is causing the issue.

parseInt("08") results in 0 instead of 8. And parseInt("09") results in 0 instead of 9.
The reason for this is because the zero in front is trying to tell the browser that this is an octal (base 8) number, and "08" and "09" are not valid octal numbers. 

Fix:
When using the paresInt function use the radix parameter 10 to tell that the string is of base 10(decimal) type.

Code Change::
var mo_num = parseInt(r[1],10)-1;

in all the date data types. 

Let me know if you have any queries.
Regards
Upendra

#86
On the January 13, 2009, Karl Varga wrote:

Thanks for the awesome code! It has really been a pleasure to use!

I had some problems with getCellText() throwing a JS error because the check for "cell.textContent ? cell.textContent : cell.innerText" is flawed logic.

I also had a problem when some cells in a column are empty and you're sorting something other than 'text'. The first time you sort, everything is likely ok, it's sorts ASC and the empty cells end up at the top. Now when you sort again it uses the empty cell to determing the content type, which is always text for an empty cell, so the sorting gets messed up. I had to change it to look down the column until it finds the first non-empty cell to determine the content type rather than picking the first.

My changes to getCellText() and getDataType() are in this pastie link:

http://pastie.org/359196

#87
On the March 11, 2009, Max wrote:

Hi everybody!

I like this excellent script very much - but I have got one big problem:
The script works on Firefox and Safari very well.

But it does not work on Internet Explorer when you call the webpage first time. It only works, when you RELOAD the page.
Does somebody know what the problem is?

#88
On the March 25, 2009, Aissa Berber wrote:

Hi,
Thanks for the great code!
now my problem is the cell align,all the <TD> are displayed in the left. I need to display sum of column in center or right.when a apply align style to the cells, i have no change!!
Can you help me to fixe this problem.
Thanks.

#89
On the April 11, 2009, Jesper Petersson wrote:

Hello!

I see that there are many having problems with updating table content using Ajax.

I've written an article about it here:
http://doubleint.com/article/2

I hope it'll help someone :-)

#90
On the June 4, 2009, Sri wrote:

Hi,

I am using your sorting feature for one of my assignments, and it works great however as it happens all the time client appreciated the work and came up with a new requirement where the user should be able to sort multiple columns at the same time, retain those up/down arrows. e.g Column1, Column2, Column3

user clicks on Column1 which is fine it sorts the table, but when user clicks on Column3 again it should retain the first time sort on Column1 and then it should sort Column3 also. Any ideas how to make that work

#91
On the June 30, 2009, Claudio wrote:

Doesn't work for FF as XHTML!

Hi! I tried to use your cool script in my app but it didn't want to work (with Firefox 3.0.11). After long time of bug hunting I found out that it's the "Content-Type" "application/xhtml+xml" that hinders the script. :-/ It does not throw an error or sth (using Firebug) but just fails silently.

Damn, that sucks. I need to use XHTML.

#92
On the July 29, 2009, Philippe Mouawad wrote:

Hello,
Thanks for your great code.
Don't know if it will interest you, but I made some optimizations on your code, using the table with scroll feature under IE6 with a table of 100 elements I noticed low performance (2s to display spent on client side).
After this optimization I managed to get to 670ms.
I can send it to you if you're interested.

Here is the patch:
### Eclipse Workspace Patch 1.0
#P fwk
Index: src/tablesort.js
===================================================================
diff -u -r1.2 tablesort.js
--- src/tablesort.js 28 Jul 2009 18:35:07 -0000 1.2
+++ src/tablesort.js 28 Jul 2009 18:35:27 -0000
@@ -27,6 +27,7 @@

var SortableTable = {
init : function(elm, o){
+ var start = new Date();
var table = $(elm);
if(table.tagName != "TABLE") return;
if(!table.id) table.id = "sortable-table-" + SortableTable._count++;
@@ -34,14 +35,15 @@
var doscroll = (SortableTable.options.tableScroll == 'on' || (SortableTable.options.tableScroll == 'class' && table.hasClassName(SortableTable.options.tableScrollClass)));
var sortFirst;
var cells = SortableTable.getHeaderCells(table);
- cells.each(function(c){
- c = $(c);
+ for( var i = cells.length - 1; i > -1; i-- )
+ {
+ var c = cells[i];
if(!doscroll) {
Event.observe(c, 'click', SortableTable._sort.bindAsEventListener(c));
- c.addClassName(SortableTable.options.columnClass);
+ SortableTable.addClass(c, SortableTable.options.columnClass);
}
- if(c.hasClassName(SortableTable.options.sortFirstAscendingClass) || c.hasClassName(SortableTable.options.sortFirstDecendingClass)) sortFirst = c;
- });
+ if(SortableTable.hasClass(c,SortableTable.options.sortFirstAscendingClass) || SortableTable.hasClass(c, SortableTable.options.sortFirstDecendingClass)) sortFirst = c;
+ }

if(sortFirst) {
if(sortFirst.hasClassName(SortableTable.options.sortFirstAscendingClass)) {
@@ -56,6 +58,7 @@
});
}
if(doscroll) SortableTable.initScroll(table);
+  alert("Time:"+(new Date()-start));
},
initScroll : function(elm){
var table = $(elm);
@@ -70,16 +73,19 @@
width: w + 'px'
});

+
+ var rows = $A(table.tBodies[0].rows);
var cells = SortableTable.getHeaderCells(table);
- cells.each(function(c,i){
- c = $(c);
+ for( var i = cells.length - 1; i > -1; i-- )
+ {
+ var c = $(cells[i]);
var cw = c.getDimensions().width;
c.setStyle({width: cw + 'px'});
- $A(table.tBodies[0].rows).each(function(r){
- $(r.cells[i]).setStyle({width: cw + 'px'});
- })
- })
-
+ for (var j=rows.length-1;j>-1;j--)
+ {
+ rows[j].cells[i].style.width = cw + 'px';
+ }
+ }
// Fixed Head
var head = (table.tHead && table.tHead.rows.length > 0) ? table.tHead : table.rows[0];
var hclone = head.cloneNode(true);
@@ -338,10 +344,15 @@
$A(table.tBodies[0].rows) : $A(table.rows).without(table.rows[0]);
},
addRowClass : function(r,i) {
- r = $(r)
+ //r = $(r)
+ /*
r.removeClassName(SortableTable.options.rowEvenClass);
r.removeClassName(SortableTable.options.rowOddClass);
r.addClassName(((i+1)%2 == 0 ? SortableTable.options.rowEvenClass : SortableTable.options.rowOddClass));
+ */
+ SortableTable.removeClass (r, SortableTable.options.rowEvenClass);
+ SortableTable.removeClass (r, SortableTable.options.rowOddClass);
+ SortableTable.addClass (r, ((i+1)%2 == 0 ? SortableTable.options.rowEvenClass : SortableTable.options.rowOddClass));
},
getHeaderCells : function(table, cell) {
if(!table) table = $(cell).up('table');
@@ -401,11 +412,36 @@
});
});
}
+ },
+ // Determine if an object or class string contains a given class.
+ hasClass : function(obj,className) {
+ if (!defined(obj) || obj==null || !RegExp) { return false; }
+ var re = new RegExp("(^|\s)" + className + "(\s|$)");
+ if (typeof(obj)=="string") {
+ return re.test(obj);
+ }
+ else if (typeof(obj)=="object" && obj.className) {
+ return re.test(obj.className);
+ }
+ return false;
+ },
+ // Add a class to an object
+ addClass : function(obj,className) {
+ if (typeof(obj)!="object" || obj==null || !defined(obj.className)) { return false; }
+ if (obj.className==null || obj.className=='') { 
+ obj.className = className;
+ return true;
+ }
+ if (SortableTable.hasClass(obj,className)) { return true; }
+ obj.className = obj.className + " " + className;
+ return true;
+ },
+ // Remove a class from an object
+ removeClass : function(obj,className) {
+ if (typeof(obj)!="object" || obj==null || !defined(obj.className) || obj.className==null) { return false; }
+ if (!SortableTable.hasClass(obj,className)) { return false; }
+ var re = new RegExp("(^|\s+)" + className + "(\s+|$)");
+ obj.className = obj.className.replace(re,' ');
+ return true;
}
}
-
-if(FastInit) {
- FastInit.addOnLoad(SortableTable.load);
-} else {
- Event.observe(window, 'load', SortableTable.load);
-}
No newline at end of file

#93
On the September 3, 2009, Ali wrote:

Hi guys,

I love this script. extremely useful and easy to understand. I am running into minor issue though, same as Tom posted above in post 6. Sorting issue with numerals and text. If there are numbers and chars in a column sorting is working every 3rd time. I think Tom explained it better. Let me know if there is a solution to this problem.

thanks

#94
On the September 3, 2009, jehovahmyhealer wrote:

I love your script, however I am trying to figure out how to implement it with Struts. I am unable to figure how to pass the cell values with my struct action.

#95
On the September 10, 2009, Andy Noyes wrote:

Hi Andrew,

Thanks for sharing this! I had a bit of a problem with the fixed header of a scrolling table having column widths that didn't match the content rows.
I fixed it by changing 
table.setStyle({
'border-spacing': '0',
'table-layout': 'fixed',
width: w + 'px'
});
to:
table.setStyle({
borderSpacing: '0',
tableLayout: 'fixed',
width: w + 'px'
});
in both places that construct is used.
Thanks again!

#96
On the September 23, 2009, Rev2Red wrote:

I've been able to implement this successfully but I'd like to add from scriptaculous, the ability to drop out a TR. I have each row uniquely identified and I can drop out a TR just fine. What I would like to know how to do is when deleting a tr to have the remaining colors update so that there aren't two colors on top of each other.  

#97
On the September 30, 2009, Bob wrote:

I'll start with I am learning Javascript and that is probably my problem. I was able to implement tablesort.js and use it in several pages I am developing. On one page i wont the scrolling, But I don't want the page striped. 
I tried using this in my script.

  SortableTable.setup({
options : {rowOddCLass : 'nostripe',
rowEvenClass : 'nostripe'
  }
  });

I setup a css class of nostripe to have no background color. But I still get the striping. is it possible without making an inline style to address not having striping in my table?

#98
On the November 11, 2009, Siva wrote:

its nice.Its works fine i want change height and width of the each rows.How i can change manually through coding.please help me.Advance thanks to you
Thanks & Regards
Siva

#99
On the November 17, 2009, Mike wrote:

I am creating a table using three different xml files and can't seem to get this to work. I have set my header row, which is actually two rows of which the first is a merged set of columns to act as a main heading and row two are the individual components of row 1. These header rows all fall within the thead tag and are populated from 1 xml.
The body of the table is between the tbody tag and is populated from another xml file.

I am also looking into populating a document list for each row of the body as a sort of sub table; this will only show once a user clicks on a row of the table, and only one row will show at a time. Do you think this will cause issues with the tablesort script?

#100
On the December 3, 2009, Shaokun wrote:

I patched this awesome tablesort to support rowspan table. Check it out on my github: http://github.com/shaokun/prototype_tablesort. And there is also an article about it: http://www.kudelabs.com/2009/12/03/rowspan-supported-table-sorting-with-prototype

Leave your comment


HTML tags will not work. Your email address will never be displayed. If you have a Gravatar we'll display it.

Random outings from a chaotic mind

The Dexagogo Rocket Australian Web Industry Association logo

Delicious

Twitter