Posted in jQuery, ColdFusion | Posted on 01-28-2010 | 7,550 views
For a while now I've been meaning to take a look at table sorting via jQuery. I finally got a chance to play with it last night and write up a quick demo. My example makes use of Tablesorter, a jQuery plugin that adds (wait for it) table sorting to existing tables. Check the plugin's web site for full documentation on options and demos. Here is a quick example of how easy this is to use.
I began with a simple ColdFusion query and table display:
2select artname, description, price, issold
3from art
4</cfquery>
5
6<table border="1">
7 <tr>
8 <th>Art</th>
9 <th>Description</th>
10 <th>Price</th>
11 <th>Sold</th>
12 </tr>
13 <cfoutput query="getArt">
14 <tr>
15 <td>#artname#</td>
16 <td>#description#</td>
17 <td>#dollarFormat(price)#</td>
18 <td><cfif issold>Yes<cfelse>No</cfif></td>
19 </tr>
20 </cfoutput>
21</table>
There isn't anything special here. I grab art records from the ColdFusion cfartgallery demo database and display the name, description, price, and sold properties. Now let's look at how easy it is to add in the sort.
First - you need to separate the header of the table from the rest of the data. This is done with the TBODY and THEAD tags.
2 <thead>
3 <tr>
4 <th>Art</th>
5 <th>Description</th>
6 <th>Price</th>
7 <th>Sold</th>
8 </tr>
9 </thead>
10 <tbody>
11 <cfoutput query="getArt">
12 <tr>
13 <td>#artname#</td>
14 <td>#description#</td>
15 <td>#dollarFormat(price)#</td>
16 <td><cfif isBoolean(issold) and issold>Yes<cfelse>No</cfif></td>
17 </tr>
18 </cfoutput>
19 </tbody>
20</table>
Also note I added an ID to the table. As you know, most jQuery operations will require you to name the items you want to manipulate. Ok, so next up I add in the JavaScript libraries:
2<script type="text/javascript" src="/jquery/jquery.tablesorter.min.js"></script>
Next - I enable the sorting:
2$(document).ready(function() {
3 $("#mydata").tablesorter();
4});
5</script>
And um - that's it! Considering that I normally have jQuery included already, I only needed to a) add tbody, theader, and an ID, b) include one more library, and c) write one line of JavaScript. Sweet.
As I said, you should check the web site for more details. One simple change you may want to make is an initial sort. That's as easy as:
You can add CSS to add pretty arrows to the headers, or keep it simple, as I did:
2th { cursor: pointer; }
3</style>
You can see a full demo of this here.


Nice to know. But, what if the data spans more than one view of the table? (ie. 100 rows showing 25 at a time). Will it sort all the data or just the visible data?
I've been using it for a while. Of course you have to load the whole recordset before the JS kicks in and paginates it, but it's not too slow unless you're also loading images for each record.
Perhaps there's a way to pull each page's content in using AJAX?
I noticed you're using the URL:
http://ajax.googleapis.com/ajax/libs/jquery/1/jque...
I actually don't recommend using this URL since it always loads the latest version of jQuery. While this may seem ideal, there are often compatibility issues that can crop up between revisions (especially changes like from 1.3.x to 1.4.x) and all the sudden code that was working yeterday, breaks for no apparent reason.
It's best to specify a specific revision, that way you can test your application/code with the newest revision before automatically updating.
Here's a link to my example, which contains a zip file you can download:
http://www.cfmzengarden.com/jQueryZenGarden/001/In...
You'll want to save a copy of this file:
C:\Program Files\Adobe\Adobe Dreamweaver CS4\configuration\Commands\ServerObjects\ColdFusion\DynamicTable_main.edml
Then copy over this bit of code:
<participant version="5.0">
<insertText location="afterSelection">
<![CDATA[
<table<@if (@@Border@@) @> border="@@Border@@"<@endif@><@if (@@CellPadding@@) @> cellpadding="@@CellPadding@@"<@endif@><@if (@@CellSpacing@@) @> cellspacing="@@CellSpacing@@"<@endif@>>
<thead>
<tr>
<@ loop (@@FieldLabelArray@@) @>
<th>@@FieldLabelArray@@</th>
<@ endloop @>
</tr>
</thead>
<tbody>
<cfoutput query="@@RecordsetName@@"<@ if (@@PageSize@@) @> startRow="#StartRow_@@RecordsetName@@#" maxRows="#MaxRows_@@RecordsetName@@#"<@endif@>>
<tr>
<@ loop (@@FieldNameArray@@) @>
<td>#@@RecordsetName@@.@@FieldNameArray@@#</td>
<@ endloop @>
</tr>
</cfoutput>
</tbody>
</table>
]]></insertText>
</participant>
Trust me, I've used jQuery since v1.1 and you really don't want to assume your code is always going to work with the latest and greatest code. In every point revision there have been another major changes that you absolutely need to test existing code before implementing in production.
While you might not run into an issue, as your usage of jQuery expands, then the more likely you'll run into compatibility issues. We utilize jQuery heavily in my day job, and I've had to make changes to code everytime jQuery has been updated to a new revision in order to get the code working 100%.
The worst thing that can happen to you is for an application just to stop working with no clue to why it's not working. By relying on a 3rd party to provide your application with code that at any time could change, it makes it very hard to find changes in behavior.
Image knowing that an app that's been working fine for years, all the sudden broke. You knew the code hasn't changed, the server hasn't changed, etc. How long is it going to take you to finally figure out that what has changed as the version of a library being loaded into the page. My guess is that's way down in the chain of what most people are going to look at.
I'm just pointing this out because in my own experience if I had relied on automatically using the latest build of jQuery, I would have seen several applications break without reason numerous times.
Also, one thing to keep in mind is that the jQuery UI has traditionally been tied very tightly to specific versions of jQuery. Most versions of the UI library only work with specific revisions of jQuery.
jqGrid w/efficient methods of SQL paging (http://blog.pengoworks.com/index.cfm/2008/6/10/Pag...) and CF make a great combo.
And once you have the current sort state, you should be able to preserve that in a cookie, then just look for the cookie on page load and if it exists use it to set the initial sort.
[Add Comment] [Subscribe to Comments]