Sorting HTML Data Tables Part 2: Dynamically Sort in Ascending and Descending Order

In last week's post we looked at dynamically sorting HTML data tables. But we only talked about sorting the columns in either ascending or descending. If the user is looking for a last name that appears near the end of the alphabet and the column is sorted from A to Z, they may have a lot of names to go through before finding the one they want. Instead we could provide an option for sorting in both descending and ascending order.

Background

So let's take final code from last week:

<?php
//IF THE FLAG HASN'T BEEN SET YET, SET THE DEFAULT
if(!isset($_GET['orderBy'])) {
     $_GET['orderBy'] = 'date_desc';
}
 
//FIGURE OUT HOW TO SORT THE TABLE
switch($_GET['orderBy']) {
     case 'first_name':
     case 'last_name':
          $sql_orderBy = $_GET['orderBy'];
          break;
 
     default:
          $_GET['orderBy'] = 'date_desc';
          $sql_orderBy = 'date DESC';
}
 
//GET THE LIST OF REGISTRANTS
$registrantList = '';
$sql = "SELECT first_name, last_name, date FROM 2011_registrants ORDER BY $sql_orderBy";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)) {
     $registrantList .= '<tr><td>' . htmlentities($row['first_name']) . '</td><td>' . htmlentities($row['last_name']) . '</td><td>' . $row['date'] . '</td></tr>';
}
 
//DISPLAY THE CONFERENCE REGISTRANTS
print '<table cellpadding="3" cellspacing="1" border="1">';
print '<tr>';
print '<th scope="col">';
if($_GET['orderBy'] == 'first_name') { print 'First Name'; }
else { print '<a href="/registrants.php?orderBy=first_name">First Name</a>'; }
print '</th>';
print '<th scope="col">';
if($_GET['orderBy'] == 'last_name') { print 'Last Name'; }
else { print '<a href="/registrants.php?orderBy=last_name">Last Name</a>'; }
print '</th>';
print '<th scope="col">';
if($_GET['orderBy'] == 'date_desc') { print 'Date Registered'; }
else { print '<a href="/registrants.php?orderBy=date_desc">Date Registered</a>'; }
print '</th>';
print '</tr>';
print $registrantList;
print '</table>';
?>

If you haven't done so already, you may want to review last week's post (Sorting HTML Data Tables Using the Header Row with PHP) which briefly describes what each part of the code does. If you're still unsure about something, feel free to mention it in the comments section below…since there doesn't seem to be any questions, let's get rolling.

Updating the Code

To sort the columns in both ascending and descending order, we'll need a few more values for the order by flag. Let's start by adding them to the first name heading.

<?php
print '<th scope="col">';
if($_GET['orderBy'] == 'first_name')          { print '<a href="/registrants.php?orderBy=first_name_desc">First Name<img src="arrowUp.gif" alt="Ascending Order (A to Z)" /></a>'; }
elseif($_GET['orderBy'] == 'first_name_desc') { print '<a href="/registrants.php?orderBy=first_name">First Name<img src="arrowDown.gif" alt="Descending Order (Z to A)" /></a>'; }
else                                          { print '<a href="/registrants.php?orderBy=first_name">First Name</a>'; }
print '</th>';
?>

The table heading will now take one of three states:

  1. If sorting first name in ascending order, display a link to sort in descending order
  2. Else…if sorting first name in descending order, display a link to sort in ascending order
  3. Else…display a link to sort by whatever the default order is for that column which will be ascending order for the first name

Note that the first two states contain an image that indicates the direction the column is being sorted. The third doesn't have an image since the data table is sorted by another column. Next we'll modify the other columns so they have the same setup.

