My first free Sunday morning in what seems like an epoch produces a complete rewrite of the original (and by far most popular) lab experiment, the “Unobtrusive Table Sort Script”, that addresses speed issues present within version #1.
At a glance…
- Plays nicely with the JavaScript global namespace (the script creates and reuses only one JavaScript object)
- Multiple columns can be sorted at once by pressing Shift while selecting the columns using either the keyboard or mouse
- The new script sorts (on average – based on my very non-scientific calculations), 5 times faster than its predecessor
- The plug-in architecture makes writing custom sort functions a breeze
- The script can highlight both alternate rows and full columns on a table by table basis.
- Like its predecessor, the script is fully keyboard accessible
- The script can correctly determine a columns datatype should a datatype not be explicitly defined (datatypes determined are limited to numbers, text, currency values and dates)
- The script is smart enough not to sort columns containing identical data
- Sort routines can be initiated using JavaScript
- Tables can be automatically sorted on a column (or columns) of your choice, even in reverse order
- Before-sort and after-sort callback functions (or Object.methods) can be defined for individual tables
The Slowdown
The original script attempted to grab the inner text of every TD node within the column to be sorted, each and every time the sort routine was activated. This was an extremely processor intensive action and the main cause of slowdown during the sort of large tables. While a limited “cache” system was offered, it relied heavily on use of the JavaScript “in” operator, which is itself notoriously slow to process.
Speeding things up
The new script addresses these issues by creating and storing an internal representation of the parsed table data the very first time that one of the table’s sortable TH nodes is activated (i.e. a 2D matrix of the parsed table data).
The data stored within this internal object is then reused during each subsequent sort action. This means that there is a slight processing overhead the first time the sort is activated (as an internal representation of the table’s data has to be created) but subsequent sorts, on any of the table’s columns, are much faster than in the previous incarnation of the script.
A listing of sample sort times for a 100 row table can be located within the dynamic table creation demo.
Sortable datatypes
The script can currently sort dates (dd-mm-yyyy, mm-dd-yyyy or yyyy-mm-dd formats accepted), currency values (£, $, €, ¥ and ¤), numbers/floats and finally, plain-text (sorted in a case-insensitive manner). Additionally, the character used as the date divider (i.e. the character that separates the date parts) can be “/”, “-”, “.” or “ “ (space).
Should you need to sort a bespoke datatype, the script can easily be extended by providing a custom sort function.
Making any column sortable
To make any table column sortable, just give the associated table header (TH) tag the class sortable, the script will automatically determine the column datatype, make the entire table header clickable (and not just the text contained within) and create the appropriate up/down arrow within the header when clicked (using the ↑ & ↓ characters).
An example showing the most basic classes required by the script is shown below:
<table id="test1">
<thead>
<tr>
<th class="sortable">Rank</th>
<th class="sortable">Movie</th>
<th class="sortable">Release Date</th>
<th class="sortable">Weekly Gross</th>
<th class="sortable">Change</th>
</tr>
</thead>
... snip ...
</table>
Forcing a columns sort algorithm
Should a column contain a mix of datatypes (or should you know the column datatype in advance), it is advised that you explicitly set the sort algorithm by adding one of the following classNames to the associated table header (TH) tag: sortable-numeric, sortable-currency, sortable-text , sortable-date, sortable-date-dmy or sortable-keep (which keeps the row in it’s original order).
An example showing how the column datatypes can be specified within the TH classNames is shown below:
<table id="test1">
<thead>
<tr>
<th class="sortable-numeric">Rank</th>
<th class="sortable-text">Movie</th>
<th class="sortable-date-dmy">Release Date</th>
<th class="sortable-currency">Weekly Gross</th>
<th class="sortable-numeric">Change</th>
</tr>
</thead>
... snip ...
</table>
It is recommended that you always try to stipulate the column datatype as shown in the above example as this speeds up the initialisation process (as the script no longer has to parse the column data in order to determine the column datatype therefore saving precious clock cycles).
A note on the date format
The script currently favours the American date format of “mm-dd-yyyy”. This is the first format that all dates are tested against during the data preparation phase, which means that European dates such as 10-08-2006 (i.e. the 10th August 2006) will be parsed as the 8th October 2006.
Should your dates be of the European format “dd-mm-yyyy”, add the class sortable-date-dmy to the TH node instead of the class sortable-date, this will tell the script to attempt to parse a DMY format date before attempting to parse a MDY format date.
A note on sorting numeric data
The sortNumeric method bundled with the source code is quite ruthless with the data passed to it. It will replace any character not valid for use within a floating point number and then attempt to parse a float from the result.
This means that the sortNumeric method can be used to sort all manner of numeric column data, for example; columns containing percentages e.g. -22%, 34.6% etc do not require a bespoke sort function in order to be sorted – giving the column the className sort-numeric will suffice.
Forcing a column to “reverse sort” by default
Should you wish to sort a column in reverse order by default, just give the associated TH node the className favour-reverse (Note the English spelling of favour). The default reverse sort is only taken into consideration when sorting on a single column.
Sorting the table automatically
The script will automatically sort any table that has been given the class sortable-onload-N immediately after the window.onload event fires – where N specifies a className of the form “-colNumber[ r ]” – with “colNumber” being replaced by the integer value of the column to sort and the optional “r” (remove the square brackets and spaces!) stipulating that the
column is to be sorted in reverse.
Multiple columns can be stipulated at once, for example, the classname sortable-onload-3r-4r-5 will automatically sort the table on column 4 (reverse sort), then column 5 (again, using a reverse sort) and finally, column 6.
Please note: the column index starts at 0 and not 1.
Preparing an already sorted column
If you have already sorted the table on a specific column or set of columns when the page is generated, it is necessary to indicate this to the script.
This can be done by adding the following className to the table sortable-onload-show-N, where N specifies a className of the form “-colNumber[ r ]” i.e. an identical className to the form discussed above.
This enables the script to create the appropriate up/down arrows within and set the appropriate className on the table headers without it having to actually sort the table data.
Row and column highlighting
The script enables both row and column highlighting.
Zebra striping the table rows
Should the table be given the class rowstyle-something, each alternate table row is given the class something after the table has been sorted i.e giving the table a class of rowstyle-alternate will tell the script to give each alternate row the class alternate.
If you are not using the “sortable-onload-X” or “sortable-show-X” classNames but still want the table to be zebra-striped on page load, just give the table the className “onload-zebra”.
Highlighting the currently sorted column
Should the table be given the class of colstyle-something, each TD node within the sorted column is given the class something after the table has been sorted i.e giving the table the class colstyle-alternate will tell the script to give each TD node within the sorted column the class alternate.
Sorting multiple columns
The script can now sort multiple columns. Just hold down the Shift key while selecting the columns to sort (either with the keyboard or with the mouse).
Stipulating custom sort functions to use
Should you wish to stipulate your own custom sort function, add the class sortable-yourCustomFunctionName to the table header (TH) tag; for example, adding the class sortable-myCustomSortFunction will tell the script to call a JavaScript function named myCustomSortFunction in order to sort that column’s data.
The name of your custom sort function may only contain letters (a-Z) and the underscore character. Function names containing other characters will not be recognised.
The function name has been limited in this way as it is defined within a className, which itself can only contain a subset of the full ASCII character set i.e. while “$” is a valid JavaScript function name, it is not a valid character to use within a className.
Available custom sort functions
A few custom sort functions have been written and made available for those who might need them. They currently include:
- A function to sort by IP address
- A function to sort English longhand date formats e.g. 12th April 2006
- A function to sort (English) dateTime e.g. 12th April 1992 at 13:44:23
- A function to sort twelve-hour timestamps e.g. 12:32a.m.
- A function to sort numbers stipulated in Scientific Notation e.g. -32.45 e 0.32
- A function to sort on fileSize i.e. 22kb, 3mb, 1.3gb
- A function to sort images on the value of their “src” attribute
- A function to sort alphaNumeric data e.g. a, b, 1a, 2d, 33.4z, -2.4s
The functions can now be seen in action on their own custom function demo page.
Preprocessing the column data
Should your custom sort function require more than just the inner text of the TD node or should you wish to keep your custom sort as fast as possible, it is necessary to write a complimentary “prepare data” function. This function is called just once, during the creation of the data object for the table. The function should have the same name as your custom sort function with “PrepareData” added to the end.
An example custom sort function
In order to write a custom sort function “sortImage” that sorts images within the table’s TD cells using the value of their “src” attribute, two functions are required; “sortImage” and “sortImagePrepareData”.
The “sortImagePrepareData” function will be used to parse the image’s “src” attribute, which is then stored within the table’s data object to be used during the sort routine e.g.
// Returns the "src" attribute of the first image
// "PrepareData" functions are passed both the TD node
// and the TD node's inner text. In this case, we use the
// tdNode and not the inner text.
function sortImagePrepareData(tdNode, innerText) {
var img = tdNode.getElementsByTagName('img');
return img.length ? img[ 0 ].src : "";
}
The “sortImage” function will then use this data during the sort i.e:
// Uses the data prepared in “sortImagePrepareData”
function sortImage(a, b) {
// Get the data for the current column from the
// two arrays passed in as arguments like so…
var aa = a[fdTableSort.pos];
var bb = b[fdTableSort.pos];
// Sort the data
if(aa == bb) return 0;
if(aa < bb) return -1;
return 1;
}
The “PrepareData” functions are not obligatory and are only called by the script if they exist.
It is worthwhile to note though, that sort routines will be much faster whenever the column data has been parsed in advance by an associated “PrepareData” function.
A few more custom sort function examples (including the above “sortImage” function) can be viewed in the custom sort functions demo
Initiating the sort process using JavaScript
As it was an uncommonly-common request for the first version of the script, the abilty to initiate the sort using JavaScript has been integrated into the rewrite. To initiate a sort, call the following method:
fdTableSort.jsWrapper(yourTableId, colNums);
Passing in the id of the table to be sorted and either an Integer stipulating the position of a single column to be sorted, or an array stipulating a set of columns to be sorted i.e. the following JavaScript statement:
fdTableSort.jsWrapper("salesTax", [0,1,4]);
will initiate the sort routine on columns 0, 1 and 4 of the table with an id of “salesTax”. An example of initiating the sort routine in this way can be seen within the JavaScript initiated sort demo.
Please note, if a callback function has been defined, in this case, it is not called after the sort routine completes.
Indicating the sort is underway
Very large tables may take a while to sort which, without some sort of feedback, may leave users slightly bewildered as to why nothing seems to be happening after they have just clicked the table header.
To enable you to provide this feedback, both the page BODY and the TH node clicked by the user are temporarily assigned the class sort-active. This enables you to create appropriate styles that visually indicate to the user that the sort is underway (adding an animated gif to the background of the TH node for example). After the sort is complete, the class sort-active is removed from both the BODY and the TH nodes.
An example of using the sort-active className can be viewed within the Dynamic table creation demo – the currently active TH node displays an hourglass during the sort.
The callback functions
The script now includes the ability to call bespoke “callback” functions. The first function “sortInitiatedCallback()” is called immediately before the sort routine fires, the second function “sortCompleteCallback()” is called immediately after the sort routine completes. The two callback functions are passed the ID of the table as an argument.
Additionally, callBack functions can now be created for individual tables by creating a function named sortInitiatedCallbackXXX or sortCompleteCallbackXXX where XXX represents the ID of the table; for example, the script will attempt to call the function sortInitiatedCallbackTestTable and sortCompleteCallbackTestTable for a table with an ID of “TestTable”.
Stipulating Object.methods or bespoke JavaScript functions as a callback
You may wish to use an Object.method or a bespoke JavaScript function as a callback, to do this, just add one (or both) of the following class’s to the table’s className:
The className sortinitiatedcallback-XXX stipulates a function that will be called before the sort initiates, where XXX should be replaced with the name of the function in question.
Object.methods can be stipulated by converting the “dots” (i.e. the full-stops) to minus signs (-); for example, the className “sortinitiatedcallback-myObject-myMethod” will tell the script to call the “myMethod” method of the JavaScript Object “myObject” e.g. myObject.myMethod();
The className sortcompletecallback-XXX stipulates a function to be called after the sort has taken place. again, the XXX is replaced in an identical fashion to the XXX within sortinitiatedcallback-XXX.
Please Note: callback functions are only called should they exist so don’t fret about creating them should you not require the callback functionality.
An example of using a callback function can now be viewed within the callback function demo.
Creating your own progress indicator
Using callback functions in this way enables you to define your own progress indicator that appears whenever a sort is initiated and disappears when the sort completes.
Table pagination
As lots of people have been asking for the functionality, I’ve written a table pagination script that, as the name suggests, paginates tables automatically (i.e. splits large tables into smaller chunks). More information on the pagination script can be located within the article Client-Side Table Pagination Script.
Please Note: The pagination script does not rely on the tableSort script and can therefore be used independently of it.
Using images for the arrows
This version of the script enables images to be used in place of the arrows. The images should be defined within your CSS as follows:
th.forwardSort
{
background:transparent url(your-down-arrow-image) no-repeat 0 0;
}
th.reverseSort
{
background:transparent url(your-up-arrow-image) no-repeat 0 0;
}
Additionally, the table should be given the class no-arrow which tells the script not to create the default arrow characters within the TH node.
Keeping things fast…
There are a few things that you can do to keep the script from slowing down:
- Always stipulate the column datatype by using one of the explicit classNames sortable-date, sortable-date-dmy, sortable-numeric, sortable-currency, sortable-keep or sortable-text. Explicitly defining the datatype in this way means that the script does not have to try to deduce the column datatype and therefore saves many clock cycles during the initial data preparation phase.
- Don’t use column highlighting on large tables as it takes time to grab the TD nodes and add or delete the appropriate class.
- Write an associated “PrepareData” function for each of your bespoke sort functions.
A note for the Ajax’ers
Whenever you re-render a table (from an Ajax callback), just call the method fdTableSort.init, passing in the ID of the table that was just re-rendered. This will remove the original cached data object for the table in question and make sure an up-to-date version is created the first time the table is again sorted.
Calling the fdTableSort.init method with no arguments will clear all of the currently cached data objects and re-initialise all sortable tables.
Installing the script
Just add the following code within the HEAD section of your HTML document (remember to change the filepath to suit your installation):
<script type="text/javascript" src="/the/path/to/tablesort.js"></script>
...and give both the TABLE and TH tags the required classNames (all classNames have been described within the article). Thats all there is too it.
The “table actions” plug-in
After countless requests, I’ve written a table actions plug-in to the script that enables zebra-striping, row selection and complex row, cell and column highlighting effects. More information can be found within the table actions post.
The License
The script is now released under a creative commons Attribution-ShareAlike 2.5 license. Should you use the script within a commercial context please think about clicking the payPal donate button – it’s certainly not an obligation but it would most certainly put a smile on my face.
Translations
An Italian translation of this article has been located at Consulente Informatico. Many thanks to Sergio Gandrus.
References
The snazzy CSS and background images used to style all demo tables were created by Veerle Pieters.
Demo, downloads and updates
Tested in Internet Explorer 6 & 7, Opera 9.01, Safari 3.0.3 (Windows) and Firefox 3.
View the table-sort demo, the custom sort functions demo page, the basic pagination demo, the sortCompleteCallback demo, the static column data demo, the Dynamic table creation demo, the secondary/tertiary sort demo or download the 41k uncompressed JavaScript source code or a 21k YUI minified version of the source code.
21/10/2008 (v5.0):
- Callback function now called using method.apply
15/04/2008 (v4.9):
- Fixed a bug that didn’t zebra-stripe identical columns stipulated as “sortable-onload”
22/03/2008 (v4.8):
- Fixed a column highlighting bug
06/03/2008 (v4.7):
- Fixed a bug that stopped the hourglass showing during sorts
03/03/2008 (v4.6):
- Fixed a bug with the “sortable-onload-” functionality
- Integrated the “favour-reverse” functionality that means you can now stipulate that columns are to be sorted by default in reverse order
- Added the secondary/tertiary sort demo
01/02/2008 (v4.5):
- Changed the code to not remove child IMG nodes from sortable TH nodes
21/01/2008 (v4.4):
- zebra table support when the table className contains “onload-zebra”
27/12/2007 (v4.3):
- Embedded table support
19/12/2007 (v4.2):
- Added the ability to stipulate Object.methods as a callback function
- Better integration with the pagination script to remove the “flicker” present in previous versions as the pagination script redrew the table
14/12/2007 (v4.1):
- Added the ability to sort multiple columns onload
- Added the ability to “show” multiple presorted columns onload
- Changed the addClass and removeClass methods
- Separated the “redraw” code into it’s own method
15/11/2007 (v4.0):
- Fixed a Safari2 bug
23/10/2007 (v3.9):
- Added the “sortable-onload-show-N-reverse” functionality (thanks to Brett Harrison)
04/10/2007 (v3.8):
- Added the multi-column sort functionality
- Deprecated the
sortDatemethod
28/05/2007 (v3.7):
- Fixed a bug that referenced getElementsByClassName and not getElementsByTagName
16/05/2007 (v3.6):
- Fixed a bug introduced within the last revision
05/04/2007 (v3.5):
- Fixed an identical column data bug
03/04/2007 (v3.4):
- Added a fix to support nested tables (Note: the solution requires that the parent table must have a tbody) – thanks to Chris for the fix
22/03/2007 (v3.3):
- Worked on Internet Explorer memory leaks
- Added code to correctly cleanup internal objects for the Ajax’ers
20/03/2007 (v3.2):
- Added a “sortable-keep” option
- Altered the jsWrapper function to not use the callback functions
- Unique callback functions can now be created for each table
02/03/2007 (v3.1):
- Fixed a bug in the parseDate method
- Removed a block of code that caused problems with dynamically created tables
- Fixed a few bugs in the custom sort functions
19/02/2007 (v3.0):
- Fixed a bug in the jsWrapper method
- Added rowspan support
- Many internal changes dealing with colspan & rowspan support
30/11/2006 (v2.9):
- Added the ability to have colspan’s within the non-sortable TH nodes
- Added a workaround for a Netscape 8.1.2. bug that crashed the browser when the script was initiated
- Added a disableTextSelection method that, not suprisingly, disables text selection on sortable TH nodes (in order to stop the browser highlighting the text within the node when the onclick event fires)
07/11/2006 (v2.8):
- Added the “automatic reverse sort” code.
- Changed the dateFormat function to accept a second parameter that tells the script to favour European d-m-y format dates
- The sortInitiated and sortComplete callback functions now get passed the ID of the table as an argument
02/11/2006 (v2.7):
- Changed the code to handle multiple TR’s within the table’s THEAD.
- Fixed an uppercase TFOOT reference
19/10/2006 (v2.6):
- Changed the license
12/10/2006 (v2.5):
- Fixed a bug when setting previously undefined classNames
04/10/2006 (v2.4):
- Altered the “prepareTableData” method to accept TD nodes that have no child nodes
02/10/2006 (v2.3):
- Altered the “prepareTableData” method to trim whitespace from the TD node’s innerText
18/09/2006 (v2.2):
- Fixed a bug within the sortNumeric method when sorting zero values
18/09/2006 (v2.1):
- Changed the sortNumeric method to be more robust
- Added a check to see if a TD node is a child of a TFOOT
- Changed the script to work with tables that have no THEAD or TBODY
- Rewrote the custom sort functions to adhere to the new “PrepareData” architecture

