EDIT: added solution from the accepted answer
The hint I'm asking here is the smartest method for.
Need to be said first: I kindly ask you to avoid suggesting databales and similar.
I'm displaying a MySQL table content in a HTML table.
I have the view that is
showdbtable.php
echohtmltable.php
echohtmltable.php
if(isset($_GET['sortby'])){
$sortby=$_GET['sortby'];
$_GET['sortby']=''; }
else {
$sortby="id_ord"; }
$query = "
SELECT id_ord, fornitore, negozio, data_insord, data_prevcons
FROM tesord
ORDER BY ".$sortby." DESC
LIMIT :from_record_num, :records_per_page";
echo "<th>".'<a href="showdbtable.php?sortby=fornitore">' . "Fornitore</th>";
echo "<th>".'<a href="showdbtable.php?sortby=negozio">' . "Negozio</th>";
echo "<th>".'<a href="showdbtable.php?sortby=data_insord">' . "Data_insord</th>";
echo "<th>".'<a href="showdbtable.php?sortby=data_prevcons">' . "Data_prevcons</th>";
LIMIT :from_record_num, :records_per_page
$query = "
SELECT id_ord, fornitore, negozio, data_insord, data_prevcons
FROM tesord
ORDER BY " . $sortby . " " . $ascdesc . "
LIMIT :from_record_num, :records_per_page";
// function used in the links
function invdir($dir){ return ($dir == "DESC")? "ASC" : "DESC"; }
// collect, sanitize and default $_GET variables
// $ordinaper is the Italian of $sortby
$ordinaper = (isset($_GET['ordinaper']))? (filter_var($_GET["ordinaper"], FILTER_SANITIZE_STRING)) : "id_ord";
$ascdesc = (isset($_GET['ascdesc']))? (filter_var($_GET["ascdesc"], FILTER_SANITIZE_STRING)) : "DESC";
// $filtraforn is a filter/search to show only one provider, see the query, it is assigned with a ìn AJAX live search
$filtraforn = (isset($_GET['filtraforn']))? (filter_var($_GET["filtraforn"], FILTER_SANITIZE_STRING)) : "";
// build the common URL GET part
$getlinks = "&filtraforn=".$filtraforn."&page=".$page."&ascdesc=";
// the variable $page comes from the pagination which is out of the scope. Here I was dealing with the correct management of sorting the HTML table columns
// the query is built accordingly, later is used in a PDO statement
$query = "SELECT id_ord, fornitore, negozio, data_insord, data_prevcons FROM tesord ";
$filtro = (strlen($filtraforn))? "WHERE fornitore = '" . $filtraforn . "' " : "";
$query = $query . $filtro . "ORDER BY ". $ordinaper ." ". $ascdesc ." LIMIT :from_record_num, :records_per_page";
// LIMIT :from_record_num, :records_per_page are bound later with variables coming from the pagination which is out of the scope. Here I was dealing with the correct management of sorting the HTML table columns
// and here it is the final table heading
// the ternary operator (($ordinaper!=="id_ord")? "DESC" : invdir($ascdesc)) is used because when clicking a different column, I want to default the sorting in DESC
echo "<tr>";
echo "<th></th>";
echo "<th>". '<a href="read.php?ordinaper=id_ord' .$getlinks. (($ordinaper!=="id_ord")? "DESC" : invdir($ascdesc)) .'">' . "id_ord</th>";
echo "<th>". '<a href="read.php?ordinaper=ord_evaso' .$getlinks. (($ordinaper!=="ord_evaso")? "DESC" : invdir($ascdesc)) .'">' . "Stato</th>";
echo "<th>". '<a href="read.php?ordinaper=fornitore' .$getlinks. (($ordinaper!=="fornitore")? "DESC" : invdir($ascdesc)) .'">' . "Fornitore</th>";
echo "<th>". '<a href="read.php?ordinaper=negozio' .$getlinks. (($ordinaper!=="negozio")? "DESC" : invdir($ascdesc)) .'">' . "Negozio</th>";
echo "<th>". '<a href="read.php?ordinaper=data_insord' .$getlinks. (($ordinaper!=="data_insord")? "DESC" : invdir($ascdesc)) .'">' . "Data_insord</th>";
echo "<th>". '<a href="read.php?ordinaper=data_prevcons' .$getlinks. (($ordinaper!=="data_prevcons")? "DESC" : invdir($ascdesc)) .'">' . "Data_prevcons</th>";
echo "<th>Paia Inev.</th>";
echo "<th>Azione</th>";
echo "</tr>";
If you are already sending the sortby via GET, why wouldn't you send the ASC,DESC Option too, I mean, you could use 1 and 0 instead of the actual ASC/DESC and toggle it inside your code,for example:
$ascdesc = ($_GET['ad'])? '0' : '1';
And just add the var to the link
echo "<th>".'<a href="showdbtable.php?sortby=negozio&ad='.$ascdesc.'">' . "Negozio</th>";
And in you query, something like
$ascdesc = ($_GET['ad'])? 'asc' : 'desc';
Something very important here is that if you are accepting user input via GET, you have to sanitize the var to avoid SQL injections, don't forget this.
UPDATE:
Possible implementation with your own code:
$sortby = (isset($_GET['sortby']))? $_GET['sortby'] : "id_ord";
$ascdesc = ($_GET['ad']=='asc')? 'ASC' : 'DESC';
The Query:
$query = "SELECT id_ord, fornitore, negozio, data_insord, data_prevcons
FROM tesord
ORDER BY ".$sortby." ".$ascdesc."
LIMIT :from_record_num, :records_per_page";
The link:
echo "<th>".'<a href="showdbtable.php?sortby=fornitore&ad=<?=(($_GET['ad']=='asc')? 'desc' : 'asc';)?>">' . "Fornitore</th>";
And if you need to add the page, just add the current page and change sort, you can add a var also to the link
echo "<th>".'<a href="showdbtable.php?sortby=fornitore&ad=<?php echo (($_GET['ad']=='asc')? 'desc' : 'asc';)?>&page=<?php echo $_GET['page]?>">' . "Fornitore</th>";
There are many other ways to handle the pagination and sorting, but I think that, without getting into a lot of trouble, this could be a way, however, about the security, you can use mysql_real_escape
You could also leave everything to javascript/jQuery by implementing something like this
Hope this can give you a better understanding, happy coding.