jQuery tablesorter – sorting tables is easy

This is a continuation of the scrolling and toggling tutorial. Some of it’s content is discussed here, without much explanation.


We have now introduced sorting a table with the jQuery tablesorter plugin and scrolling the main window upwards to compensate for toggling a div off. In effect, when we toggle the visibility of a div on we scroll down to that div so it ends up slightly below the top of the screen. When we toggle it off we scroll back by the height of the div to get back to somewhere in the vicinity of where we were when the div was toggled on.

I still use dimensions, the behavior I got while using it was a little bit different from when I tried Ariel’s example in his comment to the prior article. Using just scrollTo and passing the element id to it will scroll the div to end up at the very top of the window. For some reason that doesn’t happen when using dimensions which will keep a gap, I have no idea why we get this discrepancy but I like that gap.

When a feed entry’s description has been toggled on we also change the background color of the table row containing the whole entry to keep track of which descriptions have been read. If I recall correctly I tried using addClass() but that didn’t work in conjunction with the table sorter. I ended up having to use removeClass() and then adding the style attribute instead since addClass() wouldn’t work. Here is the current state of toggleViz():

function toggleViz(el_id){
	var el_height = $("#"+el_id).height();
	$("#"+el_id).toggleClass("hidden_simple");
	var scroll_to = $("#"+el_id).position();
	if($("#"+el_id).attr("className") != "hidden_simple"){
		$.scrollTo(scroll_to.top, {speed:500});
		$("#tr-"+el_id).removeClass("feed_tr");
		$("#tr-"+el_id).attr({style: "background:#abd"});
	}else{
		scroll_to.top -= el_height;
		$.scrollTo(scroll_to.top, {speed:500});
	}
}

Let’s get to the point, the sorting. Below is the current template responsible for rendering the feed lists:

<script language="JavaScript" src="{$baseUrl}/js/jquery.js"></script>
<script language="JavaScript" src="{$baseUrl}/js/jquery.dimensions.js"></script>
<script language="JavaScript" src="{$baseUrl}/js/jquery.scrollTo.js"></script>
<script language="JavaScript" src="{$baseUrl}/js/tablesorter.js"></script>
<script language="JavaScript" src="{$baseUrl}/js/jquery_help.js"></script>
{literal}
<script language="JavaScript">
$(document).ready(function() {
	$("#good_list").tablesorter({ 
        headers: { 
            1: { 
                sorter: "integer" 
            }
        },
		widgets: ['zebra']
    });
	$("#trash_list").tablesorter({ 
        headers: { 
            1: { 
                sorter: "integer" 
            }
        },
		widgets: ['zebra']
    });
} 
); 
</script>
{/literal}
{include file="feed_sub_list.tpl" feeds=$feeds table_id="good_list"}
<br/>
<br/>
<b><a href="javascript:toggleViz('trashcan')" class="black_link">
Trash
</a></b>
<br/>
<br/>
<div id="trashcan">
{include file="feed_sub_list.tpl" feeds=$trash table_id="trash_list"}
</div>

Note that we pass sorter: “integer”, we need that for whole numbers so that the tablesorter can understand how to sort by that table column. In our case the second one. Since the default is “text” we would get the wrong behavior if we didn’t set the sorting explicitly. As you can see we pass widgets: [‘zebra’] to the constructor. That information has to be passed if you want to use zebra tables with the sorting which I want. It has to be combined with the proper CSS too:

.feed_tr td {
  background:#eee;
  margin:0px 0px 0px 0px;
  padding:0px 5px 0px 5px;
}

.feed_tr.odd td{
  background:#ddd;
}

And finally feed_sub_list.tpl:

<table id="{$table_id}">
<thead>
<tr id="sorting">
	<th>source</th>
	<th>tech rank</th>
	<th>date</th>
	<th>title</th>
	<th>category</th>
</tr>
<thead>
<tbody> 
{foreach from=$feeds item=feed}
<tr id="tr-{$feed.id}" class="feed_tr">
	<td name="title"><b>{$feed.feedname}</b></td>
	<td name="value">{$feed.value}</td>
	<td name="date" width="70px">{$feed.date}</td>
	<td name="description" width="600px">
		<a href="{$feed.link}" target="_blank" class="black_link">{$feed.title}</a> <a href="javascript:toggleViz('{$feed.id}')">more</a>
		<div id="{$feed.id}" class="hidden_simple">{$feed.description}</div>
	</td>
	<td name="category"><b>{$feed.category}</b></td>
</tr>
{/foreach}
<tbody> 
</table>

We need the <thead> <th> and <tbody> tags for the tablescroller to work. My prior solutions for sorting tables involved refreshing the page after using a PHP function to sort a two dimensional array stored in the session. That is very ugly compared to using Javascript to make use of the client CPU to do the work. Not to mention all that bandwidth saved. However, doing that in Javascript was/is beyond me so having discovered the jQuery tablesorter is a nice treat indeed.

Related Posts

Tags: , , , ,