With a reasonably-sized record set, client-side table sorting is a nice option. But if there are too many records, browsers might buckle under the strain. In those cases, let the server do the work and sort with AJAX.
As with the previous recipe that dealt with AJAX, we won't delve into the server-side code. I trust that you've got your favorite server-side language and database, and know how to set them up.
The initial setup for this chapter is exactly the same as it was for the previous recipe. Stick with the table of top movies. Assume a database table with columns Ranking, Movie, and Release Year.
As usual, create a table with a unique ID. As with the previous recipe, clicking the column headings will sort, but this time it's going to be a server-side sort. To simplify the server-side code, give each column ID values that correspond with the database column name. Continue to use
class="sorter"
for all of the headings.<table border="1" id="movies"> <thead> <tr> <th> <a href="#" class="sorter" id="ranking">Ranking</a> </th> <th> <a href="#" class="sorter" id="movie">Movie</a> </th> <th> <a href="#" class="sorter" id="releaseYear">Release Year</a> </th> </tr> </thead>
The
tbody
will contain all 15 movie rows, the same as in the previous recipe.The script will be notably different, since we're now going out to the server to retrieve the sorted records.
<script type="text/javascript"> $( document ).ready( function() { $( "a.sorter" ).click( function( e ) { e.preventDefault(); $( "#movies tbody tr" ).remove(); $.ajax({ type: "POST", url: "_sort.php", data: { orderby: $( this ).attr( "id" ) }, dataType: "json" }).done( function( data ) { $.each( data, function( index, val ) { var tablerow = "<tr><td>" + val[ 0 ] + "</td><td>" + val[ 1 ] + "</td><td>" + val[ 2 ] + "</td></tr>"; $( "#movies tbody" ).append( tablerow ); }); }); }); }); </script>
Since there's absolutely nothing new about the table or markup, let's jump right into the script. Much of this should be just review, as there's nothing in this script that hasn't already been covered. Trigger the sort when a link with class sorter is clicked.
$( "a.sorter" ).click( function( e ) {
As you know by now, prevent the default behavior so that the browser doesn't try to follow the link and/or reload the page.
Jumping right into the $.ajax()
call. You've done an AJAX post before, where you sent startAt
and pageSize
as data. In this recipe, send a variable called orderby
, which is the value of the id
attribute of each of the links in the column headers. This is accessible via $( this ).attr( "id" )
.
The .done()
method that's baked into jQuery's $.ajax()
is also something that has already been used. In fact, the entire body of the .done()
method is identical here to the body of the .done()
method in the Pagination – server side (Should know) recipe. Use jQuery's built-in $.each()
iterator to loop over the results. With each iteration of the loop, construct a table row, and use .append()
to append it to the tbody
of the table.
The only real difference between the AJAX call in the Pagination – server side (Should know) recipe and the AJAX call here is what happens on the server. In the Pagination – server side (Should know) recipe, a specific subset of records was retrieved, which I did via mySQL's LIMIT
directive.
For sorting, we're merely doing an ORDER BY
in the SQL. The value of the ORDER BY
is the value that passed as data in the $.ajax()
call.
This should be pretty consistent among most databases.
For my setup using PHP and mySQL, the relevant code from _sort.php
is as follows:
$orderby = $_POST[ "orderby" ]; $result = mysql_query( "SELECT `ranking`,`movie`,`releaseYear` FROM `movies` ORDER BY $orderby" ); $data = array(); while ( $row = mysql_fetch_row( $result ) ) { $data[] = $row; } echo json_encode($data);
As in the previous recipe, this sort only sorts in one direction. It should be a little bit easier to modify this one to be able to reverse the sort if a specific column head is clicked on twice. You'll still need to store a variable locally in order to know which column is sorted and in which direction, but there will be no need to modify the sort algorithm. There is none! Simply pass an "ASC" or "DESC" as part of the data to the $.ajax()
call. It might look something similar to the following:
$.ajax({ type: "POST", url: "_sort.php", data: { orderby: $( this ).attr( "id" ), direction: "ASC" }, dataType: "json" })
A small modification to the server-side code to sort the ORDER BY
in a particular direction is the only change needed.