Domů

Ve dnešním pokračování si do komponenty přidáme kategorie a na nich si ukážeme zajímavé věci jako řazení pohledu seznamu, uložení řazení a také filtrování seznamu

Přidáváme kategorie

Jako první si vytvoříme potřebné soubory a to controller categories.php, dále 2 modely categories.php a category.,php a nakonec 2 pohledy categories a category a soubor pro objektové-relační mapování tabulky(v adresáři tables). Stačí použít soubory z minulých dílů a přejmenovat v nich sections na categories a section na category. Také nesníme zapomenout přidat do instalačního xml souboru Joomly přidat odpovídající soubory a také položku do menu a přidat do databáze do tabulky #__sf_categories sloupec ordering.

)
UPDATE jos_sf_categories ADD ordering int(5) NOT NULL);

Filtrování

Filtrování si ukážeme na příkladu vyfiltrování kategorií patřících do dané sekce našeho fóra. To zařídíme vytvořením rozbalovacího seznamu, do kterého musíme nejprve načíst data, což zajistíme pomocí jednoduchého dotazu do databáze. Daleko zajímavější je jeho zpracování. Jelikož potřebujeme jednu položku(volbu pro zobrazení všech kategorií) oproti datům načteným z databáze navíc, tak si jí do pole objektů, které jsme z databáze metodou loadObjectList() získali jednoduše přidáme fukncí PHP array_merge. Zde si všimněme, důležitého detailu tato položka musí být v poli, takže je nutné ji obalit ve funkci array(). Samotnou položku vytvoříme metodou select.option, jejiž název předáme do továrny HTML kódu JHTML::_(). Tento zápis je Joomlou interpretován jako volání metody JHTMLSelectOption(). Ta obsahuje parametry id položky (nastavujeme na -1, abychom jí odlišili od platných položek z databáze), text volby, a nakonec hodnoty, kde najdeme id a hodnotu(title) rozbalovacího seznamu ve výsledku SQL dotazu. Tyto dvě hodnoty musí být stejné pro celý rozbalovací seznam a zadáváme je také do metody pro samotné vytvoření seznamu select.genericlist.

  1. $query="SELECT id, title \n";
  2. $query.="FROM ".$this->getTable('section')->getTableName()." \n";
  3. $query.="ORDER BY title \n";
  4. $this->_db->setQuery($query);
  5. $sections_ol=array_merge(array(JHTML::_('select.option',-1,JText::_('Select section'),'id','title')),$this->_db->loadObjectList());
  6.  
  7. $lists["section_id"]=JHTML::_('select.genericlist',$sections_ol,'section_id','class="inputbox" size="1" onchange="document.adminForm.submit();"','id','title',$this->_section_id);

Jak vidíme jedná se opět o továrnu HTML, se kterou se setkáme ještě hodně krát. Jako parametry musíme uvést pole objektů výsledků dotazu, název seznamu, css stylování (zde je důležité si všimnout js kódu onchange, který nám zajistí interativitu seznamu), hodnoty, kde najdeme id a hodnotu(title) a jako poslední také jaká hodnota bude vybraná. Tu ještě nemáme vytvořenu, ale to hned napravíme v konstruktoru, kde si jí metodou getUserStateFromRequest() načteme.

  1. $this->_section_id=$app->getUserStateFromRequest($option.'section_id','section_id',-1,'int');

Dále je nutné filtr promítnout do samotného SQL dotazu. Z praxe mi vyšel jako nejlepší způsob, kdy si vytvořím vlastní metodu _setWhere(), kde do pole $where, v případě, že hodnota filtru je větší než 0, nebo v případě textu obsahuje nějaký text, ukládám části SQL dotazu pro filtrování(WHERE). Metodu končím navrácením řetězce spojeného pomocí PHP funkce implode() v případě, že v pole $where nějaké podmínky obsahuje, nebo prázdný řetězec v opačném případě. Tuto metodu pak volám v SQL dotazu _setQuery().

  1. private function _setWhere() {
  2. $where=array();
  3. if($this->_section_id>0) {
  4. $where[]="c.section_id=".$this->_section_id;
  5. }
  6. return count($where)?("WHERE ".implode(" AND ",$where)." \n"):"";
  7. }
  8.  
  9. private function _setQuery() {
  10. $query="SELECT c.*, s.title AS section \n";
  11. $query.="FROM ".$this->getTable('category')->getTableName()." AS c \n";
  12. $query.="LEFT JOIN ".$this->getTable('section')->getTableName()." AS s ON c.section_id=s.id \n";
  13. $query.=$this->_setWhere();
  14. $query.="ORDER BY ".$this->_orderBy." ".$this->_orderDir." \n";
  15. return $query;
  16. }