Previous Comments ~
Hi,
nice script. I am going to use this for my hobby testpage. Very usefulll…
I do not understand too much of JS but I think your script is bettter then the one I used before: http://www.workingwith.me.uk/articles/scripting/standardista_table_sorting
Can I still use this script, once my page becomes comercial?
Could you post an install instruction (I had to go into your demo scource code to install it)
thanks in advance,
Luis
Great, was always wondering if this was possible. Nice webpage
Please use a little biger default text size. People abobe 37 do not read small fonts easily. Thanks.
I am having trouble using your script. (win/nix,ie,ff)
The error message I am receiving is “txt has no properties”
I scanned over your code and I believe the reason it’s breaking in my application is related to the line:
“var start = table.getElementsByTagName(‘tbody’);”
Our legacy code builds datagrid tables but does not use the tbody tag.
Is there a way to use your script on tables that do not use tbody?
Thanks.
It’s great, but it would be perfect if you could constrain the height and have a vertical scrollbar appear appropriately . . .
Nice script.
One pedantic point, though: the possessive form of the word “it” is not “it’s” but “its”.
@ Louis: Yes, this script is free for commercial use – but you can always use the “PayPal Donate” button should you be feeling generous! I’ll try to add a short “Installation notes” paragraph to the write-up.
@ Int: Do you mean the main article text-size (which should be set as 12px) or the comment text size (which should be set at 10px)? Thanks in advance.
@ John: Hi John, I think that your looking for something like Cody’s Pushpin header technique
@ Me: Ummm, thanks!
@ Scotts: Thanks for the warning. I’ve altered the script to fix the problem.
@ Björn: Yep, your right, after speaking almost no English for four years my English language “powers” have diminished rather rapidly. I shall update the post tout de suite.
Great script, especially the caching. Really well written JavaScript, too, which is rarely seen!
@ James: Hi James, thanks for the kind words (when I start to write JavaScript as well as Dean Edwards I’ll be a happy man indeed).
Ah yes, but when your website design gets as bad you’ll be an unhappy man.
This is a very nice script … one small request or item to build on …
Im wondering if its possible to virtually paginate over a large result set via Ajax using this script. For example, 100 items, 10 per page, on sort repopulate the same DOM structure. I guess what Im trying to find out is if the data portion of the script is plugable to allow it to populate over records not visible in the table?
Im probably not making sense, just that I already have a paginated table + want to add this sorting library to it but need it to span over all the records. Any ideas?
Great script.
@ Jon: Hi Jon, the current script creates it’s data object using the innerText of the TD nodes and currently isn’t “pluggable” (is that even a valid word?). You could add a method to the script that accepts a JSON response from the Ajax callback and recreates the data object using the JSON data.
Calling the fdTableSort.init() method after the Ajax callback i.e. after the new table has been rendered, will reinitialise the script but the sort will only ever sort cell data that is present on screen (and I think that you want to sort the 100 records, not just the 10 present on the screen).
Particle Tree have an article about preloading data using Ajax that might be helpfull.
Sorry I can’t be more help,
Brian
@ Dinesha: Thanks.
You state earlier that
In the source code though the licence is creative commons nc-sa which means “Noncommercial. You may not use this work for commercial purposes”
So, which one is it ? :)
Thanks for making that code available in any case.
@ Arnaud: The script is released under a Creative Commons Attribution-NoDerivs 2.5 license.
This is now stated within the source code.
Regards,
Brian.
You can extend this script with simple css to a fixed header scrolling table by adding the following css attributes:
tbody {
overflow-y:auto;
overflow:-moz-scrollbars-vertical;
width:100%;
height: 500px;
}
@brian: thank you !
Damn well done! This certainly goes into the bookmarks, the list of features just goes on and one.
Cool except the sort direction arrows are going the wrong way in the demos
V should be largest on top to smallest on bottom, and ^ should be smallest on top to largest on bottom
@ Matt: Thanks for that, it’s a useful modification.
@ Arnaud: No problem, glad you find it useful.
@ Emil: Hi Emil, it’s always a pleasure to be bookmarked. You just gotta love your gravatar B.T.W. (note to self: get a bleeden gravatar that doesn’t suck)
@ Oolon: A clear case of “I looked at it so much that I just didn’t notice” (it made me chuckle though). I’ve changed the CSS to display the arrows properly. Thanks for the info.
On my numeric columns, the zero values are sorted before the negative values. For example, the sort is 0, -1, 1, but I am expecting -1, 0, 1. I have tested letting the script determine class, and setting the sort class.
@ Bill: Yeah, a bug!
In fact, it was a dumb error within the sortNumeric method (I used ”==” and not ”===” when comparing values). I’ve fixed the problem and updated the downloads. Apologies to everyone who has already downloaded the source code (as you will need to download it again)!
Thanks for the info,
Brian.
You Rock!
Brian,
I took your suggestion from above, and i run re-initialize the table onComplete of an ajax.Updater call. This works perfectly, except that the alternate row styles lump together. On your demo, they maintain proper spacing. When I do it, they maintain their original position, so you have clumps of alternate rows together as well as clumps of non-alternate rows.
Do you have a suggestion on what might be causing this?
thanks!
Charles
Brian, it was user error :P
I must have messed up the CSS somehow which caused issues.
I haven’t done a diff yet to see what I did wrong the first time. I took your demo code and modified it a piece at a time until the format matched what i originally wanted. There has to be a typo in there somewhere…
thanks again :P
This is just like how your cold goes away once you visit the doctor…hehe
@ Cody: Hey Cody… your wrong man, you rock (and wasn’t that your mugshot I saw in jQuery magazine ?)
@ Charles: It must have been the class “rowstyle-something” that was missing from the table className. Glad to hear it’s fixed.
Regards,
Brian
wow, the best version ever
need it for a little project, thanks dude
Very nice page(appearance,reaction).
I really love this script, however, I have a problem with sorting large numbers.
if these numbers: 1,5,8,100,800 where sorted in descending order, it should produce: 800, 100, 8, 5, 1 however, it produce 8, 800, 5, 1, 100 which is very wrong.
I hope there is some simple way to sort this out :)
Cheers
GK
@ Bryan: Thanks.
@ Stephen: Hi stephen, I can’t reproduce the problem (a test table containing identical data sorts properly for me). Have you stipulated “sortable-numeric” within the associated TH node’s calssName? If not, perhaps the script is resorting to a text based sort (it shouldn’t, the script should realise the data is all numeric – this might be another bug entirely!) which might skew the results.
Regards,
Brian.
@ Brian: Whoopse, I was putting class=”sortable sortable-numeric” hoping it would sort it but it didn’t. Having removed the first sortable it now works :) but it must be some sort of bug no detecting the datatype correctly since all the data in the column are integers.
Update: Hi Stephen, it was indeed a bug within the code. I've updated the download to include a fix for the problem.
Many Thanks
GK
I have to say this is an awsome js. I have noticed some strange behavior though and was wondering if anyone else has the same problem. If you have a table where every row has the exact same data in the 1st collumn and you set sortable-onload-0, it won’t zebra stripe the rows when the page first loads. Anyone know what a possible fix might be for this?
Typo in previous post:
should be “sortable-onload-1”
@ Brian: Hi Brian, the script will not actually sort a column that has identical data, this is intended functionality. It’s really up to you to create the initial table with the zebra-stripes – this way, users that have javascript turned off will still get a nice zebra-striped table.
Should you really wish to zebra-stripe tables with identical column data, then remove lines 314 – 318 within the “initSort” method (but be aware that this means that the script will now sort columns containing identical data which means that adjacent column data gets moved in a somewhat nonsensical manner).
Hope this helps,
Brian.
I can’t zebra-stripe tables. If the table class is class=”rowstyle-alternative”, then in the rendered javascript source I can see this alternative TR classes:
class=”” and
class=”rowstyle-alternative”
Notice the white space before word “alternative” in the tr class.
Thanks anyway for this very nice script.
Renerea.
Sorry, there is a mistake in my previous comment:
I can’t zebra-stripe tables. If the table class is class=”rowstyle-alternative”, then in the rendered javascript source I can see this alternative TR classes:
class=””
class=” alternative”
Notice the white space before word “alternative” in the tr class.
Thanks anyway for this very nice script.
Renerea.
One more.
In your demo page: http://www.frequency-decoder.com/demo/table-sort-revisited/, look at this alternative tr classes that the script makes:
The firt time page loads: – TR class=undefined – TR class=”undefined alternative”
When you sort first time: – TR class=”undefined undefined” – TR class=”undefined undefined alternative”
When you sort second time: – TR class=”undefined undefined” – TR class=”undefined undefined undefined alternative”
The third time: – TR class=”undefined undefined” – TR class=”undefined undefined undefined undefined alternative”
And so on.
@ Renerea: I’ll look into it. It appears easy enough to fix.
Update: Well, that's a FireFox "quirk" I've never seen before. Normally, polling the className of a DOM node will return an empty String whenever the DOM node has not yet been assigned any classes. The latest FireFox seems to return "undefined".
I've changed the code to check the "typeof" the className before setting the column/row classes and it appears to have fixed the problem.
P.S. I haven't tried using the node.getAttribute method (which might just return an empty string - then again, it might just return "false").
Thanks for the heads-up.
Regards,
Brian
Your demo of this scripts looks fantastic.
I would love to implement this script on a site I am working on, but I have a small problem…
I can’t seem to get the script to initiate.
The JS is included in the head properly (and I have not made any changes to the .js file whatsoever. Also, I have replaced the opening < with a # to get it to display here): #script type="text/javascript" src="/_scripts/table-sorter/tablesort.js">#/script>
The table is created with a proper structure; I show up to and including the thead (I have replaced the opening < with a # to get it to display here):
#table id=”theTable” class=”sortable rowstyle-alternative” width=”100%”>
#thead>
#tr>
#th class=”sortable-text”>Name#/th> #th>Address#/th> #th class=”sortable-text”>City#/th> #th class=”sortable-text”>Postcode#/th> #th>Telephone#/th>#/tr>
#/thead>
I am sure I am just being an idiot; can anybody shed some light on how to ensure the script is picking up the table and doing its magic to it?
@ JavaScript Noob: Hi, try adding an alert(‘hello world’) as the first line of the tablesort.js “init” method (line 42).
If you reload the page and don’t get the “hello world” alert then something included after the file has overridden the window.onload event (has you page a BODY onload=... for example ?)
Hope this helps,
Brian.
Hi,
I have tried this; I don’t appear to be getting the alert message.
I have now created a new page, with the JS being linked within the head of the document.
A simple 6-column table has been added, with the table tag having a class of “sortable-onload-6 rowstyle-alternate”
The table headers have a class of “sortable-text” and the rows below are filled with single letters (see example below):
| a | g | z |
===
| p | r | e |
===
| c | e | u |
This doesn’t seem to work either. No alert. No sorting (even with the alert removed from the JS). No alternate row classes applied.
There doesn’t appear to be no client-side JavaScript issues, as sIFR is working on the rest of the site (but is not included with the simple page I have created).
Any ideas what I am doing wrong?
How do I change the color of the headers? They’re all white I’d like to make them somethin different please :D
nevermind LoL… had some conflicting CSS… great script though :D thanks a lot
I have a really basic question (I hope). First off, the script works wonderfully, from a functionality standpoint. However, the table that I’m sorting is heavily formatted with an internal CSS which is now being overwritten by the formatting of the script; essentially everything that’s been tagged with ‘th’ (only the columns I want to sort). I’m trying to get around this and so far the only concept that seems like it will work is for me to create a custome sort-type for each column and then format them using something akin to ‘th.newsorttype’. The problem is that I have no java experience so when I tried to look at the .js source code in hopes to “copy/paste” the code for the text/date/numeric sort types to create my own…. well, I have no idea where to begin or how to write my own from scratch.
If anyone has any thoughts, suggestion or help – I would be so totally greatful.
I’ve been playing around with it some more and have made some headway; though I’ve had no success in creating any custom sort functions, I’ve just been “working” with the existing ones: sortable-text, etc. If anyone has any input on that, I’d still GREATLY appreciate it.
For some reason I’m unable to get the text of the column headers to all stay a single color, and that color’s “white.” I think I’ve copied over every possible “th” tag that’s in the demo’s source and implimented it into my own; and changed every single value to #FFFFFF but still they refuse to change and revert back to the “default” blue. I have been able to get the “active” sorted text to stay white…. but that’s not quite good enough… :(
@ JavaScript Noob: Send the .html (if it’s a dynamically created page, do a “view source”, copy, paste, save; and send me the saved file) to brian [at] modernartcafe [d0t] net and I’ll look into it.
@ Lucas: Good to hear you sorted it out.
@ Chris: Hi Chris, the script only sorts and rearranges the table rows, all of the row’s “styles” will be kept after the sort (the table overwrites no classNames etc) so I don’t understand how the script is restyling the table. Again, send the .html and the .css files to brian [at] modernartcafe [d0t] net and I’ll look into it.
Regards,
Brian.
@ Chris: Check that out, you posted your comment 4 seconds before me! Anyway, were talking a CSS problem here, not a JavaScript problem. If you want all the TH nodes to contain white text, this has to be specified within the CSS, for example:
th, th a { color:#fff !important; }
Hope this helps,
Brian.
It seems that you have not been updating the european version. It didnt worked, but the other one did.
The problem stated in the #37 seems to be still present. I am using Firefox 1.5.0.7
Thanks again.
Well, I’m not sure how the format for the CSS was being tossed aside…wait, yes I do (I think). Each of those headers that now has a class of “sortable-___” previously was defined by a class from my CSS, so I think that’s what the problem has been. I would like to note however that that one (fricken) line you gave me totally fixed the problem I was having :) Yea!!!—————————————————————————————————————-
If at all possible, I would still like to get the code for creating those custom functions for numeric and text because I think my code – while working – is extremely bloated now… but it works!! Brian, your script is awesome and your help phenomenal, thanks!
@ Merucry: Hi, the “undefined” className problem has been fixed and the European version updated accordingly (I’m using the FireFox “View Source Chart” extension to check the classNames). Remember to clear the browser cache in order to download the new version (when looking at the demo).
@ Chris: Glad you got it sorted out. I’m still unsure as to why you want to write custom functions for numeric and text values when the script contains two such functions already.
Regards,
Brian.
Hi Brian,
Your table sort functions work perfectly on my site.
Fantastic peace of software!
But when I switched over to the European date version, I got a syntax error on line 346 char. 10.
The errror is not obvious to me, so I can not fix it.
Please have a look into this.
Keep up the good work!
Bill
@ Bill: Download the updated version.
Regards,
Brian.
First of all, thank you for spending your time supporting your script.
I am using your script right now and everything is great, but being a javascript newbie i’m not sure how to modify the code to reverse sort a column or sort it twice on load? Do you think you can point me into the right direction?
-THANKS
@ Max M: Off the top of my head, you could try this…
function myDoubleSortOnLoad() {
fdTableSort.jsWrapper(“yourTableId”, colNum);}
fdTableSort.addEvent(window, “load”, function() {
setTimeout(“myDoubleSortOnLoad()”, 2000);});
it’s a dirty hack and extremely bad programming practice but there you go…
How can I store the sort order in a cookie? Is there a step by step explaination anywhere for dumb people?
Hmm when I tried your dirty hack, it didn’t work and made it where the table became unsortable.
The double sort actually isn’t too important to me, but what i would like to be able to do is have alternating colors without having to identify a class, because i update the table often often and everytime i do that i have to go through and change all the classes to their opposite, so that when the page loads it initially has colored rows. When i update the table i add it to the top of the table so most recent additions are at the top. If i could get it to double sort onload by date i figured i could have most recent on top and have the sort cause the rows to be alternated colors.
any suggestions?
Thank you
I would like to have a sortable tabel in which I could sort two rows as a group.
I would use this in order to get some sortable data into the first row and a hidden div into the second one.
Then I could load info on the data of the first line through ajax and show this in the downsliding div just under the data.
The best would be to still able to sort the table with this active info divs underneath.
Is this somehow possible??
thanks in advance and great work
i actually found a solution to my problem. i have a hidden column that has a really big number like 1 billion and everytime I add a new row to the table i will make the value of that 1 less, then sort onload by that. It’s kind of a hokey solution but oh well.
-thx
I’m seriously impressed. That’s what javascript should be about. enhancing the browsing experience, without messing the layout and let the content accessible where it belongs in the html page.
Then, I discovered your date picker. Another great one. I see a pattern, beware, you’ve got a fan !
Ok, a question/suggestion:
I’d like to be able to filter on the top/instead of sorting. I have in mind some drop-down menu, ala what you can get with access. Would it make sense for your to add a fitrable class ? This would parse the content of the table, and populate the drop-down list for that.
Chapeau bas, monsieur
@ binbarn: Hi binbarn, there’s currently no inbuilt functionality that enables you to store the sort position within a cookie. Sorry.
@ Max M: Hi Max, if all you want to do is color the rows, you should write a small script that does this for you. If you need a bit of help, mail me at brian [at] modernartcafe [d0t] net and I’ll send you a function that does just that.
@ Luis: Luis, just add the div to the first row (as the last child of the TD node) and forget about the second row, this way, the script will work “out of the box” so to speak.
@ Xavier: Hi Xavier, I’m glad you like the script. I’m a bit dumb this fine Monday morning and can’t quite figure out what you mean by “filter” (sorry). – can you explain in a bit more detail (or point me to a page that has this Access feature explained). Thanks.
Regards,
Brian.
Me again! Hey…what toLowerCase parts would i have to take out if i wanted to make the sort case sensitive? Or would taking those out without adding something else not do the trick?
Thank You
Also I was trying to do the reverse sort on the date mostly. Right now i have that hidden sortable column that has 10000 as a value and everytime i add a row i subtract 1 from the value. So each newer addition has a lower value and will sort to the top. If making it sort twice or reverse sort is something you have time to explain I would love to hear it through e-mail or this commenting section.
thanks again
Brian,
Let me clarify the filtering thing.
Say that on one of your column, you’ve got discreet values (coutries, gender, boolean, month…).
Right now, you can sort them (Austria, Belgium, Canada…). What I’d like to be able to do is to filter them to get only the people in France (or Belgium or… ;)
This is a feature often used in excel (sorry not access, didn’t help the previous explaination) for instance.
I see how to build the filter select, I don’t know what would be the clevest way of applying the filter to hide all the rows that haven’t that value (all the rows that aren’t France).
Am I clearer this morning ?
Feel free to contact me by mail.
Great work Brian!
I noticed that when I don’t presort the table
(i.e. using class=”sortable-onload rowstyle-alternative no-arrow” instead of class=”sortable-onload-1 rowstyle-alternative no-arrow”)
the alternate table coloring doesn’t work until I sort the table for the first time. Am I doing something wrong or is that just the way it is?
Thanks again!
Thank you very much for the great script. I desperately need to store the current sort in a cookie. This is so that the sort can be persisted over my paginated script etc. I’d really appreciate it if you can could give me an idea of how the cookie can be applied and used. Many thanks.
how to adjust the sort method to get the correct alphabetic order with danish letters like å ø æ, which should go after the Z letter : a,b,c, ... x,y,z,å,æ,ø.
Thanks for your help!
@ Max M: Hi Max, change lines 203 and 220 from:
txt = txt.toLowerCase();
to
txt = String(txt);
to remove the case-sensitivity. Alternatively, you could write a bespoke sortInsensitive function like so:
function sortCaseInsensitive(a,b) {
return fdTableSort.sortText(a,b);}
and give your TH tags the classname “sortable-sortCaseInsensitive”.
@ Xavier: Hi Xavier, you would need to write another widgit entirely to handle the data filter. The “prepareTableData” method could easily be altered to also save an array of unique column data (and this could be used to create the dropdown filter). It’s more scripting than I currently have the time to tackle so, unfortunately, I can’t offer to help. Sorry…
@ Simon: Hi Simon, there’s currently no cookie based save integrated into the script. Storing sort patterns in this way is made more complicated by the fact that the stored column state could be “reverseSort” which means the script would untimatly need to sort the column twice on page load (once to forwardSort and once to reverseSort). It’s entirely feasable though – I just haven’t got the time to write the code. Again, sorry!
@ Kenshin: The “sortable-onload” requires a column number (the script needs to be told which column to use when sorting the table). Hope this helps.
@ Francois: I would have thought that all of these characters were automatically sorted correctly by the sort-text function? If not, you could write a bespoke sort function and associated prepareData function. The prepareData method could replace any of these danish characters with any ASCII character having a character code value larger than “Z” and the sort function could then just call the inbuilt fdTableSort.sortText method as shown above in the response to Max M.
Regards,
Brian.
Hi!
Your script is amazing, it’s faster than any other, so I decided, I will use it for large tables. But I need some new feature, like line filtering or selecting lines. I start write these functions, but I read your licence just now, which is not allow me, to modify your code.
So I ask you to permit me to modify your code. I still not publicate and use any code, but naturally I will share everything when I finished.
Can I add these new functions or not?
Regards,
Ajnasz
If you click on the arrow the text disappears. :(
Do you have an example of the sortable-onload- ???
@ Ajnasz: Hi Ajnasz, I’ll be updating the license this week. Stay tuned.
@ Rich: ‘The text disappears’? Can you give me a little bit more detail; the browser and O/S etc – thanks. Also, the very first table within the demo is the sort-onload example. Look at the source code to see how it was initiated.
Regards,
Brian.
hi, does anybody knows if this Script will work with EzResults?
i need that the sort by column persist on links of paginations.
:( Sorry my bad english.
Wow. This script is really handy! Thank you so much for sharing you hard work with the community. I’m using it on a table with 10 columns – one of which is “comments”. These comments can be very long, so they’re tuncated in PHP and I’m using Dustin Diaz’s SweetTitles so users may hover over the truncated comment to see the full text. I’m very pleased with the results. I’m also using the Silk Icons from famfamfam.com – it’s wonderful to be able to leverage so many open source resources these days!
One question (I’m at home with xhtml/css, but my javascript skills are nil)... Currently the script takes the entire contents of TH’s and transforms them to a link. Could this be limited to perhaps just transforming what’s inside a STRONG within the TH?? That would allow me to keep my SMALL ”(hover for more details)” /SMALL inside the TH without transforming it to a link. – thanks!
Hi and thanks for this fabulous script.
I was using a previous version of this script in a project, when I realised that you have a new version. Downloaded and upgraded. But know with the new version I keep getting an error in some tables, can you check it?
The colume is an “area” and the data like “400 m2” beeing “m2” the unit. Another one is in date format.
The problem is that it doesn’t sort and then posts an errot in line 171 char 17 ”’undefined’ is null or not an object”.
Regards,
Edu.
I wanted to revisit the reverse sort that you mentioned Brian on #55… namely that’s exactly what I’m after, I have a date format I’d like to sort in descending order (newest to oldest) and I tried plugging in that bit of code, but to no avail. So I’m not sure where I’ve gone wrong, here’s the code as I had it in the tablesort.js (at the bottom of the script)
—————————————————————-
function myDoubleSortOnLoad() {
fdTableSort.jsWrapper(“reviewArc”, 4);
}
fdTableSort.addEvent(window, “load”, function() {
setTimeout(“myDoubleSortOnLoad()”, 2000);
});
—————————————————————-
So basically the table’s ID is “reviewArc” and the column I’m after to sort is #4. The class of the column is “sortEnglishLonghandDateFormat”. Now, when the page loads it does sort it twice, once in Ascending order and then the second time in a random order… it’s very strange.
ps. I gave up on the idea of creating a bunch of custom classes (#50 above); I don’t really need them right now anyway :)
@ Santiago: Hi Santiago I have no idea if the script works with ezResults but it most probably will not if were talking Ajax and result paginations. Sorry.
@ Andy Ford: Hi Andy, (off the top of my head) changing the following few lines of code should do the trick:
change…
89: thtext = fdTableSort.getInnerText(th);
91: while(th.firstChild) th.removeChild(th.firstChild);
98: th.appendChild(aclone);
to…
89: thtext = fdTableSort.getInnerText(th.getElementsByTagName(‘strong’)[0]);
while(strong.firstChild) strong.removeChild(strong.firstChild);91: var strong = th.getElementsByTagName(‘strong’)[0];
98: strong.appendChild(aclone);
@ edu ser: Hi edu, I’m going to need a bit more info in order to help you out. Can you send the HTML for the table (or tables) you are atempting to sort (as a .txt file or my spam filters will automatically delete the mail) to brian [at] modernartcafe [d0t] net and I’ll attempt to track the problem down for you.
@ Chris: Hi Chris, Here’s a quick testcase that I have working that uses the callback functionality:
var sorted = false;
if(!sorted) { sorted = true; fdTableSort.jsWrapper(“theTable”, 0); }function sortCompleteCallback() {
}
Just add the above code snippet to the HTML document (between script tags within the head section of course).
In researching your problem, I also fixed a rather nasty bug when using the jsWrapper method (I’m suprised that no one has noticed it before!) so you will have to download the updated source again.
Regards,
Brian.
Is there a way to make it so the “non-alternate” row is another color besides white. In the CSS if I give the TRs a value of say… background: #0066ff; then it’ll just convert all the TRs to that color and ignore the alternating row color. Thanks for any help anyone can provide :)
-Lucas
@ Lucas: Hi Lucas, I don’t have any such problem using the following CSS (tested on Internet Explorer 6 and Firefox):
tr { background: #0066ff; }
tr.alternative { background: #f5fafa; }
It must be a specifity problem within your CSS. Check the CSS declarations and try to spot a more specific rule (an id applied to the table may be out-weighing the generic tr rule for example).
Regards,
Brian.
Ahhh…. I got it I didn’t have it declared as tr.alternate… I just had plain old .alternate which apparently it wasn’t feelin’, thanks for the hook up :)
@Brian – Thanks for your assistance (#73/#76) – unfortunately I couldn’t get it working. As I mentioned my JS abilities are virtually non-existant. However, when reading through your code changes it looked to be making sense. I wasn’t sure where to put:
while(strong.firstChild) strong.removeChild(strong.firstChild);
so I tried it directly below line 91 as well as directly above line 98 – but still no luck. I did notice that the SMALL elements were being treated differently than in the original code, but nothing inside the TH elements were being turned into sort links.
I got to thinking though, that having anything inside a TH besides the actual heading may not be very semantic (such as my hover for full text “helper” instruction). So my workaround is to add a new TR inside the THEAD so it won’t be sorted and so I can put my extra instructions (“hover” etc) inside regular TD’s… I can’t decide if it’s semantically any better or worse than having the extra STRONG and SMALL elements inside the TH element (although I’m thinking it’s a tad more semantic… maybe) – but I think it makes sense and it works for me
Hi!
I’m here again. Thank you for change the licence. Now I realized the first version of my script, so you (and everyone) can try it on the following address: http://viala.hu/html/tablesort.html
Thanks again,
Ajnasz
@Ajnasz,
Like a good start, but it doesn’t seem to work with firefox. For instance, the double click is always seen as a single one and couldn’t find a way to apply the filter I typed.
Moreover, a little ergonomic concern: I’m not sure the double click to sort is the most obvious solution.
What about adding a “filter” icon next to the title instead ?
X+
@Xavier
To apply the filter just press enter. :)
Doubleclick: If I attach single click to the container th element, the sorting will applied when you click on the columntitle too.
Filter icon: it’s not a bad idea, but I think in some cases it reserve too much space. Maybe I will add an option.
@ Lucas: Hi Lucas, good to hear you got it working.
@ Andy: Hi Andy, the original line 91 turned into two lines within the changed code. As I said, I wrote it off the top of my head and didn’t test it (although it should have worked). You could try to add the JavaScript specific text using JavaScript (which would leave the page clutter free when JS has been turned off). P.S. I try to avoid “semantic” conversations like the plague – they bore me to death and never seem to get resolved without name-calling by people who should know better.
@ Ajnasz: Hi Ajnasz, can you link to this page and not the front page if possible – thanks. Also, your sortBinary method is a copy of the sortCaseInsensitive method and could be removed from the code alltogether. Also, once I filter a columns data, how do I “undo” the filter to see the entire column again?
@ Xavier: Hi Xavier, the filter icon is a good idea methinks…
Regards,
Brian.
@Brian
Ha ha! I couldn’t agree with you more regarding semantic conversations!
I’ll give your code change another try. Thanks again!
This is really a great script! I am using it on a very large table set with ajax. Once I have the table data in place, I use the jsWrapper method to sort specific columns. Is there a way to initially specify the sorting behavior (ascending vs. descending) for a column, without having to use some “sort it twice” type of thing?
Hi Brian,
very nice script – just a question (to add to the growing list); i have a table with 2 header rows (the first one is used to group some columns). how can i use your script so that only the second header row is sortable?
@ Denny: Hi Denny, unfortunately, theres no way to do the double sort without heading down the “sort it twice” route. Sorry about that.
@ Tim: Hi Tim, you’ve just spotted a bug my man! I’ve updated the code to handle double headers like this.
There is one caveat though – should you wish to use double headers, the TR’s have to be wrapped in a THEAD. Also, all of the sortable columns have to be declared within the last TR of the parent THEAD (I hope I’m not confusing you). I’ve created a testcase that shows the script working with headers like this.
Hope this helps,
Brian.
Nice clean javascript, thanks for your effort. I found that your script doesn’t handle numbers in exponential notation. Wondering if you might add that functionality. An example number would be 1.5e-6 which is equal to 1.5×10 to the -6 power or .0000015
Disregard my last comment as I found what I needed in the the custom sort page. Thanks again!
Very cool script.
Reverse sort on init, hope you can incorporate this in the future. Line numbers (+-{num}:) below, as added to version 0.1.
+65: var reverseSortOnInit;
+80: reverseSortOnInit = tbl.className.search(/sortable-onload-reverse/) != -1;
if(sortable) { fdTableSort.thNode = sortable; fdTableSort.initSort();+115 if (reverseSortOnInit) {
};+116 fdTableSort.thNode = sortable;
+117 fdTableSort.initSort();
+118 }
Btw, it would be cool to update the version once new additions are made.
Nothing but just say excellent!.
what is the sorting behaviour with non ASCII data?
Hi,
I love your script but I need to “exclude” a column from sorting. I explain better my problem: the first column of my table is numbered authomatically and i would like that even if I sort the other column, the first reamain 1-2-3-4-....-n. In this way, even if sorted on any column, I can immediately see the total number of rows of the table.
Is it possible?
Hi Everyone.
I realised a new version of my extended version. I fixed some bug and I implemented the filter-icon feature. Add the img-filter class to the table to activate it.
There was a question:
You must delete the filter from the input field, than press enter. The filter runs only when you press enter in the search field.
Ajnasz
@ kassaal: Glad you found what your looking for.
@ Parag: I’ll test your changes this week and perhaps integrate them into the next release of the script.
Update: I’ve already integrated the code into the new release. Thanks a million.
@ vinod: Thanks, I’m glad you like the script.
@ Hassan:
That would depend on the sort routine used I imagine. I haven’t tested the script with a non ASCII character set (Arabic for example), if you have ran any tests, I would certainly be interested in hearing the results.
@ Luca: Hi Luca, you can use the sortComplete callback function to renumber the rows. I've created a callback function demo for you that does just that. Hope this helps.
@ Ajnasz: Hi Ajnasz, I’ll stop by and have a look today.
Thanks for this library! I’m trying to use it along with scriptaculous to sort a table which is loaded dynamically into its own div. I have a hidden image which renders after the table is finished and contains an onLoad event which calls fdTableSort.init() , but my table shows no reaction and firebug doesn’t report and error. Does anyone have any ideas?
Thanks again!
@ Ezra: Hi Ezra, have you tried to put an “alert” into the init method to see if it actually gets called by the images onload event?
Regards,
Brian.
Hi,can we do this client side sorting with paging pls. (for a table that spans several pages)
Thanks for your quick response. For testing I created a standalone html file with a simple table on my local machine and added an alert to the script which verifies that it does initialize. Venkhman displays a whole list of errors.
Exception ``[Exception… “Index or size is negative or greater than the allowed amount” code: “1” nsresult: “0×80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)” location: “file:///Users/ezra/Developer/directory/Projects/directory2/TEST/tablesort_v2.js Line: 131”]’’ thrown from function anonymous(tbl=HTMLTableElement:{0}) in line 131.
Exception ``[Exception… “Index or size is negative or greater than the allowed amount” code: “1” nsresult: “0×80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)” location: “file:///Users/ezra/Developer/directory/Projects/directory2/TEST/tablesort_v2.js Line: 131”]’’ thrown from function anonymous() in line 77.
Is preceded by a whole bunch of firefox errors such as
Exception ``2147500034’’ thrown from function anonymous(iid=XPComponent:{7}) in line 2800.
Exception ``[Exception… “Component returned failure code: 0×80004005 (NS_ERROR_FAILURE) [nsIURI.host]” nsresult: “0×80004005 (NS_ERROR_FAILURE)” location: “JS frame
And the page doesen’t work in firefox. My table has the proper class, an ID and a name. What could i be doing wrong?
Thanks again.
Ezra
@ Din: Hi Din, what your asking for is impossible as the client side script needs the entire table in order to function. Sorry.
@ Ezra: Hi Ezra, here’s a few things to watch out for:
1. Make sure your table is constructed using valid XHTML (lowercase tags, a thead, a tbody etc)
2. Setting the innerHTML of a table will not work.
3. Make sure that your using the latest version of the script.
I’ve created a quick FireFox test page that uses DOM methods to create a table before calling the fdTableSort.init() method to initialise the sort. I don’t get any errors (I’ve only tested it in FF2 and not IE).
Hope this helps,
Brian
Hi Brian,
i’ve been here before (a while ago) and I’m still using your table-sort with much pleasure.
Every now and then I follow these comments to see what’s happening.
I saw that Ajnasz made some additional functions to his version of table-sort.
I really like the feature “highlighting the row when mouseover”.
Is this already possible with your version?
If so, is there an example?
If not, is it easy to build it in?
I would appreciate your help.
Anyway, thanks for making this script.
Greetings
Nils
@ Nils: Hi Nils, I haven’t integrated any mouseover effects into the code as this (in my opinion) should really be handled by another script. I want to keep this script to just the basics i.e. the sort mechanism and the poilte restyling of the rows after the sort.
In the off-chance that Internet Explorer support isn’t an issue, you could just create a tr:hover css rule. If Internet Explorer support is required, you could try to use this row and column highlighting script
Hope this helps, regards,
Brian.
It seems that it does not work correctly with colspan.
@ Morgan: Hi Morgan, the script was not designed to work with colspans – imagine this scenario:
You have a TH with a colspan of 2. The TH has been given the className “sortable”. How does the script know which of the TD’s to sort on? The first or the second?
The script will work with colspans if they are declared within a double row THEAD as shown in the example
Hope this helps,
Brian.
Yep, therefore if I don’t set the class “sortable” to the TH column with the colspan but I set it on other columns, the table will not be correctly sorted.
The problem is that the first column with class “sortable” will not sort the table.
I resolved the problem by removing the colspan. I just wanted to inform you about this effect.
Update: Hi Morgan, I’ve updated the script to deal with colspans. Read the 2.9 update below for more info.
@ Morgan: Ah ha, now I understand! I’ll have a look this week to see if I can change the code to enable non-sortable colspans. Sorry for the misunderstanding.
Regards,
Brian.
Just tried your tablesort demo in netscape (latest – 8.1.2) and it just bombed out – I know netscape isn’t popular these days but any idea why it does?
Hi,
First off, I just want to say that this is an amazing script. I spent a good amount of time trying to get a few other examples I found working and never could. Yours on the other hand, took something like 10 minutes to get working.
But… I’ve run into a snag that I’d like some advice on. I’m trying to incorporate your sorting routine into a scrollable table. In Firefox, everything works fine. I can scroll and sort whenever and where ever I want. In IE though, I can sort the table correctly, but if I scrolled down at all and try to sort, I lose the column headers. I’m using Firefox 2.0 and IE 6.0.
I’d like to think the problem lies somewhere in my stylesheet, but I’m just starting with CSS and scripting and all this goodness and don’t really know where I should start looking.
Thanks
I’m currently at work on an IE5 browser which managed to lose my post. Bloody Websense!
In essence though, great site, great script and thanks for inspiring me to try new things on my own sites.
However, there seems to be a problem with nested tables as THEADs within the inner tables are being discovered and seems to get into an infinite loop before bombing with Ezra’s error message detailed above.
Feel free to delete the post above.
The problem was due to a malformed THEAD, as the two data tables didn’t have TRs within the THEAD.
@ Dave: Hi Dave, can you tell me what JS errors are being thrown by Netscape? I’ll have a better idea of what breaks that way. Thanks.
@ Leigh: Hi Leigh, Can you send me a link to the page in question, that way I can have a look and try to figure out why IE is not playing fair. Thanks.
@ Paulus: Hi Paulus, I’m going to leave the comment in case someone else has the same problem. Thanks for the feedback.
Regards,
Brian.
Hi,
Thanks for the prompt reply – if only commercial software was so well supported :)
The big problem is Netscape gives no error – it simply closes all tabs and windows. Obviously something very wrong in Netscape (it works great in IE/FF).
If you use IE rendering in Netscape it loads fine but as soon as you load the page using FF rendering it will crash out with no error message.
Hi Brian,
Thanks for the advice (sorry for the late reaction). I’ve implemented the highlighter script and it works allright.
Thanks again.
Greetings,
Nils
@ Dave: Hi Dave, I’ve just installed Netscape 8.1.2 and indeed, it does very funky things. I’ve traced the problem to line 420 within the script:
hook.appendChild(tr);
This line makes Netscape decide to commit hari-kiri. It appears Netscape does not adhere to the standard when re-adding nodes already present within the DOM. It is necessary (for Netscape) to remove the node before attempting to re-add it.
The fix for the Netscape problem is simple, replace the original line 420 with the following two lines:
hook.removeChild(tr);
hook.appendChild(tr);
This shouldn’t affect other browsers (but will slow the script down by a few milliseconds – bah and humbug) so I shall add it to the distribution a.s.a.p.
Update: I’ve updated the distribution with the fix.
Hope this helps.
@ Nils: Good stuff Nils, I’m glad the highlighter script works in conjunction with the tablesort script.
Regards,
Brian.
Hi Brian,
I cheered too soon! (about the highlighter script).
Although it seems to work fine, I get an javascript error when I mouseover the tableheaders (TH).
It looks like the onmouseover event of the highlighter script which I had to implement interfere with the table sort.
I added in the table-tag:
The javascript error I got, is:
Line: 102
Char:7
Error: ‘length’ is null or not an object
Code: 0
I think it is refering to your script, but Im not sure.
th.appendChild(aclone);Line 102 says:
Dit I miss something?
(like I said, It is still working)
Thanks,
Nils
@ Nils: Hi Nils, here’s a good tip: Never debug JavaScript using Internet Explorer. It never tells you anything of worth re: the error. Try launching Firefox and, if your a seasoned enough player, install Firebug. This will give you a much more detailed error message and let you locate the line (and file) the error occurred in. Trust me, Firebug is well worth the one minute installation.
As for the error, the tablesort script doesn’t use mouseovers so, the error is actually coming from the highlighter script. Line 102 of the highlighter script reads:
for(var i = targetAr.length;i—;){
So this is most probably the line that throws the error. You could wrap the entire for loop in a try/catch block to see if the error still gets thrown. If no error gets thrown, you’ve located the problem.
Indeed, if the two scripts are still working after you’ve integrated the try/catch block you could leave it at that. If your curious, you could try to see what is passing a null object reference to the highlighter script.
Hope this helps,
Brian.
Hi Brian,
Thanks again for the quick response. I did what you suggested and guess what …you’re right. Nice tool though! I accidently deleted the TH settings in the config function, while I should leave them. Sorry for that, I should have spotted it myself, instead of bothering you.
The next issue I wanted to solve myself, but again I need some help. (Hope you don’t mind)
} else if(thNode.className.match(‘sortable-currency-nl’)) { data.sort(fdTableSort.sortCurrencyNL);I need another currency sortfunction (Dutch) where the dot is instead of the comma and vice versa, e.g. € 100.000,00 instead of € 100,000.00
So I’v been through all comments and I found a comment of you from april 18 (reply on a comment of Pete) where you give an example of the custom function.
Since that was written for the previous version, I tried to write it for the new one.
I added after line 358:
[code]
[/code]
And then at the end (before the SortText function) I placed:
[code]
sortCurrencyNL:function (a,b) { var aa = a[fdTableSort.pos]; var bb = b[fdTableSort.pos]; aa = parseFloat(aa.replace(”.”,””).replace(”,”,”.”)); bb = parseFloat(aa.replace(”.”,””).replace(”,”,”.”)); if(isNaN(aa)) return -1; else if(isNaN(bb)) return 1; return aa-bb; },[/code]
(of course I added the class=sortable-currency-nl in the specific TH-tag
No errors, but the sort behaviour is still like the normaul currency sort.
Do you have any suggestions?
Thanks in advance,
Nils
@ Nils: Hi Nils, glad you’ve jumped on the Firebug wagon. It really makes JavaScript development so much easier. As for the custom sort function (I should charge for writing these as I write so many of them for other people!) – try this:
it’s not been tested but should work. Just give your th node the classname “sortable-sortDutchCurrencyValues”.
Hope this helps,
Brian.
Hi Brian,
Thanks alot. Yes, it works allright. I don’t mind payin’ for it (although I’m not using it business-wise) Just tell me how. I’m not quite familiar with paypall (the button brings me to a french paypall site and I don t understand that)
Just let me know. In the meanwhile … THANK YOU VERY MUCH!
Greetings,
Nils
@ Nils: Hi Nils, I’m glad the function worked (as it was typed live into the comment textarea!). Also, I certainly wasn’t asking for payment… don’t worry about the paypal thing!
Regards,
Brian.
I’ve been using this script for a while and it’s been great! The one bit of functionality I’m still looking to include in my tables with this script is the inclusion of the ability of pagination. My table is populated with game-review data and it won’t be long before the table goes on forever and ever; which as you can imagine begins to look very unsightly. Brian, I was wondering if you know of a way to include this… or hell, if anyone knows of a script for pagination that would work well with this awesome bit of code?
Thanks, – Chris
Hi Brian,
I was woundering if it is possible to sort 2 coloums in 1 function.
I have a soccer team – 4 strikers, 4 midtfield, 2 defense and 1 goaly.
They have different staminas depending on how they played.
So I want to sort so they group by – striker, midtfield, defense and goaly. In those groups the player with the largest stamina is at the top.
Is this understandable?
Can is be done with your script?
And thanks for the script – it works brilliantly.
– Thomas@ Chris: Hi Chris, you could write a callback function (sortCompleteCallback) that paginates the table for you i.e. sets the CSS display property to “none” for all rows outside the current page limits. I’ve been meaning to write such a function for some time but just haven’t had the time. Of course, you would have to write a setUp function that counts the table rows and creates the pagination index when the onLoad event fires.
Update: I wrote a table pagination script during my lunch hour. A demo that uses both the tablesort and pagination scripts is now available (view the page source to grab the pagination source code).
@ Thomas Blomberg Hansen: Hi Thomas (man, that’s some name you have there), it is possible if the results are held within one column i.e:
striker A (stamina 5)
striker B (stamina 3)
midfield A (stamina 5)
midfield B (stamina 4)
midfield C (stamina 3)
but not if the data is split across two columns i.e. one column for the Player and another for the Stamina. Thats “group by” functionality that the database should really be handling, not a client-side script.
Regards,
Brian.
Thanks a lot :D
I should have thought of that ;)
It is in two coloums, but I will use the imagesort function and then merge the two coloum text content in to one filename for the image src.
Then I use a transparent gif so it isn’t visible to the users.
Thanks again :D
Your code is brilliant. However, I only want a vertical scroll bar. I have achieved this by leaving the width element out of the
//width: 800px;.scroll-table-head {
}
.scroll-table-body {
//width: 800px; height: 400px;}
However the scroll bar shows up too far to the right. It’s about a scrollbar width off.
Any suggestions?
Thanks!!
@ Thomas: Hi Thomas, your probably better off placing the text within a span and hiding the span using the CSS display:none declaration. You can base your custom sort function on the imageSort code but call .getElementsByTagName(“span”) instead of .getElementsByTagName(“img”).
@ Deborah: Hi Deborah, I think you have the wrong site. Your most probably looking for Cody’s site and more specifically, the Pushpin header technique post.
Regards,
Brian
Hi. I’m using your table sort in conjunction with a table filter and I was having a problem with zebra striping. The issue was that the filter would set certain rows display property to ‘none’, so when I would sort the table it would zebra stripe every other row including the hidden ones. I wrote a simple fix for this if you’re interested. I just set a switch variable to keep track of whether or not to show the stripe, and replaced your code that was checking for i%2 0. Here's a snip of the code:
@ Brian: Hi Brian, if I integrate your changes into the code, they might affect other add-on’s that use the callback functionality (the pagination demo for example).
The callback functionality was included to enable developers to write “add-ons” that deal with issues like this. You could write a callback function that (re)zebra-stripes the table in question according to the display property of the row (although, I completely understand that this might be overkill for your situation!).
Thanks for the comment anyway – it may help others in the same situation as yourself.
As an aside, what filter script are you using?
P.S. As your dealing with a Boolean value within your code change (i.e. the new rowStripe variable can either be "on" or "off"), I suggest you drop the yes/no String assignments altogether and instead use:
and (further down) replace:
with:
and also replace:
with:
Regards & happy new year,
Brian.
Thanks a lot :D
this code has been a lot of help to me, thanks again!
wow, great script. big thanks.
But one great feature is missing: rowspan support in table headers. Look at the following example table:
‹table›
‹thead›
‹tr›
‹th rowspan=”2” class=”sortable”›Column 1‹/th›
‹th colspan=”2”›Column 2‹/th›
‹/tr›
‹tr›
‹th class=”sortable”›SubColumn 2
1‹/th›2‹/th›‹th class=”sortable”›SubColumn 2
‹/tr›
‹thead›
‹tbody›
‹tr›
‹td›a‹/td›
‹td›1‹/td›
‹td›a‹/td›
‹/tr›
‹tr›
‹td›b‹/td›
‹td›2‹/td›
‹td›a‹/td›
‹/tr›
‹/tbody›
‹/table›
(please ignore the strikethrough thing)
I think thats a very common contrstuction. The first column is rowspanned because of the last one which is devided into two seperate sub columns (with colspan which is already supported). Could you please modify the script in that way that this construction is also supported please? Now, the great script produces no error, but sorts the wrong column.
This is a great tool to have. One problem I’m having, and I’m not sure if you would define this as a bug or just not something supported currently. I’ve been working on a tool that has information in a table, and I want the user to be able to edit the table contents in a form context. I have the tool working just fine before I make it sortable, but now after sorting it’s breaking my post buttons in the table (js buttons work just fine)
Ah-hah! I discovered my problem: it was because my form tags were outside the tr tags. Design flaw of my own, your code is working just fine :) Feel free to delete this and the previous post of mine.
I like the script, it is better then most I ahve looked at.
I was wondering if you have looked into modifing the code to highlight the sorted coloumn using a class < col class="sorted_column"/ > on the table. The problem I am having is that I can color the none “alternative” row but the alternative rows stay zebra stripped. Is there a way I can set the zebra stripping according to the sorted row? Something like class=”alternative” for none sorted and class=”alternative_1” for the active sorted column.
I could then also color the sorted coloumn for better scanability.
Thanks.
@ Paul: Glad to be of help.
@ Sven: I’ll look into the rowspan issue when I’ve a spare minute.
@ Shane: Glad you located the problem.
@ Benjamin: Benjamin, please RTM, more specifically, the section “Row and column highlighting”.
Regards,
Brian
Brian,
I have listed below in more detail and I have tried to explain what I am looking for better.
< table cellspacing="0" cellpadding="0" id="tbl" class="sortable-onload-2 rowstyle-alt_row no-arrow" >
< col / >
< col class="sorted" / >
< col / >
< col / >
< thead >
< tr >
< th title="Cell Hdr 01" class="sortable" >Cell Hdr 01< /th >
< th title="Cell Hdr 02" class="sortable" >Cell Hdr 02< /th >
< th title="Cell Hdr 03" class="sortable" >Cell Hdr 03< /th >
< th title="Cell Hdr 04" class="sortable" >Cell Hdr 04< /th >
< /tr >
< /thead >
< tbody >
Style:
col.sorted{
background-color: #eeeed9;
}
Above is what I was refering to: I am wishing to set a class on the sorted column. That way I can then have a color bar on the sorted column. The problem is that the zebra stripping comes after the col tags and overrides the color of the column.
Is there a way when you do zebra stripping you could set a condition that sets an alternate class for the sorted column only?
Something like:
< table cellspacing="0" cellpadding="0" id="tbl" class="sortable-onload-2 rowstyle-alt_row sortedrowstyle-colored no-arrow" >
Style:
background-color: #eeeed9;tr.colored{
}
This way you could highlight the sorted column and still keep alternating rows on all the other information.
Brian,
I got it fixed… Using a combination of rowstyle and colstyle I got my desired effect. Sorry for the trouble.
Ben
Hi Brian,
Great script. It is really awesome and thanks for sharing your code. I was wondering, is there a way to insert a new row in between groups of rows based on the sort or a way to change the value of a cell based on the sort?
For example, if I have a column named “Group” in the table, the database returns a dataset that is by default ordered by a column which contains unique data so the value in each group cell just increments by one for each row. If the user then chooses to sort based on another column “Name” which is not unique, I would like to have the “Group” column values be modified to reflect the groups that each row belongs.
Is this possible using your script or would I be better served by just executing server-side queries?
Thank you!
@ Benjamin: Hi Benjamin, glad you got it sorted out (the !important rule comes in handy here).
@ Albert: Hi Albert, I don’t quite understand what you mean (sorry!). In any case, the callback functionality can be used to re-engineer the table after the sort has taken place.
Regards,
Brian.
Brian, thanks I totally missed the part where you show an example of what I wanted. Sorry about being confusing.
Hello,
I started to integrate your script into my Wordpress Plugin, but It seems to be that the Prototype script together with your script causes a error at FF and IE (too much recursion). I’m not a JavaScript expert : Exist there any workaround or solution ?
See example here http://alexrabe.boelinger.com/?page_id=3
@ Albert: Hi Albert, glad the demo helped you out.
@ Alex: Hi Alex, is prototype adding a .reverse method to the base javascript Object? If so, this may be the problem (as the “too much recursion” error appears only when my script calls Array.reverse). Try posting a message on the prototype forum – perhaps someone there already has encountered (and fixed) the same problem.
Regards,
Brian
Thanks for the feedback,
Hard to understand for a non-java-script-programmer what’s going on here :-)
I will try to find a forum and a solution on prototype , but I already check out that I used nearly the latest version (1.5.0 RC0) , and the SubVersion repository didin’t show any difference in the .reverse script part. So this should encounter a lot of blogs which are using the upcoming prototype / script.aculo.us for AJAX features.
FYI : I found a interesting link about this problem : http://cephas.net/blog/2006/05/31/prototype-tinymce-too-much-recursion/
@ Alex: This is a problem with prototype and not my script, which means it’s really up to the prototype guys to fix (and I really wish they would be more careful when overriding built-in Object and Array methods).
The problem you are having though is that you are including two different versions of prototype in your page, which means an older version is overriding a later version and thus removing the if (!Array.prototype._reverse) check (to be more specific, your lightbox-plugin version of prototype is overriding your braintech version).
Removing the link to the second version of prototype will make everything hunky dory once again.
Regards,
Brian.
Oh, yes …
I see it… the Gallery plugin includes a older prototype script.
Thanks for the hint and your help !!
This script rocks! However, does anyone know if it supports secondary sorting?
For example, your primary column has identical values, and the secondary field is a date field that would need to be sorted by date.
Any help would be greatly appreciated. Thanks!
@ Alex: Glad to be of help.
@ Issac: Hi Issac, if the primary column has identical values and you wish to sort on the second column, just give the second column the class “sort-date”.
If your actually talking about a “double sort” i.e. resulting in a result set comparable to the SQL query “order by primary_column, secondary_column asc” then your out of luck as no client side sorting script (that I know about) currently supports this feature.
Hope this helps,
Brian.
Dude, thanks for sharing this under creative commons… I’ma try it someday…
Anyone tried paste teblesort.js contents in a greasemonkey script?
I got an error, wonder if anyone have a clue about it…
Regarding “A note on the date format”
Hi
I am using tablesort.js with awstats to sort columns in reports in the extra section and i am having problems with the date sort. i have read the section near the top of the page regarding the european dates and i am not sure what i am supposed to change. do i change the tablesort.js file with sortable-date-dmy or do i put it in the awstats.pl file. i have tried it in the awstats.pl file and it gives me the same results dates out of order, which is the same as just using sortable.
I aaded this to the appropriate column in my awstats.pl filr (class=\”sortable-date-dmy\”>)
Could some one give me a clue as to what i need to do to get it sorting dates in the english format dmy within awstats.
Many Thanks
Ian
@ hil: Hi hil, sorry, I can’t help you on the greasemonkey issue.
@ Ian Coombs: Hi Ian, adding the class “sortable-date-dmy” to the appropriate TH tag should have done the trick – if you can send me a copy of the rendered page HTML (to brian (at) modernartcafe (d0t) net), I’ll be able to debug the problem properly. It sounds like a nasty old bug to me.
I notice that you automatically add links with href=”#” to all th-tags in thead. Why don’t you use CSS to underline the text instead? Also, if you insist on using links, then use href=”javascript:void(0)” instead. http://www.tizag.com/javascriptT/javascriptvoid.php
@ Kia: OK Kia, here goes…
I automatically create links within the TH tags as this makes them keyboard accessible – which might just help visitors that don’t use a mouse.
For arguments sake, I could have created “buttons” (which also fall into the tabIndex array and are therefore keyboard accessible) but this would complicate things immensely should the table already be a child element of a form.
As I create the links “moi meme”, I can say for certain that JavaScript is active (it has just created the links after all – non?) and that activating the link will only ever call the tablesort script.
As for using javascript:void(0) – there is no such thing as a javascript protocol and this is bad practice (in my opinion) left over from days of old – but, I’m open to suggestions. Feel free to suggest ways in which I can remove the link and still be keyboard accessible – really, I’m all ears.
P.S. For your info, the scripts “accessibility” has been tested using the Jaws screenreader.
P.P.S. Here’s some light reading that may be of interest to you.
Regards,
Brian.
Do anyone knows how to: – choose arbitrary columns(more than 1) to start on reverse mode? – avoid table layout mess? When inside a frame, the layout gets a little messed if width exceeds.
Thanks :)
Decoder, alright about the Greasemonkey, I had to polute the namespace by externalizing the functions, but its working nice, with two tables.
I’m not sure if the script sorts the columns with a dollar symbol and commas. For example The column I’m talking about has values lie $ 100,000 $ 32,000 $ 55,345. Can anyone help how these columns can be sorted?
@ Hil: Hi Hil, you coan use CSS to set the table’s width to 100% to avoid the layout issues within the iframe.
@ Kris: Hi Kris, read comment 119, there’s a bespoke sort function that sorts currency values containing commas.
Thanks FD. Actually the sortable-currency worked. It was the 3rd column and I did not code th for the second column and hence the problem.
Hi again!
It seems as if you’re right (#153). Links seems to be the best for now. I was thinking that it might be possible to define an accesskey – but after a bit of googling it doesn’t seem to work.
I have another idea for your wonderful script. One of my columns have a formatted date that looks like this “Feb, 22 2006 13:15”. While it would be possible to write my own custom sort function this seems to complicated for my scenario. Reason: My column is always sorted from the beginning. In my database I’m storing the date as datetime, that’s why it’s really easy to sort using the database instead of creating a custom sort. Would it be difficult to make your script remember the default order using a sort-keepOrder? This could be useful to anyone that has a predefined order (like 9, 3, 1, 6, 5, 2) and would like to keep it and be able to reverse it.
The first time I click a column (to sort it) AND it’s already sorted I will have to click twize to get the reverse sort. Clicking only once doesn’t give any effect to the user. Is this a feature or a bug? I’m thinking that my users will not understand that they have to click twize, so I’m suggesting it’s a bug :-)
Last thing: Using the arrow makes my table (width 100%) shift its size all the time – the rows keeps getting bigger and smaller whenever I sort on it. I’m not sure why this happens. Do you?
BTW: Your script is brilliant!!!
I think this code solved my problem (add on line 285)
if (th.className.search(/sortable-keep/) != -1) { txt = rowCnt;} else
I didn’t work. The row order got “scrambled” when I sort another column.
About my third problem (arrows). When using my own custom arrow images the column width doesn’t change.
It does work! But only when adding the code in #159 and replacing line 396 with this code:
if(thNode.className.match(/sortable-numeric|sortable-currency|sortable-date|sortable-keep/))
@ Kris: Hi Kris, glad you managed to sort things out.
@ Kia: Hi Kia, when not using custom arrows, the script dynamically adds a span to the currently sorted column. It’s this span that is making the columns grow/shrink. As you mentioned, using CSS based arrows removes the problem all-together.
I like your sort-keep idea and shall try to add it as an option to the next release.
This is because the script doesn’t know that the column is already sorted. It would take a severe amount of clock cycles to see if a column requires an initial sort (of course, the “sort-keep” columns never require an initial sort and this would be easy to catch) and so, for the moment, the “bug/feature” will have to stay. Sorry.
Regards,
Brian.
This is just fantastic – works a treat for me with less than five minutes to get it up and running (and I’m by no means a geek!) THANKS
I really love your script, I have a webpage with about 100 users all the time. Your script saves me a lot of server requests. Thank you!
I have a little problem. It is that I want to group the rows for better viewing.
My plan is to place a row before every row that has id=”0”. The result is that the rows is in the top or bottom. Can you give me a hint, where in your code I can make such an if statement?
@ Dave: Hi Dave, glad you like the script.
@ Thomas: Hi Thomas, I don’t really understand what you mean. In HTML, all id’s are unique – that’s to say, only one on-screen element can have an id of “0” (in fact, “0” is an illegal id as id’s cannot start with a number but that’s another story).
It appears to me that you wish to create two callback functions, the sortInitiatedCallback() will remove these “new” rows before the sort takes place and the sortCompleteCallback() will add these new rows after the sort completes.
Imagine the rows you wish to insert are given the className “inserted”, the sortInitiatedCallback() will look something like this:
sortInitiatedCallback(tableid) { // Remove all rows with the className "inserted" var rows = document.getElementById(tableid).getElementsByTagName("tr"); var i = rows.length; while(i--) { row = rows[i]; if(row.className.search("inserted") != -1) { row.parentNode.removeChild(row); } } }...and your sortCompleteCallback function will do the inverse i.e. add the rows where appropriate and give them the className “inserted”.
Hope this helps,
Brian.
Hi, do you think its possible to add an algorithm that user could hold Ctrl key while clicking headers, and that would sub-sort columns?
I saw this algorithm once for JTable in Java, works nice, but i don’t know about the Ctrl key in your script…
Hi! First of all, Id like to say your script rocks and is very useful.
... else if (childNode.nodeType document.ELEMENT_NODE x%x%x%x% childNode.tagName.toLowerCase() “select”) { txt += childNode[childNode.selectedIndex].text; } ....Can you pls add support for TD items that contains list box? for example, when traversing thru innerText, can you add a condition something like this:
Or is this better-off as a “plugin” as opposed to a core feature?
Id like to add a suggestion: pls use “document.ELEMENT_NODE” or “document.ELEMENT_TEXT” instead of using numeric constants for readability :) thx!
@ Frequency Decoder : Morgan, I’ve updated the script to deal with colspans. Read the 2.9 update below for more info.
Thank you. I have had no time yet to test this new version, but good work.
Let me start of by saying I LOVE your program.
But, I am having trouble using the jsWrapper function.
When i call it the javascript console says colnum undefined.
I tried editing the source,
fixing the case of colNum in the jsWrapper function: colnum to colNum.
js console stopped complaining but the script seems to do nothing.
Could anyone help?
Thanks!
I forgot to metion in #169 that I am using v2.9
Brian, this script is pure gold. I’ve tried other scripts but I think this one really rocks.
I’ve just one problem (and one feature requirement, LOL).
The problem: I have a table and I want to load it not sorted but sortable.
So I don’t need to use sortable-onload, but without it the table is not “zebred” when it loads. Then it’s enough to click on a TH for sorting the table and zebra is back!
About the new feature I’m speaking about highlighting dynamically the row with the mouse (like in “Better Zebra Tables” script).
Thank you again for your very nice work.
@ hiamah: Hi hiamah, if you can point me to the algorithm in question, I’ll see what I can do.
@ stephen: Hi Stephen, I’ll leave it up to you to add the selectList change to the script. As for using ELEMENT_NODE etc, Internet Explorer doesn’t understand the DOM nodetype constants and I don’t want to add another 4 lines of code that declares them in IE just for the sake of readability – sorry!
@ Morgan Capron: Hi again Morgan, the 3.0 version also supports rowspans.
@ scotty: Hi scotty, I’ve fixed the bug in the 3.0 release. Thanks for the heads up.
@ Paolo: Hi Paolo, I won’t be adding support for just zebra striping as this is something that should be done server side before the script gets sent to the client – this way, non-javascript enabled devices also get the nice zebra-stripe effect on the initial table.
If you have no control over the server-side processing, It’s also very easy to write a script that does it client side (a matter of 5 lines of javascript).
Also, the dynamic row highlighting can be achievied using pure CSS (tr:hover) for everything but Internet Explorer, which itself can be fed a small block of javascript wrapped in a conditional compilation command or another CSS file (that uses an .htc behaviour) using conditional comments.
I just want to keep the script a “table sort” script and leave other effects etc to add-on scripts etc.
If you want the code for the initial table-striping and IE hover effect, mail me at brian (at) modernartcafe [d0t] net and I’ll send it on.
Regards,
Brian
Hi Brian, do you know MooTools? (http://mootools.net/)
They have a amazing framework which accept plugins. I think they don’t have sorting for tables yet.
First up, excellent script. The way the date regExp stuff is done is awesome and very easily allowed me to add about 8 other date/time entries and have them work (changing the static 3 to dateTest.length).
The setup I’m using is that when a menu option is selected, the contents of a div is populated with information that includes a table. The first issue I encountered is that I cannot use the Event.observe due to this only being called when the main page and javascript is loaded, which occurs before the div is populated.
If i call fdTableSort.init(); once the div is populated and the table fully loaded, it works perfectly. If I then click another menu entry that repopulates the div with another table, I’m not sure what I should be calling to sort the next table. If I call fdTableSort.init(); a second time, I get no sorting occurring. This can be seen on your dynamic table page (http://www.frequency-decoder.com/demo/table-sort-revisited/dynamicTable.html) if you click the “Create Table” link a second time.
Any thoughts on this would be greatly appreciated. Keep up the good work.
Thank you for the great script, it is truly amazing!
I have a question. My table contains groupings with subheaders – think of sections like SUVs, 4-door, 2-door, minivans, etc, each section having a subheader row (with a spanning all the way), and the data rows underneath. There are several sections like that and each has its own set of rows.
Obviously the script sorts everything and puts the subheader rows together, while I want them to stay fixed in place and only sort rows that represent “true” data, resetting the sort at each section break.
Example of the expected sort by year (I am comma separating them to make it compact, these are all rows in reality):
2-Door
1998,2000,20003,2005
4-Door
1998,2000,2003
SUVs’
1999,2006,2007
Minivans
2001,2005,2006,2006
Do you think something like this is possible or can be added? Do I need a way to flag these rows somehow so that the script bypasses them and restarts the sorting process at each section break?
Thanks in advance!
@ hiamah: Hi hiamah, I think someone is currently trying to port the script to mootools.
@ Gavin Grieve: Hi Gavin, when I wrote the code, I took it for granted (first mistake right there) that only the table body would be re-rendered – in fact, almost everyone redraws the entire table which throws the code a bit.
To fix the problem, just remove the if statement that spans lines 90 – 103 and things will sort once again. I’ll remove the offending code from the next release (and I’ll try not to make such sweeping assumptions about other peoples code again…)
I’m glad you like the date thing… thats the bit of code I like the best…
@ Mark: Hi Mark, I’ll have to sit down and have a think about this one. If it doesn’t take a mountain of code to integrate, I’ll add it to the next release. I’ll update your original comment when I’ve thought it over.
@ All & Sundry: Sorry for taking so long to reply to your comments but I’m just about to become a dad for the second time and so scripting etc has lost a few priority points (and has been replaced by thoughts of cots, daipers, double-prams etc).
Hi! there is a bug in sortByTwelveHourTimestamp custom sort function.
“12:59 AM” always comes before “12:23 AM” (in ascending order). how come?
Hi – excellent script, much better than the alternatives i’ve been looking at.
Just one query – i’ve been trying to get one of the columns on the page to sort by date – the date format is longhand “January 2007” etc.
Using the sortEnglishLonghandDateFormat function seems to work fine in Firefox, but causes problems in IE6 and Opera – the years appear in the correct order, but the months are incorrect.
Any ideas? I’m a javascript novice!
page is at: http://www.wdm.org.uk/resources/reports/listbydate.htm
thanks!
I have tried your script and find it great, and I have a few suggestions.
When loading a webpage, my tables are already sorted, so I don’t really want to sorth them again. I do, however, want to zebra-stripe them, and to do that I have to sort them, which takes about 20 seconds (pretty large tables, yeah). So, it would be good if there was an oninit function we could call that would just do the zebra-styling.
Also, you could shave some 14 kb off your code just by removing ^[ ]* (whitespace in the beginning of the line).
@ Stephen: Hi Stephen. I’ve altered the function – it should work now. Additionally, I’ve added code to deal with the special caases “12 midnight” and “12 noon”.
@ pete: Hi pete, it was because Internet Explorer will not take a third argument to the String.replace method. It’s fixed now.
@ Poromenos: Hi Poromenos, as I’ve said already, the script is a tablesort script, not a zebra-striping script. I assume that the initial table is already zebra-striped on the server.
If you can’t zebra-stripe the table server-side, I’ve a small plug-in to the script that I can send you that automatically zebra stripes the tables (and adds a row hover effect for Internet Explorer). Email me at brian [at] modernartcafe (d0t) net and I’ll send you the plug-in.
As for the 12k savings, I’m waiting for the new version of Dean Edwards packer script that will be able to handle Internet Explorer conditional compilation statements. This will shave a lot more than 12k from the download but until Dean makes the script available, you’ll have to strip the spaces yourself – sorry.
This script is a LIFESAVER. Really well done. I have one quick question. I’m having some problems sorting on a colum with dates…. the problem seems be that the information is in the format ‘10/23/2006’ which is fine, but when it encounters ‘10/3/2006’ it gets confused and can’t figure out which came first…. Any suggestions? Thanks!
@ Scott: Hi Scott, you should explicitly give the TH node a className of “sortable-date”. If this still doesn’t fix the problem, download the latest version (3.1) in which I made the parseDate function as bullet-proof as is possible.
How do I get the pagination demo to work with a multiple of 10 rows showing? e.g.: paginate-20 results in the table being cut up correctly, but the page links do nothing. Thanks in advance.
Nevermind, I’m an idiot. I didnt realized that the titles were repeating every 10 lines. This script is off the nut.
I double checked both of those things, and it didn’t seem to fix the problem. I posted an example here:
http://www.aislewalk.com/ScreenCaps/aislewalk_com.htm
I could very well be doing something wrong, but it all looks okay…
@ Danny: Hi Danny, glad you got it sorted out.
@ Scott: Hi Scott, you really need to clean up that HTML my man… here’s the offending line (square brackets used to stop textile going nuts):
[TH class=sortable-date]Received[/*TD*]
You seem to have closed the TH tag with a TD (and need to quote all your attributes etc).
Hope this helps,
Brian.
thanks – this works really well now!
Your tablesort is great! However, the title on the headings is set to “Sort on ”+thtext, which isn’t much use if the table isn’t in English! :) See Line 159 in v3.1. Perhaps the line:
aclone.title = “Sort on ” + thtext;
can be changed to :
aclone.title = workArr©[i].title || “Sort on ” + thtext;
This way, if the table heading tag contains a title attribute it will be used instead. It means it plays nicely with the mootools tooltips too ;-)
I have a complicated table with many colspans (ie group by report) and have found that to show and sort properly I have to break the table up into many tables (one per group). I was wondering if there is some function I could put on my page that when you click on a column of any of the tables, it would automatically sort every table on the page by that column? I got the script to sort all the tables, I just need to figure out how to grab the column clicked? Thanks Paul.
Yeah, the html is a mess, sorry about that. Here is a cleaned up version with nothing more than 2 tables. It seems that the regexp gets confused when it’s evaluating a date that has only 1 digit for the day, and 1 digit for the month.
http://www.aislewalk.com/screencaps/testdate.html
You can see that when the 0 is added to the dates it works very nicely. I tried to fix it in the js file, but your code is WAY about my head.
Hi guys,
I’m a css guy not a JS one… so I’m fumbling through tweaking this script.. I’m trying to add into the zebra strype function this “clickable row” script: http://radio.javaranch.com/pascarello/2005/05/19/1116509823591.html
I’ve been messing around with it but can’t figure out where to implament something along these lines:
var link = rows[i].getElementsByTagName(“a”) if(link.length == 1){ trs[i].onclick = new Function(“document.location.href=’” + link0.href + ”’”); }// make rows clickable
@ Pete: Good stuff.
@ Brian: Hi Brian, The “Sort on” text is usefull for people using screen readers and was actually integrated into the code due to feedback from a JAWS user. Feel free to remove it for your purposes though.
@ Paul: I’ve sent you a fix by email.
@ Scott: I’ve sent you a fix by email.
@ Jesse: I’ve sent you a fix by email.
Regards,
Brian
Thanks for this really great script! Glad to see you did a paginated version. I made one several months ago. Not nearly as compact as yours, but does feature forward/back, last/first buttons – and an optional #results per page. I’d be happy to share it if you’re interested.
RE: Date sorting, I ran into an issue today with it not sorting quite right on dates missing leading zeros.
Thanks Again!
Update: Hi Matt, the regExp's for the dates require the leading zeros as, without them, it's impossible to say if a date is dmy or mdy (for certain dates like 1/1/2007 or 3/4/2007), which would lead to incorrect sorting.
You can add the "?" character to the regExps to enable parsing of dates with single numeric characters for the date or month parts but if you don't explicitly tell the script the column is dmy (when the column is day/month/year), there's a chance the script will parse a m/d/y date.
As for the pagination, if you add a link to your script within a new comment, people will be able to download and use it.
Thanks for the comment,
Brian
Hi,
This script is fantastic, and exactly what I needed. One question though. I have a table that is dynamically updated via AJAX, I have the script working OK with it by calling prepareTableData manually every time the table is updated, but how can I automatically re-sort the table, using the same rules as the previous sort. So basically the sorting remains the same, but new rows will appear.
If that’s not possible, how can I do a reverse sort with the jsWrapper function?
Thanks again!
Jack
@ Jack: Hi Jack, just call the jsWrapper twice to reverse sort. You know when you need to reverse sort if the TH node contains the className “forwardSort”.
Hope this helps,
Brian
Dear Brian,
I am attempting to make my table sortable. It is generated by PHP pulling from mysql database. Is it possible to add table sorting to this type of dynamically-generated table? If so, I have not figured out how. Column headers appear as links, but clicking does not sort columns.
Any help would be appreciated-
thanks-
tim
This script installed so easily and I was up and running in just a few minutes. However, my table is pulling some info from a MySQL database where time is recorded in the table as 00:00:00. My SQL query does a TIME_FORMAT to “1:30 PM”, and I’m finding that the sorting does not differentiate 9:30 AM from 9:30 PM. Any ideas?
Sorry – I found your custom scripts!
It’s working for some but not all of the sorting; it’s working like this now:
1:30PM,2:00PM,9:30AM,11:00AM,12:00PM
I am a newbie to javascript. Just surf on the net, looking some code for sortable table header. I read your page. I have tried to implement what have been said, but my table did not sort at all.
I am using dynamic page (cold fusion query to output the result inside the table). My page contains more than one query. Will anybody help me?
@ Tim Paine: Check your email.
@ Aaron & ellisegirl: Hi guys, I really need to see the page(s) in question in order to spot the problem. Leave me a URL and I’ll have a look.
Regards,
Brian.
Brian, this script is quite elegant. well done.
One issue I’m having: I’m using the prototype-window library and I’m bringing html tables in via an Ajax.Updater call into a “window” (think DIV). btw, these tables have preset IDs. At this point, the document has already called init onload and hasn’t yet seen these ajax-d tables before, so I’m calling “init” again which I know re-initalizes all tables. Is there a better way to add just 1-2 more tables without a “init”?
Also, when I close the “window” (div), re-open, and re-ajax-request the tables again, the “init” no longer works. I tracked it down to the fact that the table IDs remain in tableCache and tmpCache. So, I’ve added a “delete fdTableSort.tableCache…” from both tableCache and tmpCache specifying the table IDs. Now I can “init” after each ajax request over and over which works.
It seems a single table “add” and “remove” would be a nice enhancement. I’ve read through this list and #174 sounds similar but not quite. Any thoughts?
@ Mike: Hi Mike, the new version of the script (3.3) enables you to pass a table ID to the fdTableSort.init method. This will automatically destroy the two internal objects for the table in question and recreate the links etc within the table’s TH nodes.
Hope this helps,
Brian.
I have a question identical to Tim Paine’s (#196). Anything you can post here?
@ Mark: Hi Mark, I can only help you if I can see the actual HTML code. Post a link to the page in question and I’ll see what I can do. Normally, it’s badly formed HTML that’s the problem, so, check your HTML is well-formed and if this isn’t it, leave another comment stating the URL.
Thanks,
Brian.
Hello Brian,
I have posted a message a while back (see “Mark #175 · Wednesday February 28”), and I am just curious if you had a moment to think through the concept I posted – it’d be huge help for me and I am sure a useful addition to the script.
Many thanks!
Mark
@ Mark: Mark, it is possible but only if you split the one large table up into smaller tables. The multiple table demo does exactly that. Accessibility-wise, it may not be perfect but it’s visually identical.
Regards,
Brian.
I’m having problems using the script with the sortable-sortImage class. I don’t use only the img-tag in the TDs, but also regular hyperlinks. In other words, (a href=blah) (img src=foo) (/a) etc.
The sorting doesn’t work. I’ve tried it with other sort-types, but got nowhere. (tested in Opera 9, FF2, IE6 / Win2k).
Any idea or tip?
Brian,
First of all, love the script! I stumbled across it a while ago but haven’t had the chance to implement it anywhere, until now!
I have 2 comments:
1) I am also using prototype on the project and this seems to be causing an issue. When the page loads, I am getting the following:
Error:
workArr©[i].getElementsByClassName(“a”)[0] has no properties
at Line 142:
workArr©[i].getElementsByClassName(‘a’)[0].onclick = workArr©[i].getElementsByClassName(‘a’)[0].onkeypress = null;
I am by no means a JS expert but managed to track the issue down to the following within the Protoype lib:
Code:
getElementsByClassName: function(element, className) { return document.getElementsByClassName(className, element); },I do not have the need for the “getElementsByClassName” function (for the time being at least) so have commented it out of Prototype. This fixed the problem and the tablesort works perfectly.
Is this something which you have come across previously?
2) One of the columns I want to sort on contains “date” data in the following format:
dd/mm/yyyy hh:mm:ss
I have given the TH tag the “sortable-date” class but the column doesn’t sort correctly, I am assuming that the “hh:mm:ss” section of the data is confusing the script somehow? Is there a custom sort function which will handle this data?
Your comments would be much appreciated.
Regards
Lee McMullen
I came over to complain that v2.9 was bailing with js error:
“Index or size is negative or greater than the allowed amount” Line: 232
if you call the autosort on an empty table… but.. I tried v3.3 and you already fixed it!
I cannot tell you enough how happy I am to use your script.
@ Dragan : Hi Dragan , I’ll need a link to th page in question in order to trace the problem.
@ Lee McMullen: Hi Lee, yep, prototypeadds a getElementsByClassName to the Object prototype (I hink) which my script attempts to iterate over using the “in” operator. I’m going to have to start to add a check for this in my scripts where possible.
As for the date format, the regExp’s used to parse a date will fail when passed the hh:mm:ss part of the datetime data. You’ll have to write a custom sort function for this. It shouldn’t be too hard so I’ll give it a go at some point in the near future.
Update: Heres something (throughly untested) that may point you in the right direction:
function sortDMYTimestamp(a, b) { return fdTableSort.sortNumeric(a, b); } function sortDMYTimestampPrepareData(tdNode, innerText) { var matchs = innerText.match(/^(0?[1-9]|[12][0-9]|3[01])([- \/.])(0?[1-9]|1[012])([- \/.])((\d\d)?\d\d) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/); return matchs.length ? String(matchs[0]) + String(matchs[2]) + String(matchs[4]) + String(matchs[5]) + String(matchs[6]) + String(matchs[7]) : ""; }@ Scotty : Hi Scotty, glad you like the script (and I’m glad the problem was fixed between releases).
hey! great script!
is it possible to show the pagination (1-2-3-4-....) not only under the table, but also ABOVE it?
Thank you!!!
Hi – and yet another thanks for a great script.
I’m not able to get it to work with a nested table. Even the simplest sub-table causes the sorter to choke. Here’s a super-simple sample – any help would be greatly appreciated!
@ Harald: Hi Harald, it’s very possible but just not at the minute as I’m currently nursing my newborn son. I’ll be recommencing all things “development” in May/June and may try to do it then. Sorry if it’s a long wait but the kid takes precedence!
@ Jeff: Hi Jeff, it won’t work on nested tables – period (I hope the’re not being used for layout old chap or the standardista cartel will invariably dispatch a squad of goons in your direction). Sorry to be the harbinger of bad news.
Update: Hi Jeff,
in fact, if I iterate over the childNode collection instead of using getElementsByTagName then I should be able to support nested tables. I'll try to add it to the next release for you (whenever that is...).Fixed thanks to Chris.Hello,
thanks for your great script. I tried to mix it with a decent script that fixes the table-headers while still scrolling the body. That’s an important feature in really big tables, I believe. There is only one script I found, which works in IE, Firefox and Opera. It was here: www.imaputz.com/cssStuff/bulletVersion.html But now only a Google cache version is still available. It works with your script in IE, but in other browsers the rows aren’t straight anymore. I’m completely lost in the code. Would be glad for any help.
Michael
I found a serious bug. The table sort fails badly when the contents of a cell in the table is itself a table with cells.
You need to add:
if (tr.parentNode != start) continue;
at line 294 or so, just after this line:
tr = trs[row];
Cheers,
Chris
@ Michael J: Hi Michael J, have a look at cody’s pushpin technique
@ Chris: Hi Chris, I never expected people to embed tables as data so I never supported the feature. You are a star though as you’ve found what is possibly the easiest way to solve the issue (I was just yesterday playing with all sorts of overly complicated solutions to the very same problem).
I’ve changed the code and integrated a fix based on your solution. The only caveat though is that the parent table must have a tbody node for embedded tables to work. A small price to pay.
Thanks again for the fix.
I’m using a function to dynamically add a row to the table. I use appendChild to insert the new row in the table. The trouble is it’s added at the bottom, but I want it to appear at the top (since the new row will be include a newer date/time field which is what my initial table is sorted by). How do I get the table to sort again after the row has been appended? Using Firefox. I’ve tried fdTableSort.init and fdTableSort.jsWrapper but neither seem to do anything (I do include the id of the tbody in those calls). Thanks for the excellent script and examples!
@ Erik: Hi Erik, I’ve no problem appending a new row and then calling fdTableSort.init – but you have to pass the id of the table, not the tbody, as shown within the testcase provided.
Hope this helps,
Brian.
Doh! Thanks for the testcase as it helped me correct another error as well.
I have discovered an anomaly… Let’s say there’s a number of rows with the same time in one column and the same date in another, except for one is perhaps the day prior. Like 6 rows – all with time 4:30 pm, 5 having date of 4/4/2007, and one with date of 4/3/2007. Sorting by time will place the one with date prior in a random row. While the expected result would be the day prior at the top of the table if time is sorted ascending and vice versa.
Is there a way to take control of this?
The tablesort js is great. I would like to know if there is a limit on the number of columns that may be sorted i.e. [0-9]
My 10th and 11th columns do not have hyperlinks to sort. Taking away the first two columns from my table makes the old ‘10th and 11th’ sortable.
@ Erik: Hi Erik, the script shouldn’t even attempt to sort identical columns so you have ound a bug (which I’ve already fixed). Apart from that, it’s expected functionality (the script doesn’t replicate the SQL “order by” clause i.e. it sorts only on the column specified and forgets all other column data during the sort).
@ Kieran : Hi Kieran , can you sen a link to a test page as I have no problem sorting tables with over 10 columns. Thanks.
I don’t have a test page to access though i have narrowed down the problem. Four of my columns are hidden at any one time by another javascript – to toggle between displaying text and percentages. (8 columns in total using this toggle function). Without this enabled, sort works on ALL 12 columns. With this enabled, it only works on the first nine.
if (foo 'percent') { changecss('.numbers','display','none') changecss('.percent','display','') } else { changecss('.percent','display','none') changecss('.numbers','display','') }function togglepn(foo) {
}
}
display: none;.percent {
}
.numbers { display: ;
}
function changecss(theClass,element,value) { var cssRules; if (document.all) { cssRules = 'rules'; } else if (document.getElementById) { cssRules = 'cssRules'; } for (var S = 0; S < document.styleSheets.length; S++){ for (var R = 0; R < document.styleSheets[S][cssRules].length; R++) { if (document.styleSheets[S][cssRules][R].selectorText theClass) { document.styleSheets[S][cssRules][R].style[element] = value; } } }
}
the 8 toggled column th has two class’s: percent sortable-numeric
Brian, as a followup to #201, I downloaded 3.5 today and it works perfectly as you stated with repeated AJAX requests – this allows me to remove some extra code. And I’m glad to see you worked on a memory leak in IE as I have seen my IExpore process grow quite large although it could be the ajax requests. The sort also seems a tad faster in the latest version, but that is just me eye-balling it. Congrats on the new baby! If your responses turn into jibberish over the next few weeks, we’ll all know why. – Mike
I need to sort a table that has two levels of hierarchy.
Currently the hierarchy is not implemented as nested tables, but simply with the child rows having a different class than the parent rows. Both parents and children have all the same data columns.
When sorting, the children should stay with their parent, but be sorted according to the same criteria.
Can you give me a hint at how I might go about refactoring the script to work with such a table?
If you don’t have a thead arround your header row, then the header row will also be moved. A solution to this is replacing a small part of the prepareTableData function:
(start.tagName.toLowerCase() == “table” && tr.getElementsByTagName(“th”).length)
should become
tr.getElementsByTagName(“th”).length
@ Kieran: Hi Kieran, adding two classes to the th node shouldn’t be a problem. I currently don’t have the time to look into it any further – sorry!
@ Mike: Hi Mike, glad the update solved the problem.
@ Michael Johnston: Hi Michael, you will need to change the prepareTableData and initSort methods to take the parent/child relationship into account. It won’t be an easy task (you have to sort the parents and then, for each parent, sort the children – the problem arises in how you will store the parent/child relationships). Sorry I can’t be more help.
@ Kristof Coomans: hi Kristof, thanks for that. I’ve fixed the problem within the 3.6 release.
Thanks for fixing the bug.
Maybe you can add another custom function example with the natural order comparison function I wrote.
function sortNaturalOrder(a, b)
var aa = a[fdTableSort.pos]; var bb = b[fdTableSort.pos]; return natcompare(aa,bb);{
}
Cheers
Hey this is an awesome script. The only thing I am missing in it is the ability to keep a row highlighted after clicking on it. The roll-over highlighting works well, but isn’t really that useful if your users are trying to ‘select’ some rows. Even better would be the ability to select the rows and then have them sorted separately to the top/bottom whenever a column is sorted.
BTW, CONGRATULATIONS on your second little bundle of ‘joy’ ;)
I was wondering if it is possible to preload the rows into a JavaScript Array.
My problem is, I have a significant amount of rows and they each have an icon that’s 40×40. Unfortunately, the creation of the clickable headers and pagination links wait until each image has been loaded in order to display.
I would like to be able to specify an array of contents. That way only the first X number of rows will be displayed and have their images loaded….
@Eric
Have you tried pagination?
@Frequency Decoder: Thanks for the reply. cody’s pushpin technique isn’t of much use. The header moves around in Opera if scrolling.
Now I found a really decent script that works perfect in Firefox, IE and Opera. It’s here It almost works with your amazing script which I’d really like to use and combine. The onload sorting in table’s class works fine but it doesn’t work by clicking the links. Any idea?
@Scott
I have, my problem is; generating all of the html code code ahead of time forces the browser to download all of the images within the table before the pagination script runs…
@ Kristof Coomans: Hi Kristof, I’ll add a link on the custom sort functions page. Thanks.
@ Barius: Hi Barius, adding the ability to select table rows means adding callback functionality etc. (i.e. selecting the row will need to call some sort of function not within the scripts scope) – it’s something I’m going to leave as an “excercise for the reader”. Oh, and that “bundle of joy” is seriously keeping me awake at night – I’m already on my third coffee this morning! He’s great though…
@ Eric: Hi Eric, you just need to add a script block below the table that calls the tableSort.init method for that table (this way you bypass the onLoad event completely so it doesn’t matter if the icons have loaded or not). Also, you may wish to remove the onLoad event from the tableSort.js file (it’s the very last line in the file). Problem solved.
@ Michael J: Hi Michael, I just don’t have the time to get a testcase up and running. If you send me a link to the page in question, I’ll see what I can do.
Of course. Here you go. Thanks in advance!
This script looks awesome. Thanks for creating it. I can’t wait to try it out.
I am new Dad too (for the first time) and I know how true your warning is about not getting back to people for months. Enjoy your baby!
Oh, I see clouds comming up … Firefox 3 a3 passes Acid2 but your wonderful script doesn’t work any more. Why is that? Opera also passes this test but your script works. So is this a bug of your script or a bug of the new Firefox engine?
Thanks for this great script.
Since you mention uncompressed, is there a compressed version?
@ Michael J: Hi Michael, thanks for the testcase, I’ll have a look this weekend.
@ phill: Hi phill, congrats on the new addition to the family!
@ Seth: hi Seth, I’m afraid that currently, no compressor can handle Internet Explorer conditional compilation so it’s impossible to provide a compressed version. Dean Edwards will be integrating support for conditional compilation into the next version of his compressor so, when it’s available, I’ll be providing compressed versions of the script – until then, it’s uncompressed I’m afraid.
@ anon: Hi Anon, as it’s an Alpha release of Firefox, I’m not particularly worried that the script breaks. Additionally, the “Acid2 test” tests only CSS, not JavaScript, so it has no relevance to the script. The problem must be with the JavaScript engine bundled with A3.
Also, “I see clounds coming up” – a bit dramatic don’t you think? (the correct term is “I see clounds on the horizon” by the way). As soon as Firefox is in production, I’ll worry about support.
@ Michael J: Hi Michael, the scroller script is actually creating three complete tables, all with the same id (“mainTable”). Install FireBug and inspect the DOM to see for yourself.
The first table is used to display the fixed table header, the second to display the table content and the third the table footer. The tablesort script will never work under these conditions as clicking on a TH will require a sort to the contents of an entirely different table.
Sorry for the bad news!
Unfortunately, I can’t get this script working together with mootools :(
If mootools is included, it just does nothing… sometimes (not everytime) FireBug throws this:
“workArr©[i].getElementsByClassName(“a”)[0] has no properties”
Any ideas?
Hello again, and congratulations on the new addition to your family! Again, nice script – don’t know if the particular problem was fixed in a previous version; the version I’m using classes each th that is sortable initially, correctly putting in links. However, when the preparedata function is run later, the non-sortable ths slip through because of this line:
if(txt != “” ) {I changed it to this:
if(txt != “” && th.className.search(/sortable/) != -1) {which seems to work; on initial pass, it manages to exclude those without a “sortable” class, and subsequently excludes those that don’t have “sortable-text” etc.
Pat Kelley
Thanks for trying. Well, but it still works with the onload function. I can think of a hack. Not very pretty, but still the best I can think of: I could include the table body with PHP and make a html file for every possible onload sorting. I just need to know 2 things: How do I make a link inside the th-tags visible / don’t let the js sorting links show up? And how do I make this conditional, so that the js sorting still show up if ”?noTableScroll=true” is active?
Hi Brian, any chance of getting some help with extending the script to handle checkbox sorting? This test page describes what I’m trying to do. I would appreciate any assistance with adding “onclick” events to the checkbox elements and accessing the internal 2D table data matrix. Thanks in advance.
hi, nice work! i’m not good at javascripts… i want to sort a directory listing (like the apache ones) – so what could i do to keep the “parent directory” entry at top (similar to tfoot)?
Great work. I’ve searched for a script such as yours as it exactly meets what I need (and more!)
However over the past several weeks I’ve been trying to get the zebra scripting to work and have been struggling to get it right.
I have a table that has 2 different colors already zebra-stripped upon load, but neither of them is the background color. When I implement the code and add zebra stripping the one row invariably loses its colorization and just uses the background color.
Today I thought… hmm what if I make the entire table have the primary background color and then just alternate every other row with the alternate color (also the one tied to the script) This – thankfully seems to work great.
Guess me question is – is this the best way to do it.
Sample: http://effectperformance.studio5d.com/qa/test2.php (this is the one that starts right, but does not have the table BG color set and when you sort it, it loses the primary color)
Sample: http://effectperformance.studio5d.com/qa/test.php (This is with the background color of the table set and seems to work well)
One more question. I want to be able to save the last user chosen so when the page is refreshed or reloaded the user’s sort selection remains instead of the default onload sort.
I figure I could do this by setting a cookie to whatever column number is selected each time a column is selected and then have the scripts onload use the cookie value (or a default if none exists).
My question is can you point me in the right direction as to what JS variable that will be or where that is called/set?
Thanks
@ Rafael: I think mootools is hijacking the page’s unload event and removing getElementsByTagName.
@ Pat Kelley: Hi Pat, I think a later version of the script fixed the problem in question (and thanks for the “congrats”, he’s still keeping me awake at nights though!).
@ Michael J: Hi Michael, just change the init method to check if the window.location contains the ?noTableScroll string and if it does, just return from the method.
@ Stachor: Hi Stachor, check your email.
@ nerdpunk: A simple solution would be to integrate the first line into the table header, this way the script will not use it within the sort process. Otherwise, wait until the next release – I’ll add support for non-sortable rows.
@ Paul Schneider: Hi Paul, check the demo CSS to see how it’s done. I set a default colour on the TR and the alternative colour on the TR.alternative.
As for the last sort position, you can grab the info from the data cache i.e.
fdTableSort.tableCache[your table’s id].pos
You can also set the cookie within the sortCompleteCallback function.
Regards,
Brian.
Thank you so much for providing such an extendable sorting library. I was able to replace our old method in record time and now our sorts are accurate and style is consistent. Speaking of consistency… Keep on knocking out the hits! Also, contrats on the newborn!
Hello,
I would like to know If you plan to implement features such as pagin or resizable column or edit in place as grid control
Great Great Great, Hope ever one is sleeping for your :)
I am having problems with multiple different (not linked together as in your example) tables on one page. Is this supported?
Congratualtions!
any idea what would cause the column headers not to be displayed on pages after page one when using the pagination ? mine only show up on the first page.
Thanks for the help with grabbing the current sort position and sending it to a cookie.
I actually did something slightly different which mostly works and leads me to me follow up question.
In the removeSortActiveClass: Function() right about the if (“sortCompleteCallback-: + tablElem.id in window) line I added:
/*set position to a cookie function*/
var oqarcurrentpos = (fdTableSort.pos);
createCookie(‘OQARtablesortpos’, oqarcurrentpos, 1);
/*eof*/
This grabs the correct position number and sets it to the cookie, but 2 things.
1) For some odd reason when I read the cookie (which reads correctly) and then write it after “class=”sortable-onload-” it then sorts (on refresh) at 1 column smaller than the one in the cookie.
So if the cookie and old sort was set to column 5, then for some reason the sort function sorts on column 4…. very strange. Anyhow – I solved this by just added 1 to the value and it seems to work okay.
2) I realized that I also really need to save whether the sort is reverse or not. I tried a number of different things that looked like they may be the stored reverse value, but no luck. Can you point me in the right direction for capturing this info as well?
Thanks much for your previous help!!!
@ Jereme: Hi Jereme, glad you like the script…
@ Sébastien Cramatte: Hi Sébastien, I’m not going to extend the script like this… sorry!
@ Philip: Hi Philip, it is supported, in fact, the plug-in page has many different tables that all get sorted correctly. Make sure you have given your tables unique id’s.
@ Josh Nelson: Hi Josh, make sure the headers are wrapped within a thead.
@ Paul Schneider: Hi Paul, for the reverse sort, just add the letter “r” to the end of the cookie if the current sort has been reversed – this will make it easy to spot a reverse sort when the cookie is read.
To spot if a column is currently reversed, you can check the TH node (captured and stored within fdTableSort.thNode) for either of the className’s “reverseSort” or “forwardSort”.
Also, you will need to set the fdTableSort.pos variable to be the value of the cookie if a reverse sort is required.
Hope this helps,
Brian.
Thank You! This is a great and simple script!!
In a paginated table I created a drop down select menu that dynamically changes the table classname “paginate-#” to the user selected number. What do I need to do to call the pagination function to re-paginate the current page according to this change?
I downloaded version 3.6 (latest version), and the issue I’d mentioned is no longer there in IE, however it does show up in Firefox . If I designate two non-consecutive columns as sortable (with type indicated or not), the intervening columns are listed as sortable, classed appropriately, and affixed with the sorting behavior.
If I replace
if(txt != “” ) {
...on line 354 with:
if(txt != “” && th.className.search(/sortable/) != -1) {
...it seems to fix the problem.
Disregard my following comment. I figured a way to do it. It may not be the best way to do it but it certainly works.
I created a function to dynamically change the class name through the DOM
function rowsDisplayed(o,c1,c2)
var viewNum=o.className; var display=viewNum.replace(c1, c2); o.className=”sortable-onload-3-reverse rowstyle-alt no-arrow paginate-”+display;{
}
and I call it this way:
select onchange=”rowsDisplayed(document.getElementById(‘theTable’), document.getElementById(‘theTable’).className, this.value); Repaginate()”
option value=”10” 10 /option option value=”20” 20 /optionselect
Im also calling the Repaginate() function I made after the class name is set. which is this:
function Repaginate() {
tablePaginater.init();}
To prevent multiple pagelists from appearing I added the following at the very beginning of the createPageinationList function found in the pagination demo code:
var el = document.getElementById(‘paginateList-theTable’);
if(el) {
el.parentNode.removeChild(el);
}
Works like a charm of Firefox 2.0 & IE6
You will of course have to change the table ids to make it wonrl on your app.
If I embed the example table in my index.html file, the sorting works. But, if I go retrieve the same table using AJAX and insert it into a DIV using innerHTML, the sorting doesn’t work.
I tried calling fdTableSort.init( ‘test1’ ); but it doesn’t seem to help.
I’ve tested unsuccessfully in firefox 2 and IE 7.
What should I do? Thanks
//@ Philip: Hi Philip, it is supported, in fact, the plug-in page has many different tables that all get sorted correctly. Make sure you have given your tables unique id’s.
My problem turned out to be that i had no thead and tbody tags, which did not cause me a problem when I had only one table, but did when i had more than one.
Thanks again
Hi,
Thanks for the hints on finding the reverse code, however when I am doing some alerts to make sure I have it I keep coming up empty (undefined). Am I over simplifying things?
I added these to alerts to the removeSortActiveClass function (which is currently where I grab the pos – which is working great)
alert (“reverss ” + fdTableSort.reverseSort);
alert (“for ” + fdTableSort.forwardSort);
but it keeps coming up undefined. Ideas?
@ CensoredFreedom: Good stuff, I’m glad you got it working…
@ Paul: Hi Paul, you have to check the TH node for the classNames “forwardSort” or “reverseSort” i.e. fdTableSort.thNode.className.search(/forwardSort/).
@ Philip: Hi Philip, you may just have found a bug my man. I’m glad it works with the THEAD and TBODY additions though!
@ Ted: Hi Ted, you can’t create a table using innerHTML. You need to use DOM methods. Check out the Dynamic Table Creation Demo for pointers on how to do it.
@ Pat: Hi Pat, I can’t seem to replicate the problem – I’ve even tried using a table that contains no THEAD, TBODY etc but things all run smoothly. Send me a link to the page in question and I’ll have a look. Thanks.
I have a new dilemma.
I am intending to use this script in tables loaded within AJAX Tabs.
The first tab is simply included with a PHP include and the script works fine.
However when you change to another tab the script does not work in the tables in those tabs, also when you return to the first tab is doesn’t work.
So is it possible to reload and re-execute this script by attaching it to an onload of some element?
Ive tried almost everything!!
Hi again,
if (window.location.search != ”?noTableScroll=true”) return;I put in
right after
init: function(tableId) {
if (!document.getElementsByTagName) return;That works fine. The script is deactivated if ”?noTableScroll=true” is not there.
But that’s not what I wanted. I’d like the script to keep on functioning. I just want to get rid of the links inside the table headers.
So that < a onClick="..."> inside the table headers can show up which writes a cookie and reloads the page. The cookie’s value subtitutes the sortable-onload-# value inside the table’s class. So that the script is only functioning with onload and not with the links.
Hi there. Is there any way to reverse sort / jsWrapper? Nice script.
I was wondering what these lines of code are used for in your script:
workArr©[i].getElementsByClassName(‘a’)[0].onclick = workArr©[i].getElementsByClassName(‘a’)[0].onkeypress = null; }I can’t seem to find anywhere in your code where you define getElementsByClassName because I assume that is not a standard function? The reason I ask, as I’ve seen posts before, is that its conflicting with the prototype script. However, when I comment the your lines of code out of your script, everything still seems to work correctly. Any thoughts?
@ censoredFreedom: Have you looked at the Dynamic Table Creation demo? This may help you fix the script.
@ Michael J.: Hi Michael J, really, your looking into changing a substantial part of the scripts functionality. Try removing the code that creates the links within the “init” method.
@ Christopher : Hi Christopher , I don’t really understand what you mean – can you explain in more detail please. thanks.
@ Mark Ross: You’ve found a bug. I’ll fix it for the next release. Thanks for the info.
Thanks for your help. I got the sort store and reverse or not with a cookie to work.
I used the following code – but I do have one follow up question. As you can see from the ode I am setting it to reverse if the forwardSort value is -1. When testing, it seemed that whenever the reverse sort was chosen forwardsort would be set to -1 and vice versa when forward was selected.
My questions is, should I expect this to be consistent or am I missing something? (I thought basically it is telling me it exists if it was a positive value – though I couldn’t tell what exactly the positive value meant) and if it was -1 it did not exist (or was not chosen).
Code:
/*set position to a cookie function*/
var oqarcurrentpos = (fdTableSort.pos);
if (fdTableSort.thNode.className.search(/forwardSort/) == -1) {
oqarcurrentsortorder = ‘reverse’;
}
else {
oqarcurrentsortorder = ‘forward’;
}
createCookie(‘OQARtablesortpos’, oqarcurrentpos, 15);
createCookie(‘OQARtablesortorder’, oqarcurrentsortorder, 15);
/*eof*/
@ Paul Schneider Your right, I store the negation of the current sort so, as you surmised, forwardSort will actually mean reverse etc…
e.g.
var oqarcurrentsortorder = (fdTableSort.thNode.className.search(/forwardSort/) == -1) ? “reverse” : “forward”;
I’m glad you got the cookie code to work. Good stuff indeed.
i was wondering if it is possible to reverse-sort using the jsWrapper method. In other words, I am wanting to load rows into a table using Ajax, then sort descending on a column. It seems to me the method will only sort ascending, so i was hoping I was missing something. Thanks.
Any chance of this ever being rewritten to leverage jQuery? That would be TRULY AWESOME.
I found an error in the “Zebra plugin”
The line:
if(table.className.search(/rowstyle-([\S]+)/) -1) != -1) continue;
Shouldn't it be:
if(table.className.search(/rowstyle-([\S]+)/) -1) continue;
??
Thanks for this script, we really love your work.
@ Christopher: Hi Christopher, you have to forward sort before you can reverse sort so, just call the jsWrapper twice.
@ Adrienne Travis: Hi Adrienne, the whole point of the script is that it doesn’t rely on a JS Library but… if you’re up to the task of porting it to jQuery then feel free to do so (although, isn’t there a table sorting plug-in for jQuery already?).
@ okan ozkan: Uhhh, thanks. (Be carefull about your landing page Okan, I’m sure I’ve seen it before…)
@ Thomas DK: Hi Thomas, yep – what a hideous bug to have left in the code. I’ve updated the plug-in with the fix. Thanks for the info.
Just to be sure, you do know that the =’s has been striped in the comment, right? :)
Hi Brian –
I am having the same issue that Tim Paine had and you had emailed him about. I am pulling data from a mysql database to fill the table and want to sort from that.
Any help would be appreciated. Thanks in advance!
Nevermind…found an alternative solution. Thanks anyways!
@ Thomas: Hi Thomas, yeah, textile really isn’t geared towards posting code…
@ Josh: Glad you found a solution.
Josh Currier – Hi, you said you found an alternative. I am pretty new to programming and have been playing around with mysql and was looking for a way to sort data in a table. Could you share the solution you found?
has anyone been able to add the next/prev links on the pagination script? and/or move the pagination links above the table as opposed to beneath? if i could get any pointers on either, it would be greatly appreciated. thanks.
Thanks so much for this! Holy crap is it unobtrusive…
For whoever may be curious to know, I was able to position the table pagination above the table instead of beneath. My solution might not work correctly for anyone else, though, without some modification first. But here’s what I did:
Original code:
if(tbl.nextSibling) { tbl.parentNode.insertBefore(ul, tbl.nextSibling); } else { tbl.parentNode.appendChild(ul); };My change:
{document.getElementsByTagName(‘div’)[6].appendChild(ul);};}
I removed the “if” conditional and instructed the script to add the pagination to a div higher up, specifically the 7th one in my page. I actually wanted to navigate to that div by getElementById, but that wouldn’t work for me, for some reason. Oh well. I hope my little change helps someone else—again, though, the code will need to be changed to suit the containing page layout. Thanks frequency decoder, for the powerful, useful script. I appreciate your work!
Update by f.d: To place the pagination list above the table, simply use the insertBefore DOM method i.e.
tbl.parentNode.insertBefore(ul, tbl);I’ve updated the pagination demo to create two lists, one positioned above and one positioned below the table.
I am no coder and am a bit new to js, php, html, and MySQL, but your code looks and works very well.
I am donating my time to help code a web page for a non-profit that focuses on the prevention of child abuse and neglect.
I hate to sound like a total idiot and I have read and re-read the manual for this script as well as all the posts, but I do not see an anwer to the following delima.
I would like to be able to define the style (in CSS) of both the normal and alternate rowstyles for zebra-striping without effecting other tr and td styles. The code as I read it inserts a class or removes it to create the zebra effect, so a non-alternate row will use the default td style. Changing the “global” td style will effect the style of td site-wide, not only for the table being sorted.
Is there an easy CSS fix for this that is eluding me?
Thank you in advance for the help.
Seth
@Seth: Hi Seth, the answer that is eluding you is CSS specificity (info).
Just give the table to be sorted an id and then hang the style rules off of this hook i.e. if you give your table an id of #sortableTable then the following two rules will apply only to this table:
#sortableTable td { default row style } #sortableTable td.alternative { alt-row style }Regards,
Brian.
i love the script. it’s a very nice script. i have a question, is it possible to show the header always on top?
Thanks in advance.
Krishna Biyyam.
@Krishna: Namaste Krishna, I think your looking for something like Cody’s pushpin header technique.
Regards,
Brian
Hi Brian, yaa similar to cody’s technique. is it possible to implement the same in your script. if so, please tell me how can we implement.
Thanks, you have saved me a lot of work, a little donation is on the way.
@ Krishna: Hi Krishna, Cody’s technique is pure CSS so just use the CSS he provides. No alterations to the tablesort script should be required.
@ Alex: Hi Alex, glad you like the script.
Hi Brian
I’ve searched every where and can’t find your pay pal donate button, point me in the right direction please. ;-)
Al
@ Alex: Hi Alex, thanks for the donation my man, much appreciated. I’ve (re)integrated the paypal button above the comments. It must have got lost during the redesign…
Hi,
It is a nice, I am going to use one of my site. If you could add Filter feature then it will be greate..
cheras
NAS
Hello. I love this script. I have a question: what kind of sorting algorithm is used in this script? Is it the standard sort() or was a custom sorting algorithm defined? If a custom sorting algorithm is NOT used, how hard would it be for someone to implement one and would it be worth the time and effort? Its seems like there would be some custom sorts that could half the time of sort 100 tables from 43ms to 20ms.
Hi Brian,
Your script works perfectly for me with a small dataset, but with a large one it becomes sluggish. Is there any thing I can do to speed up load with the pagination on a large dataset?
@ Chris: Hi Chris, you should really attempt to read the article before commenting. Most of your questions would have been answered without having to post a comment at all.
Yes, the built-in native sort is used. It isn’t the actual “sort” that takes the time, it’s the DOM manipulation required in order to reinsert (and render) the rows that burns the clock cycles and, of course; I, nor yourself, have any control over the browsers internal DOM manipulation functionality. So, to recap, it’s impossible to write a sort function that would shave 20ms off of the time as, the 20ms in question is in fact, used to manipulate the DOM; not to sort the data.
@ Kyle: Hi Kyle, you could hack the script to only reinsert the row into the DOM if it falls within the current range of your pagination limits; this would invariably cut down on the DOM manipulation and therefore make the script faster.
What sort of “large” dataset are you talking about anyway? Perhaps an Ajax pagination script is more useful in your case.
What sort of “large” dataset are you talking about anyway?
————-Not really large, but large enough where is slows it down tremendously. It’s sports stats…approximately 2000+ records. I tried with more, but it took forever.
If I go with an AJAX pagination script will the rows only be sortable if the records are visible on the screen. I would still want all the records to sort. Any suggestions on an AJAX pagination script?
you could hack the script to only reinsert the row into the DOM if it falls within the current range of your pagination limits; this would invariably cut down on the DOM manipulation and therefore make the script faster.
———Has this been done before? If not, any ideas on where to start.
Thanks
I added the ability to indicate how the table was sorted when it is loaded. This is useful when you have already sorted a large table when the page was generate and you do not want to force a sort on load. If you want the changes I made, where do I send my updated .js file.
@ Kyle: Hi Kyle, you could try particle tree’s pagination script. but It still won’t sort properly on the client (as the JavaScript will require the entire table and not just a portion). Still, it’s probably a more robust solution for your scenario.
@ Brett: Hi Brett, I don’t understanf what you mean by “indicate how the table is sorted” but send the changes on anyway to brian at modernartcafe d0t net and I’ll work it out… thanks in advance.
any chance someone has a working demo that includes the zebra stripe and hover code? I can’t seem to get it to work (IE 6).
code freezes on incomplete cells.
eg. 5×5 table
row 5 collum 5 does not exist (everything else does, there’s just no code for those)
if you try to sort collum 5, the java will freeze
Hello there, great work!
My only question is regarding the pagination. Why are the buttons messed up?
They show vertically and not horizontally and most of them don’t show at all. Is there something wrong with the script, css?
Thanks a lot.
@ Chris: Hi Chris, a little more detail on the browser/version would be helpful, also, make sure you read the article for the pagination script.
If they are “messed up”, it’s certainly the CSS and nothing that can’t be rectified (in fact, I have already rectified an IE7 problem so you might like to try the demo again).
@ Dan: Hi Dan, the script expects a sane table. Tables with missing cells just won’t work.
The script does not work on Mac OS X and Safari 2. I can see the table but I cannot click on the headers to sort it. On firefox 2 (again on Mac) it works as expected.
@ Anonymous Surfer: Hi Anonymous Surfer, I’ve currently no access to Safari 2 (I’ve Safari 3 on Mac and Windows) so am currently unable to pinpoint the problem. If possible, can you tell me the error that gets thrown (if any)? Thanks in advance.
Well I go with Safari (MacOS X with all updates) to view the TableSort (revisited) demo 50 row table test. The table renders correctly.
I hover the mouse over the table header (e.g. movie, release date, weekly gross et.c.) and the mouse pointer tranforms into a hand to show that they are clickable.
I click and nothing happens. The arrows by each header are always switched off. There is no visual indication on Safari that something was wrong. There is no error message or dialog or something.
Anyway if it works on safari 3 which it out in some time, this won’t matter anymore. As for my own project I predict I will modify your javascript file extensively so I will find a solution one way or another.
Overall Great work! The killer feature of the script is that it allows sorting in multiple columns.
Thanks for your response on the sorting issue that I mentioned in a few posts back. For small table that are under 10,000 in row length. yes I agree this script is perfect for general users and not a problem at all. I am not stating to rewrite a browsers sorting capabilities, that would be silly. I am wondering if you could create a js algorithm that would accept data for sorting as apposed to using the standard built in sort(). ex’s- radix sort ,bucket sort, etc.. I do believe although not 100% certain that the sort function used is a bubble sort or something ridiculously slow and not effective for bigger lists. If I have a table with my music collect of say 23,000, the dom trick only goes so far when it would eventually become more feasible to shave off time from sorting. right. So Impossible == possible. Impossible is not a word in a programmers dictionary or at least not in mine. I have an algorithm that I have already create but sadly I don’t think that I have the time to implement it at this point. There are also other variables that may tie into whether or not this would be efficient. and perhaps the biggest disadvantage would be witting an algorithm as such in a surface level language with little to no flexibility. All are variables I simply lack the time to test at this moment. Keep up the great work. I commend your efforts for creating such an awesome script.
I cannot seem to get multi-column sort to work. If I hit shift and click a row header… it indicates that both are selected…but no additional sorting takes place.
I’ve tried this in FireFox and IE7
@ Kostis: Hi again, thanks for the further info. I’ll see if I can get my hands on Safari 2 in order to remedy the problem.
@ Chris: Hi Chris, I would be suprised if the algorithm used for the sort method is a plain old bubble sort (but stranger things have happened at sea my man). As I say, the DOM manipulation is the greatest waster of clock cycles, so, you could try to paginate the table and only work with the rows that would be shown – in fact, I’ll try to see if I can knock up a demo next week (i’m on holiday until then so shant be near a keyboard).
@ Carole: Hi Carole, without a link to the page in question I can’t really do anything for you!
Thanks for a great script!
I have a request similar to comment #243 about adding checkboxes to the script, i.e. when the table is sorted, checkboxes are reset. Is there a fix to this? How can I keep the checkboxes from defaulting to their original state?
@ Simon: Hi Simon, you will have to write sortInitiatedCallback and sortCompleteCallback callback functions. The sortInitiatedCallback should store a list of all of the checkbox “checked” properties, the sortCompleteCallback function will then use this list to reset the checkboxs to the required state.
Hope this helps,
Brian
P.S. This is necessary as Firefox has a bug when dealing with checkboxs that are removed and then readded to the DOM.
What a great script! I think this is the best table sorter lib I have ever seen.
Could you please tell me how to sort the following numbers in one column?
100,000
(200,000)
300,000
Here, (200,000)= -200,000
I think current script regards (200,000) as 200,000.
Thanks,
Michael
@ Michael: Hi Michael, you need to write a custom sort function… here’s something to try (warning, written into the comment box and so therefore untested):
Hope this helps,
Brian
Brian,
Thanks a lot for your solution.
I am also considering whether it is possible to add these two lines(ending with //New) in prepareTableData: function prepareTableData(table):
...
else if(th.className.search(/sortable-numeric|sortable-currency/) != -1) {
//To support negatives in () txt = txt.replace(/[\)]/g,’‘);//New txt = txt.replace(/[\(]/g,’-’);//New
txt = parseFloat(txt.replace(/[^0-9\.\-]/g,’‘)); if(isNaN(txt)) txt = “”; } ...After all, when a number in () appears with other numbers in one column, it will be regarded as negative in most cases. If data in one column are all in (), this will not influence the sorting, hmm…, except the arrow on table header :-)
Best regards,
Michael
Michael
@ Michael: Hi Michael, I can’t stop you from changing the code but I think a custom sort function is still the best (and most portable) bet. I’m curious as to why are your negative numbers wrapped in brackets? Is it a common notation?
First thing, thanks for the excellent script!
This is exactly what I was looking for. However, I also have the need to customize the columns. I was wondering if anyone has implemented, or knows of a way to hide/delete columns?
Thanks again for the awesome script!
Ryan
Brian,
I agree with you. After all, you are the owner of the smart scripts ~
Sometimes, people do not want to see negative numbers because it indicates loss:-( so they will wrap them in brackets.
Thanks,
Michael
Hi Brian
Your script works great, eth only one I found to work for my Ajax created table. However being a Ajax / JS newbie, I’m after slightly more of an example for the calling of the method fdTableSort.init.
I’m juts missing this and any hints would be greatly appreciated
Excellent script. I however used the script at http://www.frequency-decoder.com/2005/11/18/unobtrusive-table-sort-script
I have a question.
If I would like to disable the sort on just one of the columns and make it into a link instead, how would I do it? The link would be an internal link (pointing to the same page before any sorting). The reason I ask for such a link is, I have a column for date. However I do not know the exact dates for a few entries. I know just the month and year. Hence, though the date format for most entries is mm-dd-yyyy, for a few entries it is just mm-yyyy. The sort therefore is not accurate. Hence I thought of making the date variable into a link that loads the page the way I entered the data (before any kind of sorting) and disable sorting for the date variable. Any ideas on how to do that?
Thank you very much
Hi Brian,
Do you have a simple solution to highlight a row after selecting it? (e.g. onclick). I’m not talking about your hover-plugin, but something similar as the solution provided by Ajnasz at #81. I’ve tried to look at his solution, but since he uses an older version of tablesort I don’t know how to implement it in the latest tablsort script.
Also I’ve read at #192 (Jesse) that you sent him an example.
Maybe I can use that same example?
Thanks,
Nils
WOW, this is a great.
I keep running across one that is better than the previous.
I hope this is my last stop. I have to say, this is the cleanest looking one.
Thanks for sharing…
>>A penny for your thoughts…
Umm, now where’s my penny?
@ Ryan: Hi Ryan, sorry mate but I’ve no idea. Perhaps google can provide a more solid answer?
@ Phil: Hi Phil, imagine your AJAX’ed table has been rendered (i.e. exists within the DOM) and has ID of “myTable”, you just have to call fdTableSort.init(“myTable”).
@ Nivedita Krishna: Hi Nivedita, why don’t you just give this “date” column the calssName “sortable-keep”, this will keep it in the same state it was when the page was loaded.
@ Nils: Hi Nils, the two examples cited ended up being very projet specific. I’m currently overhauling the hover plugin to accept row selection etc. If your pressed for time, you can hassle me for the beta code at brian (at) modernartcafe (d0t) net.
@ Trey: Trey my man, pennies, like pints of Guinness are “virtual” round these parts… Glad you like the script!
Regards,
Brian
P.S. Comments off for a few days to avoid an automated spam attack on this specific post – the spamming bastards…
Ok first off, great script! Unfortunately I have run into a small problem…
I am writing quite a complex script involving multiple AJAX calls, and basically I am trying to sort by ascending order, but everytime more elements get added to the table I initiate a cache clear and a resort. The only way I can get it to sort in ascending is to actually call the sort twice:
fdTableSort.init(“rtable”);
fdTableSort.jsWrapper(“rtable”, [2]);
fdTableSort.jsWrapper(“rtable”, [2]);
So, picture a dynamically created table with mootools in javascript, and new elements getting added when a remote JSON call occurs and data gets retrieved. Id rather not call the sort function twice. But it seems once you call the init, the first time the sort is called its descending order. Is there no way to force ascending? It would be really good if the same function would only sort in one way no matter how many times you called it from JS, like maybe:
fdTableSort.jsWrapper(“rtable”, [2], “ascending”);
Hope you can give me a solution :) Keep up the great work
@ Jonathan: Hi Jonathan, why don’t you give the table the className sortable-onload-X-reverse (where “X” is the number of the column to sort) and then call the .init method with the table ID as an argument?
Regards,
Brian
Brian, believe me i’ve tried. Here is the code:
http://www.gettorrent.com/search/?top+games
Please take a look, you can see its perfectly sorted the wrong way on the seed column :( Its quite difficult code – any thoughts? you can see Ive commented out the second sort…
Brian,
You were right. I had put N by accident instead of the number. Was not concentrating :) I have however discovered a new problem!! It sorts correctly now with just using the init call and no tablesort functions at all, BUT if i switch from one ordered column to another, it automatically chooses to order that second column in the opposite direction to the first!!!!! Is there anyway of changing column order from one column to another but MAINTAINING ascending order? I think this might actually need more code…
Custom Sort? Hi, I noticed a problem recently with one of my columns of data. I have a number with one letter (a-z) (e.g., 12a or 12 or 9b or 9b). If I use the text sort it doesn’t sort correctly as numbers are not sorted properly once you get to 10. If you sort numeric, then the alpha character (if present) is not sorted properly.
Looking it over it appears I need to have a custom sort that accounts for numeric and alpha and was wondering if you or anyone had already written one or if you could point me in the right direction (am not quite the JS script wiz you are :-) )
THANKS
@ JB: Hi JB, the script sorts in ascending order by default. You need to do two sorts to get it to descend (the first to get it to ascend and the second simply reverses the results of the first).
Why is it such a problem if the script sorts in ascending order by default? Users can click on the TH again to sort it how they please anyway.
@ Paul: Hi Paul, yep, you require a custom sort but I just don’t have the time to write it for you. Sorry!
FD – its not such a problem, but when changing columns the user has to click twice :) not that ideal :) ANYWAY i have some news for you:
http://www.gettorrent.com/search/?ministry+of+sound
You might appreciate this as its an implementation of both your table sort + your pagination script linked to all sorts of code. JSON, HTMLSQL, XSSI, the works :) I do need your help though :(
Right now I am never sure exactly when to call the init functions of the sort + the pagination, and im not sure im doing it the fastest way. IE has a lot of problems. The issues i have are
1) when the table is populationg, the seed arrow jumps back and forth as if its flipping order – why?
2) how many times should i call the init function? every 100 rows? what about pagination? The rows are filled through a periodical.
3) The call back to pagination doesnt seem to work when you you populate a table like this so you have to keep calling inits all the time?
4) calling init every row makes the whole thing crash
5) with the current implementation, wait till the page loads, then try sorting by name, then back to seeds. you will see a few rows get stuck at the top and the bottom.
The project is suppose to be a real time torrent comparision engine, but I’ve hit a wall unless I can get this thing to go faster and be more reliable. – any advice? Ps can pay for your service if you don’t relish the technical challenge already!!! Best JB
@ JB: Hi JB, you should only call the init functions once; after all of the table rows have been downloaded and added to the DOM. As it’s a client-side sort/paginate solution, the scripts require the entire data set to be present before they can work properly.
Hope this helps,
Brian
Hello!
First I want to say that this is a great script! I used is for my dvd database, I like the pagination in the script but I want it only on the bottom of the table and not on the top, I’ve tried to get it done but didn’t work.
Can you help me with it?
Thank you!
Krijn
Hi Brian.
The first time I click a column the script makes forward sort.
I would like to make reverse sort instead. I mean, to get reverse sort I should click twice on a column, but I want to reverse the results the first time I click it.
This is because I have empty results, so the forward sort puts them on the begining of the table.
Is there a class to write in the TH node to do this ?
I already tried:
class=“sortable-text reverseSort”
class=“sortable-text-reverse”
class=“sortable-text reverse”
Thank you very much.
Marcelo
@ Krijn: Hi Krijn, you can just hide the top set of buttons using CSS i.e.
# your table id + -tablePaginater { display:none; }
@ Marcelo: Hi Marcelo, you will need to change the sort functions to return -1 instead of 1 and 1 instead of -1.
Regards,
Brian
Hi I have a table, that when created is storing a javascript array that has the row number and then the value of the 3rd column (it is an ID that relates to the rest of the data in that row).
This works out great, but when I added in the table sort this function – since it was not tied into the table sort stop recording correctly.
In researching your script I see that for an initial sort, if I modify the prepareTableData function and update MY array with rowCnt being the row value and identVal [ 2 ] being the value of the 3rd column in my table and place that in this function right after
/ Add the tr for this row
data[rowCnt][numberOfCols] = tr;
and before rowCnt++;
Everything works great. However, as soon as you then sort the table with any other sort or reverse sort this function is NOT called (at least that I can see) and therefore my array is not updated. I’ve been trying to determine exactly where in the tablesort.js these same values (what row it currently is and what is the data value for the third column) could be captured/found, but so far I am coming up empty.
Can you point in the right direction/function.
p.s. I found and adapted a solution to a custom sort of numeric and alpha characters in the same column. I tried to post it here for others (and for suggestions on improving) – but the code was a bit hard to read – suggestions for posting code (the “No HTML” strip didn’t seem to do the trick).
@ Paul: Hi Paul, the prepareTableData method is only ran once and shouldn’t really be fiddled with. Why don’t you create an after-sort callback function that reiterates over the (just sorted) table and stores the data that you require; for example:
// Make the storage variable global so other functions can use it var storage = []; // Create a callback function for the table MyTable function sortCompleteCallBackMyTable() { var rows = document.getElementById("MyTable").getElementsByTagName("thead")[0].getElementsByTagName("tr"); // Reset the storage variable storage = []; for(var i = 0, row; row = rows[i]; i++) { storage.push(row.getElementsByTagName("td")[2].nodeValue; }; };Hi,
Can anybody help me out making a custom sort function which sorts a (european) date including a (24) timestamp?
Like this: dd/mm/yyyy hh:mm:ss
(e.g. 31/12/2007 23:59:59)
I’ve been trying it myself, but it’s way above my league.
Thanks in advanced,
Nils
@ Nils: Hi Nils, this is very untested and typed into the comment box live so prepare to debug it a bit but this might just do:
Hi Brian,
Thanks for the quick response. At first I thought it was working correctly, but after small investigation it doesn’t.
As far as I can see, it looks at the last number in a part (e.g. dd, mm, yyyy, hh, mm or ss)
I’ve tested it with these records:
11/12/2007 12:01:01
11/12/2007 22:11:02
11/12/2007 13:11:02
11/12/2007 12:11:02
11/12/2007 12:02:01
11/12/2007 12:11:01
in this case 11/12/2007 13:11:02 is before 11/12/2007 22:11 when I descend the date/time.
Can you give it a look again?
Thanks,
Nils
@ Nils: Hi Nils, 13 is before 22 in the 24 hour clock… I’ve not really got the time to look into it further, sorry, but things are a little hectic here at the moment. Try to paste the sorted results for me to look at (both asc & desc). Thanks.
I just loved that it worked out of the box in a mootools enviroment. I’ve tried lots of tablesorters but not a single one has been working this good with mootools without some major code alterations. Especially when it comes with Ajax content. Did I say I love it? ;)
Hello to all. I need some help . For example i have TD with URL , but this URL can be too long , so my table will be long too , going through window ;) Is there any way to trim this url , for example , to 50 chars long , with this API ? or i should write custom js function ? Thanks . P.s. sorry for my bad eng
.Brian,
I sent you a sample of my testing results.
As I said in the email, only dive into it when you have time!!!
Nils
isn´t there any way to make editable fields?
like this: http://www.millstream.com.au/upload/code/tablekit/
Could you ask me throught mail? :P
Thank you.
hi, i’m using the following wordpress plugin for creating tables –
http://alexrabe.boelinger.com/wordpress-plugins/wp-table/
and it uses the sorting script mentioned here, which is INCORRECTLY sorting a table of percentage values, I am hoping someone here might know of a way to correct it?
Here is how it is sorting a series of over 270 values ranging from +100% to -100% –
in ascending order –
-1.00%
-10.00%
-100.00%
Update: I've removed over 260 unnecessary lines of output!
9.00%
93.00%
thanks in advance for any help you can offer!
ralph
I’ve noticed that when using the fdTableSort.init function, ↓ and ↑ characters are added to the th. Is there any way around this?
I’ve tried doing a colHeader.replace(String.fromCharCode(8595), “”) and other similar things to no avail.
@ Henrik: Hi Henrik, glad you like the script.
@ App: Hi App, this is a table sorting script and has nothing to do with the question you asked. Why don’t you try googling overflow:ellipsis or something?
@ Nils: Hi Nils, there is a gaping error in the reg Exp, I’ve emailed you a fixed version.
@ Tayson: No, there isn’t any way to make editable fields. Reading the article would have told you that.
@ Ralph: Try using “sortable-numeric” as the className on the associated TH node.
@ Tim: Hi Tim, there’s an entire section on this in the article. Please RTFM before posting comments.
Regards,
Brian
Hi,
brilliant script btw!
i was just wondering if it is possible to presort a table using the sortable-onload-N line to sort a table by two columns (the same way you would do it by pressing shift)??
thanks
Brian, thanks for the help but I must confess your suggestion was miles over my head, if you or anyone can dumb that explanation down for me I’d appreciate it, I am using a wordpress plugin so I don’t see where I could adjust the code for the table sort script, PLEASE HELP!
thanks :)
I also think that multiple columns for sortable-onload would be a sweet feature to see in the future.
Don’t need to rush it. After creating some TXP plugins myself I know the feeling of getting hunted down for updates on your code. :)
@ Ben & Henrik: Hi guys, I’m actually working on that at the moment. I’ll hopefully have it released early next week…
Thanks for the feedback,
Brian
Sorry, I was confused with the arrows because the usual arrows are placed in span tags, but when using the fdTableSort.init function the arrows are appended to the title. That’s all working now. Thanks.
Another issue though – in IE6, after running the fdTableSort.init function, clicking on a header will result in it (seemingly) keeping the sort-active class. This is not a problem in Firefox. Any ideas on how to get around this?
Fantastic script too by the way.
I have thrown together a demo page to describe what I’m talking about: http://tim.murphy.org/tablesort/tablesort.html . This shows the sort-active issue (IE only) and the extra arrows.
@ Tim: Hi Tim, you still have to add the class “no-arrow” to the table’s className if you don’t want the arrows! As for the “sort-active” class never being removed, download the latest version as I’ve changed the code that adds/removes classes to be more robust.
@ Ralph: Hi Ralph, first off, your site is coming up as having “spam content” and so all of your comments are hitting the moderation queue.
You should really be writing to the creator of the wordpress plug-in as it requires a change to his code, not mine.
Regards,
Brian.
Great script – a couple of feature requests:
1) Fixed Header option (like at http://www.imaputz.com/cssStuff/bulletVersion.html)
2) Pivot Table option (I know – it’s a biggie).
re: Why don’t you create an after-sort callback function that reiterates over the (just sorted) table and stores the data that you require; for example:
I think I understand what you mean – in terms of created a call back function that just iterates through the table and adds the data, but I have what I think is a simple question, but is stumping me.
I would think that calling this function would be best done right after your script completes any sort that is requested of it, but I can’t seem to determine where it is in the script this occurs (what function/area).
Suggestions for where to put that call to the call back function?
To solve the problem of needing to sort a field that had ALpha and Numeric characters mixed e.g., 17a, 4, 34b
I added the following customer sort to the customsort.js. However, I was not able to figure out how to create the function so ther was the function and a functionPrepareData supporting function. Any ideas or suggestions for improving this solution are most appreciated.
/* sortpage with Alpha —————— */
function sortAlphaNumeric(a, b){
// Get the innerText of the TD nodes var aa = a[fdTableSort.pos]; var bb = b[fdTableSort.pos];
var cnt= 0, ax, tem; var a= aa.toLowerCase(); var b= bb.toLowerCase();
var L= Math.min(a.length,b.length)+ 1; while(cnt< L && a.charAt(cnt)=== b.charAt(cnt) && x.test(b.substring(cnt))== false && x.test(a.substring(cnt))== false) cnt++; a= a.substring(cnt); b= b.substring(cnt); if(x.test(a) || x.test(b)){ if(x.test(a)== false)return (a)? 1: -1; else if(x.test(b)== false)return (b)? -1: 1; else{ tem= parseFloat(a)-parseFloat(b); if(tem!= 0) return tem; else tem= a.search(/[^\.\d]/); if(tem== -1) tem= b.search(/[^\.\d]/); a= a.substring(tem); b= b.substring(tem); } } if(a== b) return 0; else return (a >b)? 1: -1; }if(a== b) return 0; var x=/^(\.)?\d/;
@ Oskar: Hi Oskar, the fixed header code you mentioned is, apart from an IE hack, CSS based and can be integrated at will. As for the pivot table… I think I’ll leave that to MS XL!
@ Paul: Hi Paul, there’s a section “The callback functions” within the article that explains how to set them up. As for the code that got textpattern mangled, mail it to brian [at] modernartcafe (d0t) net and I’ll add it to the custom sort page.
Regards,
Brian.
Hi, I’m using the table sort and it works quite well. I’m pulling a lot of data and so far it’s handled it like a champ! One issue I’ve been having is when you sort the tables in FF the table border disappears after 2 sorts. Here’s an example:
http://elusiveform.com/GUILD/guild-info.xml
It’s an xml doc, uses and xsl to render it as html. Works exactly the same as a normal html, so I don’t think that’s the issue.
@ Brandon: Hi Brandon, it appears to be a bug in Firefox. Try changing the style rule for the TD tags, placing the border declarations above the font-style declaration (as Firebug is showing that all declarations after the font rule are being ignored).
Also, stop hotlinking to the script on my site please.
Regards,
Brian
re: Callback
Thanks for the hints- I got this to fire and work as a call back function, but I keep getting an error with the sample you provided.
at this line
storage.push(row.getElementsByTagName(“td”)[2].nodeValue);
(FYI there was a missing ) at the end and I added that. Any idea why this might be failing?
Here is the full code
The table id is designNotes
function sortCompleteCallbackdesignNotes() { var rows = document.getElementById(“designNotes”).getElementsByTagName(“thead”)[0].getElementsByTagName(“tr”); // Reset the storage variable storage = []; for(var i = 0, row; row = rows[i]; i++) { storage.push(row.getElementsByTagName(“td”)[2].nodeValue);
}; };Also – did you get my email with the alpha numeric sort script? Just wanted to make sure it went through.
Happy Holidays – thanks for your assistance.
@ Paul: Hi Paul, I’ve added the alphaNumeric sort to the custom sort page (but rewrote the code a little bit). I see I’ve referenced a thead and not a tbody in the script… you’ll have to change that.
Try:
storage.push(fdTableSort.getInnerText(row.getElementsByTagName(“td”)[2]));
Which uses one of the tableSort functions to grab the text instead.
...and have a happy Christmas!
Regards,
Brian
Hi Brian,
I know I am getting closer – but getting a new error with the mod – I am now getting an “illegal character” error on the new line.
Here is the full code updated
The table id is designNotes
function sortCompleteCallbackdesignNotes() { var rows = document.getElementById(“designNotes”).getElementsByTagName(“tbody”)[0].getElementsByTagName(“tr”);
CHANGED the above line to use tbody instead of thead as you mentioned (though same results either way)
// Reset the storage variable storage = []; for(var i = 0, row; row = rows[i]; i++) { storage.push(fdTableSort.getInnerText(row.getElementsByTagName(“td”)[2]));I TRIED ADDING .nodeValue after [2] – though I didn’t think that was right – both ways it did not work.
}; };Hope you had a great Christmas and will have a good new year.
FYI 2 things
1) I tried the updated alpha numeric script – works great
2) I noticed a minor typo in the script – the comment tag calls it the DutchCurrency instead of AlphaNumeric (looks like a copy paste thing)
Cheers
Thank you very much for the valuable script. However, I’m having a little problem with the following scenario. Your prompt help will be highly appreciated.
Scenario:
————-
The script works fine and the sorting shows up for the colums as detailed in the article. However, when I try to put the same code using AJAX, the sorting behavior is not initialized after the AJAX call for the same normal code ( the difference only it is coming from server-side at run-time).
Do the script has support for this? Is there a way out or solution available for this scenario?
@ Paul: Hi Paul, it looks as if you have copied and pasted the text directly from my comment without changing the quotes to be JS friendly (i.e. straight double quotes, not tilted double quotes).
@ Shaan: Hi Shann, I need a link to the page in question in order to help you. You should look at the code of the dynamic demo – it fakes an Ajax callback when creating a new table.
Hi Brian,
That was exactly it! It is always the little things. Thanks so much again for all your help – have a great New Years!
Thank you very for the reply. The link is as follows:
http://www.mzeeshan.com/shaan/sort/test_ajax.html
You can click the ‘Download Source Code’ Link to get the source code of all the files in use.
Looking forward for your reply.
Thanks,
@ Paul: Yeaaaahhhhh, good to hear it’s sorted…
@ Shaan: Hi Shaan, there’s so much wrong with that code I don’t know where to start (and I’m not trying to be haughty, believe me).
1. You have a table stuffed into a span element. Thats bad HTML karma.
2. You replace the original table with two script tags (one being another table sort script SortedTable.js and the other an Event.js file!) and one new table. Neither the new table, nor any of it’s TH nodes, have any of the required classNames e.g. sortable-text, sortable-numeric etc.
3. Even if the new table had the required classNames, you fail to call fdTableSort.init() to re-initiate the sort routine.
So, to recap… try to either use my sort script or the SortedTable.js script, not both; remove the table from it’s SPAN wrapper and, finally, remember to use the appropriate classNames and call the fdTablesort.init method after you create any new table…
Hope this helps,
Brian.
Firstly, excuse me, for not putting it alright. As in a hurry, I mixed the two. Thanks for pointing it out and certainly thanks again for not being haunty over it. ;). Your patience in this regard is highly appreciated.
Priase be to God, it worked perfectly, as you suggested. The fdTableSort.init() function after the request is completed in AJAX worked perfectly. Your a genius.
May God bless you. Thank you very much for the valuable tips.
Hi,
first of all – great script. I have one question though : since I come from Slovenia, where we use central european charachters (for instance c with a cirmcumflex which should be alphabeticaly sorted in between c and d), I was wondering how to fix my problem, since the script is sorting text according to english charachters. I looked at the sortText function but couldn’t think of a way to do it. Thanks for your answer.
@ Shaan: Hurray – you got it working…
@ Marko: Hi Marko, you need to write a bespoke sort function that can sort the Slovenian alphabet correctly. I can give you a pointer (I think!) which is, in true frequency decoder tradition, written straight into the comment box (and is bound to contain numerous syntax errors etc):
Again, it’s only a pointer (and you will also have to give the TH node the className “sortable-sortSlovenianText” in order to get the script to call the function) and, as it has no prepare data function, will be slower to use than a regular String.sort
Regards,
Brian.
Hello Brian,
thank you for a superfast reply, now everything works as a clockwork.
thanks again and keep up the good work
regards
Marko
Hi Brian,
Just want to wish you all the best for 2008!!!
And thanks again for all the help in the past.
Nils
It seems that sortable-onload-N changed in the new version. If I do a sortable-onload-3 it sorts after the fourth column. The columns probably starts on 0 in the Javascript and in the adding of multiple columnsupport you missed it. It can happen to anyone.
Other then that it’s still the best tablesorter! Keep up the good work!
(Oh, I haven’t tried multiple sorts on startup just yet. Just downloaded the source and immediatly noticed this new ehmm .. Let’s call it feature :).
I just have to add (sorry for the commentspamming :)
Reverse onload sort!
/me lays down on the pavement and dies a happy man
Now if I only could set that a column always starts the first sort as reverse I’d be in heaven!
@ Henrik: Hi Henrik, yeah, I broke compatibility between versions (which is naughty I know) but to my credit, I did say so in the article…
Glad you like the script. I’ll try to get your “reverse sort first time” thing into the next version.
Regards,
Brian.
Sorry for breaking the first rule of all: RTM.
All though to my defence the multiple sort example does state:
Should maybe be altered to read:
and so on.
And I can’t wait for a new version that includes reverse sort as a starting sort for a column.
Ooooh .. I have totally missed sortable-onload-show-N. Sweet!
bloody beautiful. Beautiful page as well! Thanks!
I would like to define 2 classes for zebra stripping the table rows, but
with the class rowstyle-something, I can only define each alternate table row and the other row stays white.
Is there a way, how I can make zebra stripping with 2 predefined classes ?
@ Henrik: Hi Henrik, I’ll change the article to reference the correct columns for the next update… thanks again.
@ Matt O: Hi Matt, glad you like the script.
@ Kulotti: The other row stays white as it inherits the background colour . You don’t need two distinct classes to create two colours. Here’s how to do it with just one class.
tr td { background-colour:red; };
tr.alternative td { background-colour:blue; };
Hi Brian,
Excellent script! Unfortunately, I’ve found some incompatibilities with Prototype. There is “no properties” error for .headers and fdTableSort.thNode in functions removeTmpCache and addThNode on page load. Can you suggest me something? The sorting works well.
@ Dmitry-Sh: Hi Dmitry, I can’t reproduce the problem using the latest prototype and scriptaculous releases. Can you give me access to the page in question?
Regards,
Brian
Hi Brian,
Nice work with the new version, as always though =)
But I’ve faced a weird problem with it:
zebra does not work on page load =( Before I switched to the new version, tables with no “sort-onload-” were colorized anyway, but now, they are plain till I first time sort the table, then the rows are recolored…
Now erros are shown/logged. Did I miss something and it should be initialized manually now?
Test URL:
http://files.myopera.com/PsychodelEKS/files/new.html
I have a table with a footer that I do not want to be included in the sorting. Basically, the footer should remain the last row in the table. Is there a way I could do that?
@ PsychodelEKS: Hi PsychodelEKS, I’ve reintegrated the onload zebra but only for tables that have been given the class “onload-zebra” (of course, if your table has an “onload-sort-X” or “onload-show-X” className defined then you don’t require the “onload-zebra”).
I’ll update the code this afternoon to V4.4…
Thanks for the heads-up, I can’t believe I missed that one…
@ Husain: Hi Husain, the demo table has a TFOOT that doesn’t get sorted.
I have a table that has two columns that use the same custom sort function. Call the columns “Created on” and “Last update”. The contents of the table cells are dates like “2008/Jan/01-12:12:34”. The custom function changes the date string into a number and then sorts numerically. The custom function is strongly based on sortEnglishLonghandDateFormat from customsort.js.
Here’s the problem. When I sort the first column (“Created on”), the column is properly sorted,both forward and reverse. When I sort the second column (“Last update”), the data used for the sort is the data from the first column.
I’m not an expert in JavaScript by any means, but when I look at the prepareTableData code, can it really handle more than one table column with custom sort functions?
BTW, this is a really great script. I have found uses for it on many pages.
@ John: Hi John, I’ve no problem using the same custom sort function multiple times. You must be referencing the same column during the prepareData phase. Send me a URL (or the code) and I’ll have a look. brian (at) modernartcafe [d0t] net
Regards,
Brian.
Brian — Thanks for the offer of help.
I found the problem. My prepare-data function was not removing all of the non-numeric characters properly and that of course caused sortNumeric to fail when called.
Hi,
Thanks for this script, it’s very useful.
I got a little problem with the “sortable-date” class. My “td” got datetime like this : “14/01/2007 à 09:00” and does not sortable… Any idea ?
hi ,
I am having a little problem with sortable-date class. I have a table containg month, success , redirect column . the page appear with month column sorted and when click on month head its do proper sorting . When i click on success , the success column get sorted .Now when i again click on month it does not get sorted . month column does not sorts after clicking any other column .
Hey,
Ive got the same problem as TylerD, in that i want to sort a date+time field, but it doesn’t seem to do anything when this field is clicked. All other field types work great. Any ideas would be most welcome.
Big fan of your work, Many thanks,
- Lee
I love this script but was recently notified that it’s not displayed in IE 7, in particular the pagination links:
http://www.newscaststudio.com/setstudio/
Any ideas?
Small problem/bug: How to add image inside th tag? it seems like tablesort.js is doing something to table header that makes images disappear?
TylerD and Lee—see my post #386. You need a custom sort function to change the date string to a number, and then sort numerically. On my pages the date is in the format “2008/Jan/01-12:12:34” so you may have to change the string around in the PrepareData function below.
Brian, feel free to add the code below to customsort.js if you see fit. As I said above, I am by no means a good JavaScript programmer (PHP is my preferred language of choice these days), so if there’s a better way to convert the month string to the appropriate integer value, go ahead and change the code. Its pretty obvious I used the sortEnglishLonghandDateFormat function as the basis of my code.
function sortStringDate(a, b) { return fdTableSort.sortNumeric(a, b);
}
function sortStringDatePrepareData(tdNode, innerText) { var str = innerText; var month_str = [‘Jan’,‘Feb’,‘Mar’,‘Apr’,‘May’,‘Jun’,‘Jul’,‘Aug’,‘Sep’,‘Oct’,‘Nov’,‘Dec’]; var month_num = [‘01’,‘02’,‘03’,‘04’,‘05’,‘06’,‘07’,‘08’,‘09’,‘10’,‘11’,‘12’];
// Replace the string with an integer equivalent for (var i = 0; i < 12; i++) { str = str.replace(month_str[i], month_num[i]); } str = str.replace(/\//g,”“).replace(/-/,”“).replace(/:/g,”“); return str; }@ John: Hi John, glad to hear you fixed the problem.
@ TylerD & Lee: Hi guys,
you need to write a custom sort function. See Johns comment (394) for assistance.I've written a custom sort function that may help you. Check out the sortEnglishDateTime function.@ Geeta: Hi Geeta, I can’t do much without a link to the page in question.
@ Michael: Hi Michael, it’s a CSS issue, probably because your not importing the IE only rules using conditional comments – the demo page works fine in IE7.
@ Keijo: Hi Keijo,
the script currently removes all children of the TH tag. You can change the code to get it to skip img tags within the init method. If you need help, email me at brian (at) modernartcafe [d0t] net.I've changed the script to leave IMG nodes alone. Download the new version (4.5)@ John: Hi John, thanks for the function. I’ll add a version to the custom sort page (which sorts date time) when I get a spare moment.
Update: Hi again John, I've added a sortEnglishDateTime function to the custom sort functions.
This is just brilliant – thx Brian. Unfortunately I don’t seem to be able to get images to show in the table headers, even with ver 4.5.
My code is quite simple:
<code><th class=“sortable-numeric simp”><img src=“pic/head.png” /></th></code>
The image shows until the javascript kicks in, at which point the image is gone.
stupidity alert!
note to self – make sure that change and updates have been saved and propagated fully before complaining that something doesn’t work
please ignore/delete my previous comment
Good afternoon! I made a quick demo with a single sortable-numeric column. I added the values 1, -4, 0, to the table and it doesn’t seem to sort correctly. Any help would be appreciated. I’ll try to upload the demo somewhere soon.
Thank you and great work!
What does it mean when the datagrid loads and then immediately unloads, or disappears after it’s rendered from clicking the “create” button?
I am using the javascript source code for tablesort.js and the code and the content from the demo with the calls for rendering time and such removed.
Amazing
@ kie: Hi kie, glad you got it to work.
@ Paul H: Hi Paul H, try to upload the demo as I’ll need to have a look at the page in question.
@ Jason: Hi Jason, your using the code from the page that tests dynamic table creation (i.e. that fakes an Ajax callback in which the table would be redrawn) – you should just look at the plain-vanilla demo
@ David Jacques-Louis: Thanks.
Thanks for this great piece of code! I’m sure you’ve noticed already, but I get three warnings when using it in Firefox 2:
anonymous function does not always return a value
Line: 344, Column: 10
Source Code: return;
anonymous function does not always return a value
Line: 354, Column: 1
Source Code: },
assignment to undeclared variable fdTableSort
Line: 30
Also, could you specify which encoding the file has? It’s almost properly decoded as ISO-8859-1 (one of the regExp_Currency characters is unrecognized).
@ Victor Engmark: Hi Victor, I can’t see the warnings in FireBug or in the error console (which is strange as they should be thrown). How are you managing to list them?
I’ll fix them for the next release.
F.Y.I: The file is UTF-8.
How would I allow for multiple column sorts without shifting. For instance, Lets say I have the following column types.
Name | date | time | amount of money | color
And when a user clicks on a header, it sorts THAT column but it also does a secondary and tertiary sort. Can I explicitly call that? For each header might have a different multi sort order.
For instance, when a user selects color, its sorts by color, but its secondary sort is ‘amount of money’ and the tertiary is ‘time’. When I sort by time, the secondary is “amount of money” and its tertiary is “name”.
Is this possible with the script. Basically, I want to take more control no what columns are sortable in multiple columns?
Please advise. Thank you.
@ James: Hi James, you could remove the onclick and onkeypress events (added by the tablesort script) from each of the links within the table headers and then add these events again but this time, get them to call a bespoke function that uses the jsWrapper method to sort the required columns.
I may be being dim again but I seem to be getting an error for tables that are using the sorting and pagination scripts.
When I try to sort a paginated table, I get the following error in firebug:
tablePaginater.redraw is not a function
initSort(undefined)processes.js (line 1332)
init(false)processes.js (line 905)
initEvt(load )processes.js (line 761)
[Break on this error] tablePaginater.redraw(fdTableSort.tableId, identical);
I’m sure the 2 scripts used to play together fine previously before I upgraded the table sort script to version 4.5 …..
ah I was being dim !!
I had only upgraded the table sort – I didn’t realise that the paginate script had also been upgraded
so for the record, TableSort revisited v4.5 plays nicely with paginate table object v1.6
This is the best tablesort I’ve found. Thank you very much! Do you know if it’s possible with your script to specify hidden or collapsed rows? I need to add accordion functionality to some tables and the few options available for sort+accordion fall way short of your script.
Thanks again!
@ Kie: Hi Kie, glad you managed to get things up and running…
@ Mike B: Just add the className “hiddenRow” to all rows (tr’s) you wish to hide. You will also have to add the appropriate style rule e.g.
tr.hiddenRow { display:none; visibility:hidden; }
Hi Brian,
Is there any way to combine 2 custom sort functions easily without rewriting a whole new custom sort?
I’v ran into this next issue: I want to display the values in a field, so I’ve changed your sortImage function to a sortField function like this:
// Returns the “input” attribute of the first input // “PrepareData” functions are passed both the TD node // and the TD node’s inner text. In this case, we use the // tdNode and not the inner text. function sortFieldPrepareData(tdNode, innerText) { var input = tdNode.getElementsByTagName(‘input’); return input.length ? input[ 0 ].value : “”; }
// Uses the data prepared in “sortImagePrepareData” function sortField(a, b) { // Get the data for the current column from the // two arrays passed in as arguments like so… var aa = a[fdTableSort.pos]; var bb = b[fdTableSort.pos]; // Sort the data if(aa == bb) return 0; if(aa < bb) return -1; return 1; }If the values are plain simple, it looks like it’s working. But I also want to sort on other custom functions (like sort sortDMYHM or sortDutchCurrencyValues). Now I cannot just add another c