Animated table sort (REGEXP friendly)
Note: this script is currently unsupported. You are free to use it, but, due to its complexity, there are some bugs. Some people report it working fine, others (with large tables, especially), have issues.
Overview
This plugin allows you to animatedly sort a table based on a column's <td>s, or on the content/value of a child/descendant element within those <td>s. The various <td>s fly to their new homes, giving a nice effect. It also supports sorting on REGEXP matches. You can also control whether row relationships are maintained, whether it sorts on ascii or numeric and ascending or descending.
Usage & parameters
Call tableSort(params) on a table returned by a jQuery selector.
$(selector).tableSort(params);
...where params is an object of property/value pairings, including:
onCol (int, required) - the index of the column in your table to sort on (not zero-indexed)
keepRelationships (bool, default: false) - if true, row relationships wil be maintained. That is, the sibling <td>s will move also
regexp (RegExp, default: null) - a string representing a regular expression (/pattern/) to sort on instead of the complete contents of the <td>. Useful with regexpIndex - see below.
regexpIndex (int, default: 0) - if sorting on a regular expression, this is the index of the returned array of matches to use for the sort, should it return more than one match. See below for an example of this, where a regexp sub-pattern is used.
child (string) - sort on the content/value of a child/descendant element within each <td>, rather than on the <td>s themselves. This should be a selector string to match that element. See notes for more info.
sortType (string, default: ascii) - either 'ascii' or, if wanting to sort numerically, 'numeric'
sortDesc (bool, default: false) - if true, the sort will be done in descending order, not ascending
Example 1
Click the column headings to sort the table based on that column
| Place | County | Phone code | Approx. population |
|---|---|---|---|
| Nottingham | Nottinghamshire | 0115 | 292400 |
| Luton | Bedfordshire | 01582 | 203800 |
| Huddersfield | Yorkshire | 01484 | 146234 |
| Carlisle | Cumbria | 01228 | 103700 |
| Brighton | East Sussex | 01273 | 155919 |
| Woking | Surrey | 01483 | 62796 |
| Basingstoke | Hampshire | 01256 | 82913 |
| Rhyll | Clwyd | 01745 | 24889 |
Here's the code applied to the links in the <th>s:
1//column 1 - by place name
2$('#example1_table').sortTable({
3 onCol: 1,
4 keepRelationships: true
5});
6//column 2 - by county
7$('#example1_table').sortTable({
8 onCol: 2,
9 keepRelationships: true
10});
11//column 3 - by phone code
12$('#example1_table').sortTable({
13 onCol: 3,
14 keepRelationships: true,
15 sortType: 'numeric'
16});
17//column 4 - by approx. population
18$('#example1_table').sortTable({
19 onCol: 4,
20 keepRelationships: true,
21 sortType: 'numeric'
22});
Example 2 - REGEXP
To illustrate better how the regular expression parameters can be useful, consider the following example.
| Product category |
|---|
| Playstation 3 games (164) |
| XBox 360 games (94) |
| Nintendo Wii games (142) |
| Nintendo DS games (89) |
| PC games (221) |
| Apple Mac games (18) |
This simple table shows a number of product categories and, for each, the number of products in each one.
Here, we want to sort on the number of products, not on the whole contents of each <td>. Stipulating this in a suitable regular expression string passed in the regexp parameter allows this.
Click the link in the <th> to see the demo.
Here's the code behind this example:
1$('#example1_table').sortTable({
2 onCol: 1,
3 sortType: 'numeric',
4 sortDesc: true,
5 regexp: /\((\d+)\)/, //match just the number of products
6 regexpIndex: 1, //sort on just the number, not brackets too
7 keepRelationships: true
8});
Note we specify regexpIndex as 1 because we our regexp pattern returns an array of matches containing two elements, and we want to sort on the number in isolation, i.e. the sub-pattern, not on the surrounding brackets as well.
If this is Greek to you, click here for more information on Javascript regular expressions.
Notes
DOM
Since <td>s are very fixed elements and aren't animatable, the animation is done by some DOM-scripted <div>s, which animate to their new homes then repopulate their new <td> homes.
These complimentary elements are removed once the animation is complete, leaving you with a legitimate table, each of the <td>s of which genuinely contain the content they appear to. This means you can perform further traversal or manipulation on the table without issue.
UPDATE - 17/07/2010: sort on child element
Following a request, you can now sort on the content/value of a child/descendant element within each <td> by passing a selector string to match that element in a new parameter, child.
So for example, if the <td>s in column one each contained a text field, and you wanted to sort the table on the current values in those fields, you could run the following:
1$('#example1_table').sortTable({
2 onCol: 1,
3 keepRelationships: true,
4 child: 'input'
5});
Important: ensure child matches only one element in each <td>, or the sort will fail. So in the above example, if each <td> contained more than one <input>, the script would be break. To avoid this, be more specific, e.g.
1child: 'input:first-child'
2//or
3child: '#myField'
4//etc
Comments (97)
Alex, at 17/09/'10 23:13, said:
Frank, at 20/09/'10 11:38, said:
Mitya, at 20/09/'10 12:30, said:
Frank, at 22/09/'10 12:12, said:
Mitya, at 22/09/'10 15:09, said:
This can be achieved by appending the following line to the 'PREP' section in the code: $(this).get(0).tableSortParams = params; You can then interrogate any of the currently effective parameters (see above on this page) for the given table with something like: <a href="javascript:alert(document.getElementById('example1_table').tableSortParams.sortType);">alert</a>Frank, at 24/09/'10 06:48, said:
Mitya, at 24/09/'10 09:55, said:
Frank, at 24/09/'10 11:46, said:
Nick, at 29/09/'10 10:58, said:
Mitya, at 29/09/'10 11:05, said:
Divyesh , at 29/09/'10 20:14, said:
Agence Index Web Marketing - Montreal, at 2/10/'10 07:42, said:
Jonathan, at 13/10/'10 04:26, said:
Jonathan, at 13/10/'10 04:26, said:
Jonathan, at 13/10/'10 06:34, said:
Henrik, at 18/10/'10 08:10, said:
Mitya, at 18/10/'10 10:18, said:
mike johnson, at 26/10/'10 00:31, said:
Dilip Nikam, at 28/10/'10 05:58, said:
Mitya, at 31/10/'10 15:21, said:
Mike Johnson, at 1/11/'10 13:24, said:
Mitya, at 1/11/'10 13:43, said:
Frank, at 9/11/'10 09:31, said:
Frank, at 17/11/'10 07:19, said:
Saul, at 17/11/'10 16:37, said:
@Frank - This is how I did it. Replace the 'Sort Values Array' portion of the code with the following : if (params.sortType == 'numeric') { valuesToSort.sort( function(a, b) { a.replace(/[^\d\.]/g, ''); b.replace(/[^\d\.]/g, ''); return a - b; }); } else { valuesToSort.sort(); } if (params.sortDesc) { valuesToSort.reverse(); } var thisTD = $(this).find('th a:eq(' + (params.onCol - 1) + ')'); if ( thisTD.hasClass('tableSort_toggled')) { valuesToSort.reverse(); } thisTD.toggleClass('tableSort_toggled'); Cleans it up a little and gets the job done. Thanks, Mitya!Frank, at 18/11/'10 07:10, said:
Mitya, at 18/11/'10 22:25, said:
Merdan, at 23/11/'10 12:26, said:
Mitya, at 23/11/'10 13:26, said:
dr john, at 30/11/'10 10:22, said:
Mitya, at 30/11/'10 10:29, said:
anna, at 1/12/'10 12:21, said:
mitya, at 1/12/'10 12:30, said:
FRED, at 5/12/'10 03:35, said:
ej, at 6/12/'10 01:50, said:
sarathkrishna, at 6/12/'10 18:57, said:
Abram, at 21/12/'10 22:53, said:
battery, at 22/12/'10 05:40, said:
John_www, at 4/01/'11 18:48, said:
Rob, at 5/01/'11 11:39, said:
Daniel Hölbling, at 10/01/'11 11:42, said:
digital camera battery, at 24/01/'11 08:03, said:
Raghib Suleman, at 10/03/'11 05:02, said:
Freddy, at 11/03/'11 10:28, said:
RAT, at 2/05/'11 04:07, said:
Peter, at 14/05/'11 18:18, said:
Awesome, I love your script. The thing is, I'm used to TableKit, but that one is Prototype based. So I wanted a way to create the sort links in the table headers automatically, like TableKit works by adding the "sortable" class to the table. So here's a small piece of jQuery that adds an ID to all tables that have a "sortable" class, and automatically adds the links to the table headers for sorting. Enjoy! $(window).ready(function() { $(".sortable").each(function(tableIndex,table) { $(table).attr("id","sortable_table_"+tableIndex); $(table).find("th").each(function(thIndex,th) { $(th).html("<a href=\"javascript:$('#"+"sortable_table_"+tableIndex+"').sortTable({onCol:"+(thIndex+1)+",keepRelationships:true});\">"+$(this).html()+"</a>"); }); }); });Peter, at 14/05/'11 18:31, said:
Also, in addition to Saul (17/11/'10 16:37), to display images which indicate the direction of the sorting, use this piece of code for the "Sort values array" part; if (params.sortType == 'numeric') { valuesToSort.sort( function(a, b) { a.replace(/[^\d\.]/g, ''); b.replace(/[^\d\.]/g, ''); return a - b; }); } else { valuesToSort.sort(); } if (params.sortDesc) { valuesToSort.reverse(); } var thisTD = $(this).find('th a:eq(' + (params.onCol - 1) + ')'); if ( thisTD.hasClass('tableSort_toggled')) { valuesToSort.reverse(); thisTD.addClass('desc'); thisTD.removeClass('asc'); } else { thisTD.addClass('asc'); thisTD.removeClass('desc'); } thisTD.toggleClass('tableSort_toggled'); This adds a desc or asc class to the th. You can define your own pictures, or add jQuery UI (it has built in images & css for tables, including these arrows). Cheers!abdeljalil, at 23/05/'11 23:17, said:
air max 90, at 10/07/'11 16:08, said:
Lawyer Townsville, at 12/07/'11 13:53, said:
Debbie Austin, at 12/07/'11 14:02, said:
Sam Summer, at 13/07/'11 02:19, said:
Jon Long, at 15/07/'11 00:54, said:
I needed to execute a piece of code right after the sorting had finished, so I modified this plugin to include a callback that lets you know when it's done. Just remove the "jQuery.fn.tableSort_cleanUp" function, and replace this line: if (done == valuesToSort.length-1) thiss.tableSort_cleanUp(); with this: if (done == valuesToSort.length-1){ thiss.find('td').each(function() { if($(this).get(0).toTD) $($(this).get(0).toTD).get(0).newHTML = $(this).children('div').html(); }); thiss.find('td').each(function() { $(this).html($(this).get(0).newHTML); }); $('td.tableSort_TDRepopulated').removeClass('tableSort_TDRepopulated'); thiss.find('.sortOnThisCol').removeClass('sortOnThisCol'); thiss.find('td[newHTML]').attr('newHTML', ''); thiss.find('td[toTD]').attr('toTD', ''); if (typeof callback == 'function') { // make sure the callback is a function callback.call(this); // brings the scope to the callback } } Let me know if you ever put it up on GitHub and I'll gladly contribute :) Thanks again for this awesome plugin!Mitya, at 15/07/'11 10:45, said:
nike dunks, at 16/07/'11 02:54, said:
cute handbags, at 17/07/'11 05:06, said:
Roy, at 17/07/'11 05:09, said:
pennsylvania, at 17/07/'11 17:09, said:
abi, at 26/07/'11 11:54, said:
Dhiraj, at 26/07/'11 14:58, said:
Dhiraj Chawla, at 26/07/'11 14:59, said:
Fake Oakley Sunglasses, at 29/07/'11 15:12, said:
Fake Oakley Sunglasses, at 29/07/'11 15:14, said:
JP, at 3/08/'11 00:13, said:
JP, at 5/08/'11 20:37, said:
uwedding, at 10/08/'11 04:06, said:
software qa, at 10/08/'11 11:15, said:
Kenny, at 11/08/'11 23:55, said:
raybansunglasses, at 18/08/'11 02:46, said:
cartier love outlet, at 9/09/'11 07:45, said:
wanghui, at 20/09/'11 09:41, said:
3Nex, at 19/10/'11 20:40, said:
Mitya, at 20/10/'11 09:58, said:
New Era hats, at 1/11/'11 16:03, said:
Ban Terbaik GT Radial, at 3/11/'11 03:34, said:
wholesale new era hats, at 8/11/'11 03:52, said:
Goyal, at 20/12/'11 09:07, said:
Goyal, at 20/12/'11 19:03, said:
Ashik, at 16/01/'12 14:46, said:
i have a table to sort, eg: <table> <tr><td> <div class="c1">10</div> <div class="c2">5</div> </td></tr> <tr><td> <div class="c1">10</div> <div class="c2">6</div> </td></tr> </table> Here i need to do the multiple div values sorting, ie here second row must moved to first position , how can i solve this with jquery animated script. Thanks for your support ---------Not Working below script---- $('#table').sortTable({onCol: 1, keepRelationships: true, sortType: 'numeric',sortDesc: true,child: '.c1 .c2'});Warren, at 14/02/'12 17:11, said:
Warren, at 14/02/'12 18:29, said:
Mitya, at 14/02/'12 18:43, said:
Snapback Hats, at 10/04/'12 02:45, said:
alifellod, at 24/05/'12 04:32, said:
Fabien Rigaux, at 11/06/'12 14:46, said:
The same script with two more optional parameters : - animationDuration : TD animate duration in milliseconds - callback : function to call after sortTable has been done Example : -------------- <script type="text/javascript"> function nextSort() { $('#promoTab').sortTable({onCol: 4, keepRelationships: true, sortDesc: true, animationDuration: 100}); } $(document).ready(function(){ $('#promoTab').sortTable({onCol: 1, keepRelationships: true, sortDesc: false, animationDuration: 100, callback: nextSort}); }); </script> "Plugin modifications" : --------------------------- jQuery.fn.sortTable = function(params) { ... animateOn.children('div').animate({top: moveBy_top}, !params.noAnim ? params.animationDuration : 0, null, function() { if ($(this).parent().is('.sortOnThisCol') || !params.keepRelationships) { done++; if (done == valuesToSort.length-1) thiss.tableSort_cleanUp(params.callback); } }); } }; jQuery.fn.tableSort_cleanUp = function(callback) { ... if (typeof(callback) != 'undefined') { callback(); } };james, at 13/06/'12 11:12, said:
anne, at 13/06/'12 11:15, said:
TISA Snapbacks, at 9/07/'12 12:22, said:
Objet publicitaire, at 25/10/'12 04:21, said:
KevinChan, at 15/01/'13 04:18, said:
leo, at 16/01/'13 08:27, said:
Latsassessy, at 14/05/'13 02:56, said:
Latsassessy, at 14/05/'13 02:56, said:
Dyexadveway, at 15/05/'13 07:05, said:
Dyexadveway, at 15/05/'13 07:05, said:
Dyexadveway, at 15/05/'13 07:05, said:
Dyexadveway, at 15/05/'13 17:14, said: