Zoraďovanie dát z databázy
Potom, ako sme si ukázali a naprogramovali základné operácie s dátami na našej stránke, si ešte na záver časti o zavádzaní SQL do praxe ukážeme, ako využiť v praxi zoraďovanie dát v databáze. Ak si spomeniete, v semestri o jazyku SQL sme si ukazovali príkaz ORDER BY, ktorému môžeme zadať názov stĺpca, podľa ktorého budú dáta zotriedené. Okrem toho môžeme zadať postupne zotriedenie podľa viacerých stĺpcov a taktiež určiť smer zoraďovania (vzostupne alebo zostupne).
Naša tabuľka používateľov môže obsahovať veľký počet záznamov. Pre lepšiu prehľadnosť sme si pridali filtrovanie, ktoré umožňuje a uľahčuje rýchle nájdenie žiadaného záznamu. Veľmi častým zvykom je pri tabuľkách a akýchkoľvek iných zoznamoch mať možnosť zoradiť dáta podľa konkrétnych stĺpcov. Vo väčšine sa klikne v hlavičke tabuľky na konkrétny stĺpec a dáta sa následne zoradia podľa príslušného stĺpca. Po opätovnom kliknutí na už zotriedený stĺpec sa zvykne zmeniť spôsob (poradie) zoraďovania. Niečo podobné si ideme spraviť aj my.
Opäť to nebude nič extra ťažké, len to bude zase spojenie viacerých vecí, čo už vieme, dokopy. Takže si to rozoberme na menšie časti. Keďže sme povedali, že klikneme na názov stĺpca, tak budeme musieť z neho spraviť odkaz (a). Po kliknutí na tento odkaz musíme dať najavo, že chceme podľa tohto stĺpca zoradiť dáta v tabuľke, takže asi k URL na našu aktuálnu stránku (index.php) pridáme nejaké tie parametre, ktoré nám povedia, podľa čoho chceme triediť. Aby sme to mali na začiatok jednoduchšie, spravíme si triedenie len podľa mena a priezviska. Následne v kóde musíme odchytiť parametre, či bola nejaká požiadavka na triedenie a ak áno, tak to aplikujeme do príkazu SELECT.
Poďme teda na to. Začneme tým, že si z hlavičky spravíme odkazy, ktoré zavolajú našu stránku s parametrom, v ktorom bude uvedené, podľa ktorého stĺpca máme dáta zotriediť. Mohlo by to vyzerať asi takto:
index.php (zmena v hlavičke tabuľky):
echo '<tr>';
echo '<th>ID</th>';
echo '<th><a href="index.php?sort_by=user_name">Meno</a></th>';
echo '<th><a href="index.php?sort_by=user_surname">Priezvisko</a></th>';
echo '<th>Vek</th>';
echo '<th>Rola</th>';
echo '<th>Akcie</th>';
echo '</tr>';
Ako vidíme, pridali sme do URL parameter s názvom sort_by, ktorý bude určovať stĺpec, podľa aktorého máme dáta triediť. Názvy týchto dvoch stĺpcov by sa mali zmeniť na odkazy, po prejdení ponad ne je vidieť, aká URL sa zavolá (aj s parametrami). Dizajnom sa zatiaľ nejdeme zaoberať... Teraz sa môžeme v kóde, kde načítavame dáta z databázy opýtať, či je tento parameter neprázdny, čo bude znamenať, že sme sa na našu stránku dostali z kliknutia na odkaz v hlavičke tabuľky. Ak áno, hodnotu tohto parametra pridáme do príkazu sql ORDER BY. Mohlo by to vyzerať takto:
index.php (za spracovanie filtrovania pred zavolanie query na select):
…
//ZACHYTENIE PARAMETRA PRE TRIEDENIE DAT V TABULKE
$sort_by = $_GET['sort_by'];
if($sort_by){
$sql_query .= " ORDER BY ".$sort_by." ASC";
}
...
Ako vidíte, ak sa nejaká hodnota v našom parametri nachádza, tak pridáme (.= priliepa k stringu) do nášho selectu príkaz order by. Ak si to vyskúšate, tak uvidíte, že zoraďovanie skutočne funguje. Len pre kontrolu si môžete dať vypísať pomedzi to query, aby ste videli, aký dotaz na databázu zadávame a že sa v nej skutočne nachádza klauzula order (print_r($sql_query)). Ako vidíte, zatiaľ sme dali natvrdo zoraďovanie vzostupne. Poďme sa ale zamyslieť nad tým, ako by sme spravili, aby sa po opätovnom kliknutí na zoradený stĺpec zmenilo poradie zoradenia.
Otázka je, čo vlastne chceme. My chceme, aby v momente, kedy je nastavené zoradenie podľa nejakého stĺpca a po kliknutí na ten istý stĺpec, sa zmenil spôsob zoradenia. Presne túto vetu, ktorú sme si teraz povedali, musíme iba napísať do podmienky if, aby sme práve tento prípad odchytili a v danom momente zmeníme poradie sortovania. Jednoducho by sme to ale mohli spraviť, keby sme si vedeli nejako pamätať, čo bolo predtým. To lenže samozrejme nevieme, my máme vždy našu stránku s takou url, ako sa zavolala. Takže si do URL musíme pridať ďalší parameter, ktorý bude určovať smer zoradenia a následne meniť jeho hodnotu, podľa toho, čo je aktuálne zotriedené. Čiže defaultne budeme mať aj spôsob zoradenia v URL a bude defaultne nastavené na ASC. Ak sa kliklo na nejaký stĺpec pre zoradenie, budeme to vidieť v URL a následne podľa toho nastavíme URL pre kliknutie v hlavičke. Mohlo by to teda vyzerať nejako takto:
index.php (zmenený kód):
…
//ZACHYTENIE PARAMETRA PRE TRIEDENIE DAT V TABULKE
$sort_by = $_GET['sort_by'];
$sort_type = $_GET['sort_type'];
if($sort_by){
$sql_query .= " ORDER BY ".$sort_by;
if($sort_type){
$sql_query .= " ".$sort_type;
}else{
$sql_query .= " ASC";
}
}
$result = mysqli_query($connection, $sql_query);
…
echo '<tr>';
echo '<th>ID</th>';
echo '<th><a href="index.php?sort_by=user_name';
if($sort_by == 'user_name'){
if($sort_type == 'ASC'){
echo '&sort_type=DESC';
}else{
echo '&sort_type=ASC';
}
}else{
echo '&sort_type=ASC';
}
echo '">Meno</a></th>';
echo '<th><a href="index.php?sort_by=user_surname';
if($sort_by == 'user_surname'){
if($sort_type == 'ASC'){
echo '&sort_type=DESC';
}else{
echo '&sort_type=ASC';
}
}else{
echo '&sort_type=ASC';
}
echo '">Priezvisko</a></th>';
echo '<th>Vek</th>';
echo '<th>Rola</th>';
echo '<th>Akcie</th>';
echo '</tr>';
...
Ako vidíte v kóde, v časti pri zachytení parametra o sortovaní sme pridali aj zachytenie druhého parametra pre spôsob zotriedenia a následne sa pýtame, či nám tento parameter prišiel. Ak nie, tak defaultne zotrieďujeme vzostupne a ak áno, tak podľa jeho hodnoty. Ako sme povedali, musíme tento parameter pridať aj do odkazov v hlavičke. Podmienka pri skladaní odkazu by sa dala prečítať nasledovne. Najprv si k URL priliepame parameter pre zotriedenie (order_by) podľa toho, na aký stĺpec to je odkaz. Následne sa pýtame, či sú dáta aktuálne zoradené podľa tohto stĺpca (if($sort_by == 'user_name'){). Ak nie, tak nastavíme natvrdo smer ASC. Ak áno, tak sa následne pýtame, akým smerom (ASC alebo DESC), resp. či je to zotriedené vzostupne. Ak áno, tak aktuálny odkaz bude na zotriedenie zostupne a opačne, jednoducho nastavujeme URL pre opačné zotriedenie.
Ak máme zoradené napríklad podľa stĺpca user_name, tak URL pre odkaz user_surname bude mať ASC, pretože pri zmene stĺpcov, podľa ktorých sa zoraďuje, chceme mať defaultne na ASC. Skúste si dať vypísať query pred zavolaním a uvidíte, že to skutočne funguje. Šikovné nie? Takto by ste si už teraz vedeli sami spraviť aj zoraďovanie podľa ostatných stĺpcov, nejdeme sa s tým teraz zdržiavať, bolo by to to isté...
Možno ste si všimli ešte jednu vec, ktorá nie je úplne korektná. Ak klikneme na nejaký stĺpec pre zoradenie, tak v URL máme parametre pre zoradenie, to je v poriadku. Spomeňte si ale, ako funguje náš filter. Zadané vyhľadávané slovo sa tiež posiela cez URL. V obidvoch prípadoch však voláme URL iba buď s parametrom pre filtrovanie alebo s parametrami pre zoraďovanie. To zapríčiní to, že ak si niečo vyfiltrujeme a následne klikneme na zoradenie podľa nejakého stĺpca, filter sa nám z URL stratí, pretože pri skladaní odkazu pre zoraďovanie ho nezahŕňame do URL a rovnako pri filtrovaní nezahŕňame parametre pre zoradenie.
Aby sme to mali dokonalé, mali by sme tento problém vyriešiť tak, že by sme všetky tieto parametre zahrnuli v obidvoch prípadoch. Mali by sme teda toto pridať do kódu:
index.php (len pridaný kód):
…
<input type="hidden" name="sort_by" value="<?php echo $sort_by;?>">
<input type="hidden" name="sort_type" value="<?php echo $sort_type;?>">
…
if($search_keyword){
echo '&search_keyword='.$search_keyword.'&search_form=Filtruj';
}
...
Ak teda chceme, aby sa v momente, kedy máme napríklad vyfiltrované slovo ''ar'' a následnom kliknutí na zotriedenie, zachovalo filtrovanie, pridáme túto podmienk na koniec skladania URL pri tvorení odkazov v hlavičke tabuľky. Nerobíme nič iné, iba sa pýtame, či je niečo vyfiltrované. Ak áno, tak parametre filtrovania pridáme do našej URL, aby sa zachovalo. Všimnite si, že sme pridali aj parameter search_form. Ak by sme ho nezadali, tak by sa následne filtrovanie nezaregistrovalo kvôli podmienke, ktorá kontroluje, či bol odoslaný formulár (if($_SERVER['REQUEST_METHOD'] == 'GET' && $_GET['search_form']){).
Opačný prípad, kedy je nejaké triedenie nastavené a my následne vyfiltrujeme, je v prvej časti kódu. Filtrovanie sa rieši cez formulár a ako vieme, v URL sa objavia iba tie parametre, ktoré sa nachádzajú vo forme. Preto použijeme rovnakú fintu ako v prípade zachovanie id_usera na stránke uprava-zaznamu a pridáme do formu dva skryté (hidden) elementy, ktoré budú slúžiť iba na to, aby sa preposlali aktuálne hodnoty nastavené v parametroch sort_by a sort_type. Teraz je už naše zoraďovanie čo sa týka funkcionalite vyhovujúce našim požiadavkam a dokonca spolupracuje aj s filtrovaním a parametre týchto dvoch funkcionalít sa navzájom nebijú.
Aby to bolo úplne dokonalé, chcelo by to zmeniť dizajn odkazov a tiež dať nejako dizajnovo používateľovi najavo, že je nejaké triedenie aktívne, lebo momentálne to je viditeľné iba v URL a používateľ neprogramátor z toho veľa nevie. To si ale spravíme v nasledujúcej prednáške:)