<?php
//DISPLAY THE CONFERENCE REGISTRANTS
print '<table cellpadding="3" cellspacing="1" border="1">';
print '<tr>';
print '<th scope="col">';
if($_GET['orderBy'] == 'first_name')          { print '<a href="/registrants.php?orderBy=first_name_desc">First Name<img src="arrowUp.gif" alt="Ascending Order (A to Z)" /></a>'; }
elseif($_GET['orderBy'] == 'first_name_desc') { print '<a href="/registrants.php?orderBy=first_name">First Name<img src="arrowDown.gif" alt="Descending Order (Z to A)" /></a>'; }
else                                          { print '<a href="/registrants.php?orderBy=first_name">First Name</a>'; }
print '</th>';
print '<th scope="col">';
if($_GET['orderBy'] == 'last_name')           { print '<a href="/registrants.php?orderBy=last_name_desc">Last Name<img src="arrowUp.gif" alt="Ascending Order (A to Z)" /></a>'; }
elseif($_GET['orderBy'] == 'last_name_desc')  { print '<a href="/registrants.php?orderBy=last_name">Last Name<img src="arrowDown.gif" alt="Descending Order (Z to A)" /></a>'; }
else                                          { print '<a href="/registrants.php?orderBy=last_name">Last Name</a>'; }
print '</th>';
print '<th scope="col">';
if($_GET['orderBy'] == 'date')                { print '<a href="/registrants.php?orderBy=date_desc">Date Registered<img src="arrowUp.gif" alt="Ascending Order (Oldest to Newest)" /></a>'; }
elseif($_GET['orderBy'] == 'date_desc')       { print '<a href="/registrants.php?orderBy=date">Date Registered<img src="arrowDown.gif" alt="Descending Order (Newest to Oldest)" /></a>'; }
else                                          { print '<a href="/registrants.php?orderBy=date_desc">Date Registered</a>'; }
print '</th>';
print '</tr>';
print $registrantList;
print '</table>';
?>

We'll also need to modify the code for processing the order by flag.

<?php
//FIGURE OUT HOW TO SORT THE TABLE
switch($_GET['orderBy']) {
     case 'date':
     case 'first_name':
     case 'last_name':
          $sql_orderBy = $_GET['orderBy'];
          break;
 
     case 'date_desc':
     case 'first_name_desc':
     case 'last_name_desc':
          $sql_orderBy = substr($_GET['orderBy'], 0, -5) . ' DESC';
          break;
 
     default:
          $_GET['orderBy'] = 'date_desc';
          $sql_orderBy     = 'date DESC';
}
?>

Now when the flag is set to "date", "first_name", or "last_name"; the SQL query sorts the data by the selected column. But if the flag is set to "date_desc", "first_name_desc", or "last_name_desc"; it sorts by the column in descending order. Note that the substr() function is there to get the column name by chopping off the last five characters ("_desc"). The rest of the code is the same as last week.

Final Code

In the end, here is what the completed code looks like all together:

<?php
//IF THE FLAG HASN'T BEEN SET YET, SET THE DEFAULT
if(!isset($_GET['orderBy'])) {
     $_GET['orderBy'] = 'date_desc';
}
 
//FIGURE OUT HOW TO SORT THE TABLE
switch($_GET['orderBy']) {
     case 'date':
     case 'first_name':
     case 'last_name':
          $sql_orderBy = $_GET['orderBy'];
          break;
 
     case 'date_desc':
     case 'first_name_desc':
     case 'last_name_desc':
          $sql_orderBy = substr($_GET['orderBy'], 0, -5) . ' DESC';
          break;
 
     default:
          $_GET['orderBy'] = 'date_desc';
          $sql_orderBy     = 'date DESC';
}
 
//GET THE LIST OF REGISTRANTS
$registrantList = '';
$sql = "SELECT first_name, last_name, date FROM 2011_registrants ORDER BY $sql_orderBy";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)) {
     $registrantList .= '<tr><td>' . htmlentities($row['first_name']) . '</td><td>' . htmlentities($row['last_name']) . '</td><td>' . $row['date'] . '</td></tr>';
}
 
