Jak vytáhnout data z db na základě selectBoxu
- Freestyler
- Člen | 50
Ahoj,
vytvářím si vlastní jednoduchej datagrid, kterej vytáhne data z databáze
a na základě vybraného selectBoxu zobrazí výpis (ajax zatím nepotřebuju,
ale do budoucna ho tam chci taky). Myšlenka je, že v modelu bude dotaz do db,
kterej mi vytáhne IDčko a na jeho základě vypíše data. Koukal jsem na již
hotové datagridy, hledal na fóru, ale nikde jsem nenašel nic co bych
využil.
Zatím mám tohle:
Komponenta, která vykreslí formulář a zatím vypíše id kategorie
public function createComponentArticleMenu() {
$form = new Form();
$form->addSelect('category','Kategorie', $this->articles->getCategory()->fetchPairs('id','category_name'));
$form->addSubmit('submit', 'Zobrazit');
$form->onSuccess[] = $this->articleMenuSuceeded;
return $form;
}
public function articleMenuSuceeded($form) {
$values = $form->getValues();
$category = $values->category;
echo $category;
Tohle funguje, ale chtěl bych, aby to bylo schopné dynamicky zjistit jaké id (selectBox) jsem vybral a podle toho to ty data vypsalo, zatím vypíše jen id kategorie. Pořád se mi v hlavě objevuje if, ale nevím jak ověřit, které id bylo vybráno jinak než napevno ifem a nechci to tam nadrátovat napevno (když přidám kategorii do db, tak bych musel připsat další prvek do pole). Tzn. array (1,2,3,4 …) nechci.
Výsledek by měl být → vyberu prvek ze selectBoxu, kliknu na Zobrazit a dole se mi vypíše to co patří do dané kategorie.
Mohl by mě někdo prosím popostrčit?
Díky.
Ještě doplním šablonu, která se stará o zobrazení:
block content}
<br /> <br />
<div class="article_main">Posledních 10 příspěvků: <br /><br />
{control articleMenu}
<br /> <br />
<table class="table-article-create">
<thead>
<tr>
<th>ID</th>
<th>Název</th>
<th>Text</th>
<th>Autor</th>
<th>Datum</th>
<th>Kategorie</th>
</tr>
</thead>
<tbody>
<tr n:foreach = "$articles as $article">
<td>{$article->id}</td>
<td>{$article->title}</td>
<td>{$article->content}</td>
<td>{$article->author}</td>
<td>{$article->datetime}</td>
<td>{$article->category}</td>
</tr>
</tbody>
</table>
</div>
</div>
{/block}
- Mysteria
- Člen | 797
Normálně ve formuláři přesměruj na stejnou stránku a přidaj jako parametr to IDčko ze selectboxu a zpracuj to v render / action metodě.
public function articleMenuSuceeded($form) {
$this->redirect('this', ['categoryID' => $form->values->category]);
}
public function renderSomething($categoryID) {
$this->template->articles = !empty($categoryID) ?
$this->articleRepository->getByCategoryId($categoryID) :
$this->articleRepository->getAll();
}
Editoval Mysteria (29. 6. 2014 22:29)
- Freestyler
- Člen | 50
Díky, ale nešlo by to trochu víc rozepsat. První funkci chápu, ta mi hodí ID do url, ale to zpracování mi jasný není vůbec, zvlášt zápis otazníku a dvojtečky a co to má vlastně dělat, co k tomu mám dopsat.
Mysteria napsal(a):
Normálně ve formuláři přesměruj na stejnou stránku a přidaj jako parametr to IDčko ze selectboxu a zpracuj to v render / action metodě.
public function articleMenuSuceeded($form) { $this->redirect('this', ['categoryID' => $form->values->category]); } public function renderSomething($categoryID) { $this->template->articles = !empty($categoryID) ? $this->articleRepository->getByCategoryId($categoryID) : $this->articleRepository->getAll(); }
- Majkl578
- Moderator | 1364
Freestyler napsal(a):
zvlášt zápis otazníku a dvojtečky a co to má vlastně dělat
To je ternární operátor, zkrácený zápis
if (...) { ... } else { ... }
, to jsou základy PHP a nepatří na
tohle fórum.
- Freestyler
- Člen | 50
Pardon, jsem zase o něco chytřejší.
Nicméně to nic neřeší. Problém přetrvává a ten kód nefunguje, tak jak bych chtěl. Možná je problém jen v dotazu.
Tohle je funkce z modelu, která mi vypíše tabulku „category“ (ale možná úplně zbytečně)
public function getCategory() {
return $this->database->table('category');
}
Každopádně s tím předchozím kódem nefunguje, koukám do toho už tři hodiny a nic :(. Tak prosím ještě pořádne nakopnout.
Díky.
Majkl578 napsal(a):
Freestyler napsal(a):
zvlášt zápis otazníku a dvojtečky a co to má vlastně dělat
To je ternární operátor, zkrácený zápis
if (...) { ... } else { ... }
, to jsou základy PHP a nepatří na tohle fórum.
- Mysteria
- Člen | 797
Aby ti fungoval ten můj příklad, tak potřebuješ přidat do toho svého modelu ty dvě metody, co tam volám, takže zhruba takto:
// Vybere všechny články
public function getAll() {
return $this->database->table('articles');
}
// Vybere pouze ty články, který patří do kategorie vybrané v tom selectboxu
public function getByCategoryId($categoryID) {
return $this->database->table('articles')->where('category_id', $categoryID);
}
Pokud si ani tak nevíš rady, tak sem hoď komplet celej tvůj model + ten presenter.
Editoval Mysteria (30. 6. 2014 0:53)
- Freestyler
- Člen | 50
Píše mi to: „Missing argument 1 for getCategory“ :/.
HomepagePresenter
<?php
namespace AdminModule;
use Nette\Application\UI\Form;
/**
* Homepage presenter.
*/
class HomepagePresenter extends BasePresenter
{
/**
* @var \App\Model\Articles
* @inject
*/
public $articles;
public function beforeRender() {
$this->template->articles = $this->articles->fetchAll();
}
public function createComponentArticleMenu() {
$form = new Form();
$form->addSelect('category','Kategorie', $this->articles->getCategory()->fetchPairs('id','category_name'));
$form->addSubmit('submit', 'Zobrazit');
$form->onSuccess[] = $this->articleMenuSuceeded;
return $form;
}
public function articleMenuSuceeded($form) {
$this->redirect('this', ['categoryID' => $form->values->category]);
}
public function renderDefault($categoryId) {
$this->template->articles = !empty($categoryId);
$this->template->articles = !empty($categoryId) ?
$this->articles->getCategory($categoryId) :
$this->articles->fetchAll();
}
}
Articles Model
<?php
namespace App\Model;
/**
* Description of Articles
*
* @author Freestyler
*/
class Articles extends Base {
public function fetchAll() {
return $this->database->table('articles')
->limit('10');
}
public function articleAdd() {
}
public function getCategory($categoryId) {
return $this->database->table('articles')->where('category',$categoryId);
}
}
- Mysteria
- Člen | 797
Tak samozřejmě, protože protože ve výpisu kategorií pro ten selectbox ve formuláři používáš u metodu bez toho parametru. Každopádně máš tam bordel i v názvech. Do modelu přidej třeba metodu
public function getArticleCategories() {
return $this->database->table('category');
}
a tu použij v
$form->addSelect('category','Kategorie', $this->articles->getArticleCategories()->fetchPairs('id', 'category_name'));
Btw, pojmenovat si metodu, která ti vrací články dle jejich kategorie jako getCategory($categoryId) není moc ideální. Ten návrh getArticlesByCategory($categoryId) jsem nenavrhoval pro nic za nic. Samozřejmě na funkčnost to mít vliv nebude, ale až se na to koukneš za měsíc…
- Freestyler
- Člen | 50
Super, díky moc. Funguje přesně jak má.
Ještě bych potřeboval poradit s jednou věcí. V tabulce articles je sloupec categories, který je cizím klíčem propojen na tabulku categories, kde je id a name (např. úvod, program, fotogalerie etc.).
Snažím se aby ve výpisu článků nebylo id z tabulky articles ale name z tabulky categories. Myslel jsem, že když mám tabulky propojeny cizím klíčem, tak to bude sranda, ale nedaří se :(.
Toto vypíše bez problému id kategorie v které článek je, pokud to nahradím za „name“ (což je název sloupce v tabulce categories), tak to samozřejmě skončí chybou. Zkrátka nedaří se mi tahat z té tabulky data přes cizí klíč. Dokumentaci (konkrétně část table a selection jsem četl).
<td>{$article->categories}</td>
Pokud zkusím přistoupit přímo ke sloupci „name“ (což by mělo jít protože jsou propojeny klíčem), tak dostanu chybu Trying to get property of non object …
<td>{$article->categories->name}</td>
Díky.
Mysteria napsal(a):
Tak samozřejmě, protože protože ve výpisu kategorií pro ten selectbox ve formuláři používáš u metodu bez toho parametru. Každopádně máš tam bordel i v názvech. Do modelu přidej třeba metodu
public function getArticleCategories() { return $this->database->table('category'); }
a tu použij v
$form->addSelect('category','Kategorie', $this->articles->getArticleCategories()->fetchPairs('id', 'category_name'));
Btw, pojmenovat si metodu, která ti vrací články dle jejich kategorie jako getCategory($categoryId) není moc ideální. Ten návrh getArticlesByCategory($categoryId) jsem nenavrhoval pro nic za nic. Samozřejmě na funkčnost to mít vliv nebude, ale až se na to koukneš za měsíc…
Editoval Freestyler (30. 6. 2014 22:48)
- David Matějka
- Moderator | 6445
nepouziva se nazev cilove tabulky, ale nazev spojovaciho sloupecku (respektive jeho cast)
nazev „categories“ pro ten sloupecek je tedy ponekud nestastny. Je lepsi
pouzit category_id. Pote se necha pouzit $article->category
.
Ale muzes pouzit metodu ref, konkretne
$article->ref('categories')
vice v dokumentaci
- Freestyler
- Člen | 50
Ať použiju $article->ref(‚categories‘,‚categories_id‘)->name
a nebo zkusím přistoupit přímo ke sloupečku přes
$article->categories->name tak dostanu „Trying to get property of non
object“. Není problém že ty data předtím projíždím foreachem? Podle
mě by to ale mělo fungovat, jinak platí ten kód co jsem tady psal
už dříve.
Vytáhnu si data z db:
public function fetchAll() {
return $this->database->table('articles')
->limit('10');
}
Injectu do proměnný articles
/**
* @var \App\Model\Articles
* @inject
*/
public $articles;
public function beforeRender() {
$this->template->articles = $this->articles->fetchAll();
}
A projedu foreachem:
<tr n:foreach = "$articles as $article">
<td>{$article->id}</td>
<td>{$article->title}</td>
<td>{$article->content}</td>
<td>{$article->author}</td>
<td>{$article->datetime}</td>
<td>{$article->ref('categories','categories_id')->name}</td>
</tr>
Jinak SQL dump tabulky zde:
SET NAMES utf8;
SET foreign_key_checks = 0;
SET time_zone = '+02:00';
SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
DROP TABLE IF EXISTS `articles`;
CREATE TABLE `articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_bin NOT NULL,
`content` text COLLATE utf8_bin NOT NULL,
`categories_id` int(11) DEFAULT NULL,
`datetime` datetime NOT NULL,
`author` varchar(50) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`),
KEY `categories_id` (`categories_id`),
CONSTRAINT `articles_ibfk_1` FOREIGN KEY (`categories_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
DROP TABLE IF EXISTS `categories`;
CREATE TABLE `categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
- Mysteria
- Člen | 797
Nemáš tam nějakou záludnost typu, článek bez kategorie? Protože pak by to samozřejmě nefungovalo a musel by jsi to mít třeba takto:
{($category = $article->ref('categories','categories_id')) ? $category->name : 'Bez kategorie')}
matej21 napsal(a):
nepouziva se nazev cilove tabulky, ale nazev spojovaciho sloupecku (respektive jeho cast)
Díky za upřesnění, už moc dlouho využívám místo cizích klíčů konvenční pojmenování, kde ta část spojovacího sloupečku je vlastně název cílové tabulky. :)
- Freestyler
- Člen | 50
Samozřejmě jsem tam měl jeden článek bez kategorie a vůbec mi to nedošlo…
Díky moc!
Mysteria napsal(a):
Nemáš tam nějakou záludnost typu, článek bez kategorie? Protože pak by to samozřejmě nefungovalo a musel by jsi to mít třeba takto:
{($category = $article->ref('categories','categories_id')) ? $category->name : 'Bez kategorie')}
matej21 napsal(a):
nepouziva se nazev cilove tabulky, ale nazev spojovaciho sloupecku (respektive jeho cast)Díky za upřesnění, už moc dlouho využívám místo cizích klíčů konvenční pojmenování, kde ta část spojovacího sloupečku je vlastně název cílové tabulky. :)