Giving users the ability to sort tables could hold some risks if actual field names are used as URL parameters.
Re-coding my user management made me want to write this. It not only allows tables to be viewed in any sort order, but also checks to see if the user request to sort is actually valid…Just to make sure.
The request format is “?orderby=fieldname:sort”, eg. fieldname “?orderby=Id:DESC”
The code is pretty self explanatory.
/* function to check if a fieldname is valid */
function isDBfield($tablename,$fieldname){
if (isset($fieldname) && isset($tablename)){
$tmp = $this->DoQuery('SHOW COLUMNS FROM '.$tablename,1);
foreach ($tmp as $s){
if ($s[Field]==$fieldname) return true;
}
return false;
}
return false;
}
/* getting/setting the "ORDER BY" string asuming $_GET[orderby] to be in "field:order" format */
$defaultSortField = 'Id';
$defaultSortOrder = 'ASC';
if (strstr($_GET[orderby],':')){
$orderarray = explode(':',$_GET[orderby]);
} else {
$orderarray = Array();
$orderarray[] = $defaultSortField; //default field
$orderarray[] = $defaultSortOrder; // default order
}
/* checking the validity of the "orderarray" */
if ( ($mpage->isDBfield(PREFIX.'TableName',$orderarray[0]) ) && ($orderarray[1]=='ASC' || $orderarray[1]=='DESC')) {
$orderstr = ' ORDER BY '.$orderarray[0].' '.$orderarray[1];
} else {
$orderstr = ' ORDER BY '.$defaultSortField.' '.$defaultSortOrder;
}
/* Fetching data */
$sql = "SELECT * FROM ".PREFIX."TableName".$orderstr;
$r = $mpage->DoQuery($sql, 1);
/* Fetching fieldames */
$fieldname = array_keys($r[0]);
/* function to create sorting links */
function createOrderLink($fieldname,,$orderstr){
$order='ASC';
$classStr = '';
if (strstr($orderstr)){
if (strstr(,$orderstr,$fieldname.' ASC')) {
$order='DESC';$classStr=' orderdesc';
} else if (strstr(,$orderstr,$fieldname.' DESC')) {
$order='ASC';$classStr=' orderasc';
}
}
$str = '
<a href="javascript:void(0);" class="sortable'.$classStr.'" onclick="getHTML(\'?orderby='.$fieldname.':'.$order.'\',\'corecontent\');this.blur;return false;">
'.$fieldname.'
</a>';
return $str;
}
/* creating the table head row */
$page_content .= '
<table style="width:100%" class="listtable">
<tr>
<th>'.createOrderLink($fieldname[0],$orderstr).'</th>
<th>'.createOrderLink($fieldname[1],$orderstr).'</th>
<th>'.createOrderLink($fieldname[3],$orderstr).'</th>
<th>'.createOrderLink($fieldname[4],$orderstr).'</th>
<th>'.createOrderLink($fieldname[6],$orderstr).'</th>
<th>'.createOrderLink($fieldname[7],$orderstr).'</th>
<th>'.createOrderLink($fieldname[8],$orderstr).'</th>
<th>'.createOrderLink($fieldname[9],$orderstr).'</th>
<th>...</th>
</tr>';















…
Personally, though the concept of this is great, I think it may cause more problems than needed in bigger applications. Sorting is great, but when you have a vast amount of tabular data, needing to write the same code all over again just doesn’t make sense… Not to mention you have to maintain that order during pagination, which means either storing it in a session, or appending it to the query string.
Now, this is not necessarily a bad thing, but it might be worthwhile considering a javascript solution, something like Brainjar’s code, or Webfx, or even active widgets. The upsides is that you can make everything sortable by default, and that’s it. Personally I like javascript sorting anyways - it’s real time, and I don’t have to do all sorts of funky error checking with the query string.
*grins* and you spelled Create wrong.
-Ryan
…
Hmm…The problem with javascipt is, when i’m viewing records 1 to 30, and I sort by ID, I only sort and view records 1 to 30 by ID. The upside of javascript is when i’m viewing records 31 to 60, and I sort by ID, I only sort and view records 31 to 60 by ID.
Get my dilemma?
Local javascript sorting only sorts with the data it currently has. AJaX sorting is better in this case.
PS: Thanks for the typo note…I never spellcheck my code after speedtyping it :-/