Zobrazení filtru je velice jednoduché. Stačí jej přidat do souboru default.php daného pohledu v našem případě categories. Tady si dejte pouze pozor, aby filtr začínal až ve formuláři, nikoliv nad ním, což se mi několikrát stalo a pak jsem se divil proč filtrování nefunguje.

  1. <table width="100%">
  2. <tr>
  3. <td><?php echo Jtext::_('Section'); ?>: <?php echo $this->lists["section_id"]; ?>
  4. </tr>
  5. </table>

Přidání rozbalovacího seznamu do editace

Abychom mohli sekce filtrovat, tak je nutné si je neprve přiřadit k dané sekci. Postupovat budeme víceméně stejně jako u filtru seznamu. Pouze do css stylování metody select.genericlist nepřidáme akci onchange. Také si musíme přidat předání dat listingu do přípravy pohledu.

  1. <tr>
  2. <td>
  3. <?php echo JText::_('Section'); ?>
  4. </td>
  5. <td>
  6. <?php echo $this->lists["section_id"]; ?>
  7. </td>
  8. </tr>
  1. $this->assignRef('lists',$this->get('lists'));

Řazení seznamu

V případě řazení seznamu si vystačíme pouze v pohledu, konkrétně v jeho záhlaví, kde nahradíme popisky sloupců za další metodu HTML továrny a to grid.sort, které jako parametry předáme Popisek sloupce, jméno pole v SQL databázi podle kterého se má řadit, dále uloženou položku listingu orderDir, ve které máme uložen směr řazení a také ještě aktuální sloupec podle kterého se řadí(orderBy). Tyto hodnoty máme již v modelu připravené. Jako druhý krok ještě na konec formuláře přidáme dvě skrytá (hidden) pole s názvy filter_order a filter_order_Dir. Do těchto polí nám totiž js Joomly ukládá aktuální filtrování.

  1. <thead>
  2. <tr>
  3. <th width="5">
  4. <?php echo JText::_('NUM'); ?>
  5. </th>
  6. <th width="5">
  7. <input class="inputbox" type="checkbox" name="toggle" value="0" onclick="checkAll('<?php echo count($this->data); ?>')" />
  8. </th>
  9. <th>
  10. <?php echo JHTML::_('grid.sort',JText::_('Title'),"c.title",$this->lists["orderDir"],$this->lists["orderBy"]); ?>
  11. </th>
  12. <th>
  13. <?php echo JHTML::_('grid.sort',JText::_('Section'),"s.title",$this->lists["orderDir"],$this->lists["orderBy"]); ?>
  14. </th>
  15. </thead>
  1. <input type="hidden" name="filter_order" value="<?php echo $this->lists["orderBy"]; ?>" />
  2. <input type="hidden" name="filter_order_Dir" value="<?php echo $this->lists["orderDir"]; ?>" />

Uložení řazení

Někdy se nám může hodit, aby se položky ve veřejné části, na kterou dojde později, zobrazovaly seřazené podle určitého způsobu. Ani na toto Joomla nezapomíná a pomůže nám s tím. Do tabulky seznamu si přidáme sloupec určující řazení. Záhlaví sloupce obsahuje metodu grid.order s parametrem všech dat seznamu. Jako nepovinný parametr můžeme zadat název akce(task), pokud nám výchozí saveorder nevyhovuje. Tato metoda zajistí zobrazení tlačítka diskety, které pomocí js kódu předá zadané řazení k uložení.

  1. <th width="100px">
  2. <?php echo JHTML::_('grid.sort',JText::_('Ordering'),"c.ordering",$this->lists["orderDir"],$this->lists["orderBy"]); ?>
  3. <?php echo JHTML::_('grid.order',$this->data); ?>
  4. </th>
  1. <td align="center"><input class="inputbox" type="text" size="5" name="ordering[<?php echo $row->id; ?>];" value="<?php echo $row->ordering; ?>" /></td>

