Chris Nizzardini, Salt Lake City Utah, Web Developer Specializing in LAMP+Ajax Since 2006

My Blog

Here is my awesome blog.

MooTools Table Sorter 0.9.5 – For Sorting MySQL Data via XHR…and looking good doing it.

Well its been a long weekend and I’m starting to wrap it up. But I couldn’t go to bed without redoing the documentation for my baby the MooTools TableSorter and updating the demo page. The documentation will loosely follow what you see in the demo page.

HTML Setup

You’ll need to include 3 files: MooTools 1.2 or higher, the CSS file, and the Table Sorter javascript class. You’ll also want to make sure all the images are there and update the CSS image paths to jive with the location on your web server.

1
2
3
	<link rel="stylesheet" media="screen" href="/mootools/table-sorter/table-sorter.css" />
	<script type="text/javascript" src="/js/mootools1-2.js"></script>
	<script type="text/javascript" src="/mootools/table-sorter/table-sorter.js"></script>

PHP Setup

You’ll want to use the TableSorter php class I included to make things easy one you.

1
	include_once 'TableSorter.class.php';

Server Side First

Notice setting the table headers is important. For instance when a user clicks on city the TableSorter will send the ORDER BY stored in the TH Title. This is how your server side code will know what to order by. Reply to this post if you have any questions on the server-side PHP code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
	function returnGeoHtmlTableStr($whereClause='',$startingFromRecord=0,$rowsPerPage=100,$orderBy='city ASC')
	{
		mysql_connect('localhost','user','password','database');
		mysql_select_db('database');
 
		$startingFromRecord = (int) $startingFromRecord;
		$rowsPerPage = (int) $rowsPerPage;
 
		$sql = "SELECT 
					count(*) as count 
				FROM 
					cnizz_geo 
 
				$whereClause
 
				";
		$result = mysql_query($sql);
		$countArr = mysql_fetch_assoc($result);
		$totalRows = $countArr['count'];
 
		if($orderBy==''){
			$orderBy='city ASC';
		}
 
		$sql = "SELECT SQL_CALC_FOUND_ROWS
					* 
				FROM 
					cnizz_geo 
 
				$whereClause
 
				ORDER BY 
					$orderBy
				LIMIT 
					$startingFromRecord,$rowsPerPage
				";
		$result = mysql_query($sql);
		$arr = array();
		while($row=mysql_fetch_assoc($result)){
			$arr[]=$row;
		}
 
		$sql = "SELECT FOUND_ROWS() as totalRows";
		$result = mysql_query($sql);
		$foundArr=mysql_fetch_assoc($result);
 
		$str = '
			<table class="DefaultTable" style="width:500px;">
			'.TableSorter::returnMetaStr($startingFromRecord,$rowsPerPage,$foundArr['totalRows'],count($arr),$orderBy).'
			<tr style="background:#FFF;"><td colspan="10" style="height:5px;">&nbsp;</td></tr>
			<tr id="GeoHead" class="DefaultTableHeader">
				<th id="City" title="'.(($orderBy=='city ASC')?'city DESC':'city ASC').'">City</th>
				<th id="State" title="'.(($orderBy=='state ASC')?'state DESC':'state ASC').'">State</th>
				<th id="Abbrev" title="'.(($orderBy=='state_abbrev ASC')?'state_abbrev DESC':'state_abbrev ASC').'">State</th>
				<th id="County" title="'.(($orderBy=='county ASC')?'county DESC':'county ASC').'">County</th>
			</tr>
			';
		$x=1;
 
		foreach($arr as $i)
		{
			if($x%2){
				$class='';
			}
			else{
				$class='zebra';
			}
			$str.= '<tr class="'.$class.'">
								<td><a id="'.$i['city'].'" title="'.stripslashes($i['city_id']).'">'.stripslashes($i['city']).'</a></td>
								<td>'.$i['state'].'</td>
								<td>'.$i['state_abbrev'].'</td>
								<td>'.$i['county'].'</td>
							</tr>';
			$x++;
		}
 
		$str.= '<tr style="background:#FFF;"><td colspan="10" style="height:5px;">&nbsp;</td></tr>';
		$str.=$meta.'</table>';
		return $str;
	}

Your Server Side Controller

1
2
3
if($_GET['action']=='returnGeoHtmlTableStr'){
	die(returnGeoHtmlTableStr('',$_GET['start'],$_GET['rows'],$_GET['orderBy']));
}

Now the JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
	window.addEvent('domready',function(){
		sorter = new TableSorter({
			request: 'action', 
			action: 'returnGeoHtmlTableStr', 
			destination: 'XhrDump', 
			prev: 'PagePrev', 
			next: 'PageNext', 
			head: 'GeoHead',
			rows: 100,
			startWait: "",
			endWait: ""
		});
	})

Lets explain this line by line.

  1. request: ‘action’, This is how you name the GET parameter. So in this instance the GET looks like $_GET['action']
  2. action: ‘returnGeoHtmlTableStr’, This is the value of GET parameter defined in step 1, so $_GET['action'] = ‘returnGeoHtmlTableStr’
  3. destination: ‘XhrDump’, This is the element id where TableSorter will write results too
  4. prev: ‘PagePrev’, This is the element that the class will listen on for Previous Page requests.
  5. next: ‘PageNext’, Same as above except it goes to the next page when this element is clicked
  6. head: ‘GeoHead’, This tells the class where to look for all those TH tags, which it uses to do sorts on if a Title is defined on the TH tag.
  7. rows: 100, How many rows should the request return.
  8. page: location.href, Where to send the GET request
  9. method: ‘get’, The type of method (GET or POST). By default the method is get, but you can change it to post.

Other cool stuff you can do

You can add additional parameters to the GET request in the form of parameter name => parameter value.

1
sorter.addParameter('zipcode','84101');

You can remove these user-defined parameters by calling removeAllParameters.

1
sorter.removeAllParameters();

You can remove a specific parameter by calling removeParameter.

1
sorter.removeParameter('zipcode');

You can initiate a sort anytime you want by calling sort.

1
sorter.sort();

At the moment this is all it does. There are some known issues in IE where the up/down arrows will not appear on sorts. Also the visual-effects are a bit degraded in IE as well. However it does work in IE and all other major browsers. I have windows-only clients using this right now, as well as FireFox and Safari only clients using it. I’ll be releasing a new version later this Summer based on bug fixes to production installs and feature enhancements I have running in the wild. Please reply to this blog post with any comments, bugs, or questions. Enjoy.

Tags: ,

Leave a Reply