//DISPLAY THE CONFERENCE REGISTRANTS
print '<table cellpadding="3" cellspacing="1" border="1">';
print '<tr>';
print '<th scope="col">';
if($_GET['orderBy'] == 'first_name')          { print '<a href="/registrants.php?orderBy=first_name_desc">First Name<img src="arrowUp.gif" alt="Ascending Order (A to Z)" /></a>'; }
elseif($_GET['orderBy'] == 'first_name_desc') { print '<a href="/registrants.php?orderBy=first_name">First Name<img src="arrowDown.gif" alt="Descending Order (Z to A)" /></a>'; }
else                                          { print '<a href="/registrants.php?orderBy=first_name">First Name</a>'; }
print '</th>';
print '<th scope="col">';
if($_GET['orderBy'] == 'last_name')           { print '<a href="/registrants.php?orderBy=last_name_desc">Last Name<img src="arrowUp.gif" alt="Ascending Order (A to Z)" /></a>'; }
elseif($_GET['orderBy'] == 'last_name_desc')  { print '<a href="/registrants.php?orderBy=last_name">Last Name<img src="arrowDown.gif" alt="Descending Order (Z to A)" /></a>'; }
else                                          { print '<a href="/registrants.php?orderBy=last_name">Last Name</a>'; }
print '</th>';
print '<th scope="col">';
if($_GET['orderBy'] == 'date')                { print '<a href="/registrants.php?orderBy=date_desc">Date Registered<img src="arrowUp.gif" alt="Ascending Order (Oldest to Newest)" /></a>'; }
elseif($_GET['orderBy'] == 'date_desc')       { print '<a href="/registrants.php?orderBy=date">Date Registered<img src="arrowDown.gif" alt="Descending Order (Newest to Oldest)" /></a>'; }
else                                          { print '<a href="/registrants.php?orderBy=date_desc">Date Registered</a>'; }
print '</th>';
print '</tr>';
print $registrantList;
print '</table>';
?>

Example Table

With a few style sheet (CSS) declarations and a couple images, here is what our table might look like:

Screenshot showing a data table's column being sorted in ascending order
Figure 1. First Name Sorted in Ascending Order
Screenshot showing a data table's column being sorted in descending order
Figure 2. Last Name Sorted in Descending Order

11 Comments

  • #11 Patrick Nichols on 03.07.15 at 8:09 am

    @EZ – If you are pulling the table content from a text file, you could convert the text file content into an array with the file() function. Then you can use one of the array sorting functions to perform the sort.

  • #10 EZ on 02.19.15 at 5:11 pm

    Any idea on how to make 1 column of the table hyperlink to a textfile? The file is pulled from an sql db.

  • #9 Patrick Nichols on 09.29.14 at 7:32 pm

    @Anoop – Sorry, I'm not sure what you mean. The code for both sorting in ascending and descending order can be found in the post above. Of course, you'll need to modify the code to fit your needs.

  • #8 Anoop Singh on 09.27.14 at 5:19 am

    Sir i want decending and ascending both in one table one after click please give me code in php…thank you..sir..

  • #7 Patrick Nichols on 07.01.13 at 8:59 pm

    @Guru – Does the file you're linking to "(file name).php" exist in the root folder of your website? For reference, the following article explains in more detail how the different link types work:
    Absolute vs. Relative Paths/Links

  • #6 Guru on 06.29.13 at 6:21 am

    but sir its not working it gives error message…

    The requested URL /(file name).php was not found on this server.

  • #5 Guru on 06.29.13 at 5:59 am

    k sir thank you.. i find it…

  • #4 Patrick Nichols on 06.26.13 at 11:00 pm

    @Guru – Sorry about the confusion. The "registrants.php" file name doesn't really matter. The code can be incorporated into any page on your website. If that page isn't called "registrants.php", you'll need to modify the links accordingly.

    Technically, the file name could be left out entirely:
    print '<a href="?orderBy=date_desc">…

  • #3 Guru on 06.26.13 at 8:37 am

    Sorry sir, i cant understand about registrants.php file..
    what is it..?

  • #2 Patrick Nichols on 08.21.12 at 8:22 pm

    @Joe – No problem. Glad to help! :-)

  • #1 joe on 08.21.12 at 1:39 pm

    so awesome, thank you once again! what other cool stuff ya got? :P

Leave a Comment