Do datové části sloupce vložíme textové pole, které nám umožní zadat požadované řazení. Tady je důležité, aby název pole byl ve tvaru jmeno[id], v našem případě tedy ordering[id]. Takto jej půjde později jednoduše zpracovat. Zpracování probíhá hlavně v modelu. Controller obsahuje pouze volání metody reorder modelu. Zpracování dat v modelu spočívá v projetí všech položek v cyklu foreach(), kde perfektně využijeme, že jsme pro hodnoty řazení využili pole v požadavku. V cyklu načítáme záznam podle id a přiřazujeme mu aktuální hodnotu řazení a tento záznam následně ukládáme. Hlavní práce se ale skrývá v metodě reorder(), kdy Joomla za nas vyřeší, aby číslovaní položek bylo kontinuální bez mezer.

  1. function reorder() {
  2. $ordering=JRequest::getVar('ordering',array(),'post','array');
  3.  
  4. foreach($ordering as $k=>$v) {
  5. $this->_table->load($k);
  6. $this->_table->ordering=$v;
  7. if(!$this->_table->store()) {
  8. $this->setError($this->_db->stderr(true));
  9. return false;
  10. }
  11. }
  12. $this->_table->reorder();
  13. return true;
  14. }

Jako domácí úkol nechávám přidání uložení řazení v sekcích. Výsledný kód najdete v příštím díle.

Příště

V dalším pokračování přejdeme k samotným příspěvkům našeho fóra a ukážeme si na nich mimo jiné, jak pomocí AJAXu načítat kategorie v závislosti na vybrané sekci. Aktuální stav komponenty naleznete ke stažení zde.

Komentářů (0)
Přidat komentář
YOUR_CONTACT_DETAILS:
Komentářů:
[b] [i] [u] [s] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
SECURITY
Prosím=vložte text z obrázku (anti-SPAM ochrana

Zprávičky

Napsat novou zprávičku  |  Vše

sh404SEF 2.0.3.545

Nová verze

Napsal Peter Smrčák | 13.08 22:12

Kunena 1.6 RC1

Nová verze

Napsal Peter Smrčák |  9.08 15:28

Vyšla nová Kunena RC1 pre pripravovanú Joomlu 1.6.

EasyBook reloaded!

Nová verze

Napsal Peter Smrčák |  4.08 06:41

Vyšla stabilná verzia obľúbenej návštevnej knihy EasyBook reloaded vo verzii 2.0.4.

VirtueMart 1.1.5

Nová verze

Napsal Peter Smrčák | 28.07 15:11

Práve vyšiel nový VirtueMart.

Táto verzia opravuje rôzne problémy.

changelog | download

Joomla 1.5.19

Bezpečnost

Napsal Filip Bartmann | 16.07 18:30

Dnešním dnem spatřila světlo světa další aktualizace stabilní řady Joomly 1.5, tentokrát s pořadovým číslem 19 a kódovým jménem Wojmamni ama batani. Jedná se o opravu několika menších bezpečnostních chyb v administraci a také novou verzi js frameworku Mootools.

Více...

Jméno Joomla!® je použito pod limitovanou licenci od Open Source Matters ve Spojených státech a ostatních zemích. Joomladev nemá spojení s Open Source Matters, nebo projektem Joomla! a není součástí jejich podpory
Logo Joomla!® je použito pod limitovanou licenci od Open Source Matters ve Spojených státech a ostatních zemích. http://joomladev.eu nemá spojení s Open Source Matters, nebo projektem Joomla! a není součástí jejich podpory