CheckboxList a jeho kompletní použití
- iskejp
- Člen | 41
Ahoj,
po několika hodinách hledání jsem stále nenašel nějaký rozumný a kompletní postup jak použít CheckBoxList pro výběr položek v tabulce pro nějakou operaci s ním (mazání, úprava apod.). Jde o klasickou problematiku, která tu ve fóru byla již řešena, jenže jde o vlákna 2–3 roky stará a návody jsou spíše jen náznaky, které se mezi sebou ještě liší.
Byl by někdo ochoten pomoci? Zatím umím CheckBoxList připojit a zprovoznit. V čem jsem ztracen?
- Napojení záznamu o ID položky z DB do addCheckBoxList.
- Jak vypsat formulářový prvek v šabloně, tak aby se posléze odesílalo pole s vybranými položkami k nějaké operaci?
Zřejmě to bude triviální, ale nějak to nezvládám rozlousknout. Díky moc.
- vvoody
- Člen | 910
Myslim ze ten priklad pouzitia v tom linku je jasny.
- s cim mas problem? So ziskanim pola ID-ciek z tabulky pre tento checkkbox list? Metoda FetchPairs je k tomu ako stvorena. Alebo s dopravou tohoto pola do formlaru? Kde mas form definovany? Vo vlastnej triede alebo v presenteri?
- Vypisat formularovy prvok? Kazdy input vypisujes zvlast? Alebo cely formular ako komponentu ({control ..})?
- Filip Procházka
- Moderator | 4668
Já si nemyslím, že CheckBoxList se hodí do tabulky. Naznačím lepší řešení.
$select = $form->addContainer('select');
foreach ($radkyTabulky as $item) {
$select->addCheckbox($item->id);
}
{form grid}
<table>
<tr n:foreach="$radkyTabulky as $item">
<td>{input select-{$item->id}}</td>
...
</tr>
</table>
{/form}
$form->onSuccess[] = function ($form) {
$selected = $form['select']->getValues(TRUE);
// array(1 => TRUE, 2 => TRUE, 4 => FALSE, ...)
$ids = array_keys(array_filter($selected));
// array(1, 2, ...)
};
Editoval HosipLan (28. 7. 2012 15:53)
- iskejp
- Člen | 41
HosipLan napsal(a):
Já si nemyslím, že CheckBoxList se hodí do tabulky. Naznačím lepší řešení.
$select = $form->addContainer('select'); foreach ($radkyTabulky as $item) { $select->addCheckbox($item->id); }
{form grid} <table> <tr n:foreach="$radkyTabulky as $item"> <td>{input select-{$item->id}}</td> ... </tr> </table> {/form}
$form->onSuccess[] = function ($form) { $selected = $form['select']->getValues(TRUE); // array(1 => TRUE, 2 => TRUE, 4 => FALSE, ...) $ids = array_keys(array_filter($selected)); // array(1, 2, ...) };
Díky, to vypadá srozumitelně. Jen stále narážím na obecnější problém. Jakým způsobem se dostanu k datům, které načtu z DB v Presenteru. V uvedeném příkladu myslím $radkyTabulky, když je mám uložené v DB.
- Patrik Votoček
- Člen | 2221
iskejp napsal(a):
… Jakým způsobem se dostanu k datům, které načtu z DB v Presenteru …
Hosiplan nezná tou iplementaci modelové vrstvy takže ti to těžko řekne ale asi to bude něco jako:
$radkyTabulky = $presenter->nejakejTvujModel->findAll();
- iskejp
- Člen | 41
Patrik Votoček napsal(a):
iskejp napsal(a):
… Jakým způsobem se dostanu k datům, které načtu z DB v Presenteru …
Hosiplan nezná tou iplementaci modelové vrstvy takže ti to těžko řekne ale asi to bude něco jako:
$radkyTabulky = $presenter->nejakejTvujModel->findAll();
Ok, zde je to konkrétněji s částí kódu. Ta obecná formulace asi není nejlepší. Jde o Presenter:
private $row;
public function renderDefault() {
$articles = $this->context->createArticles()->where(array('user_id' => $this->getUser()->getId()));
$this->template->articles = $articles;
$this->row = $articles->fetch();
Nette\Diagnostics\Debugger::barDump($this->row);
}
protected function createComponentActionArticle($name) {
$form = new Form($this, $name);
$select = $form->addContainer('select');
foreach ($this->row as $item) {
$select->addCheckbox($item->id);
}
$form->addSubmit('actionDelete', 'X')->onClick[] = callback($this, 'actionArticleFormSubmitted');
$form->addSubmit('actionPublish', '!')->onClick[] = callback($this, 'actionArticleFormSubmitted');
$form->addSubmit('actionEdit', '?')->onClick[] = callback($this, 'actionArticleFormSubmitted');
$form->onSuccess[] = callback($this, 'actionArticleFormSubmitted');
}
Dump mi vypisuje na proměnou $row:
Nette\Database\Table\ActiveRow(3) ▼ {
table private ⇒ Articles(22) ►
data private ⇒ array(8) ►
modified private ⇒ array(0)
}
Díky moc.
Editoval iskejp (28. 7. 2012 18:49)
- Filip Procházka
- Moderator | 4668
private $articles;
public function actionDefault()
{
$this->articles = $this->context->createArticles()
->where(array('user_id' => $this->getUser()->getId()));
Nette\Diagnostics\Debugger::barDump(iterator_to_array($this->articles));
}
public function renderDefault()
{
$this->template->articles = $this->articles;
}
protected function createComponentActionArticle($name)
{
$form = new Form;
if (!$this->articles) {
// bezpečnost především
throw new Nette\Application\BadRequestException;
}
$select = $form->addContainer('select');
foreach ($this->articles as $item) {
$select->addCheckbox($item->id);
}
$form->addSubmit('actionDelete', 'X');
$form->addSubmit('actionPublish', '!');
$form->addSubmit('actionEdit', '?');
$form->onSuccess[] = callback($this, 'actionArticleFormSubmitted');
}
- voláš dump nad řádkem, né nad selectem. Nemůže ti nikdy vypsat nic rozumného
- pokud chceš vypsat všechny výsledky, bez
iterator_to_array
to nepůjde - v createComponent iteruješ nad řádkem, né nad výsledkem… to je blbost
- proč proboha dáváš na tlačítka i na formulář stejný callback? Víš že nad tlačítkem se ti předává tlačítko a nad formulářem se ti předává formulář? budeš z toho mít pěknej guláš
- zkus tomu kódu dát nějakou kulturu, to se nedá číst
Editoval HosipLan (29. 7. 2012 11:59)
- MartinitCZ
- Člen | 580
OT:
Jaký je v tom rozdíl?
$form->onSuccess[] = array($this, 'actionArticleFormSubmitted'); // 1.
$form->onSuccess[] = callback($this, 'actionArticleFormSubmitted'); // 2.
- iskejp
- Člen | 41
To HosipLan: Chyb s čtením řádku a nikoli záznamu jsem si vědom. Jen jsem nevěděl jak se správně dostat k těm datům.
Teď se hezky vypíše tabulka a checkbox s ID, ale po odeslání tlačítkem to skončí na tom, že $this->articles je prázdný a neprojde dále. Zachytí to ta přidaná kontrola chyb (díky za ní).
Měl jsem za to, že se po stisku odesílacího tlačítka volá metoda uvedená v callbacku a pak po přesměrování $this->redirect(‚this‘); opět celý presenter, takže se načtou opět data z DB.
No, asi tomu moc nerozumím, takže díky za trpělivost.
- vvoody
- Člen | 910
iskejp napsal(a):
Teď se hezky vypíše tabulka a checkbox s ID, ale po odeslání tlačítkem to skončí na tom, že $this->articles je prázdný a neprojde dále. Zachytí to ta přidaná kontrola chyb (díky za ní).
Preco nacitavanie dat z db nepresunies do tovarnicky? Evidentne tvoj form nieje v akcii default takze sa tie data nenacitaju.
Měl jsem za to, že se po stisku odesílacího tlačítka volá metoda uvedená v callbacku a pak po přesměrování $this->redirect(‚this‘); opět celý presenter, takže se načtou opět data z DB.
Ano, je to tak.
- Filip Procházka
- Moderator | 4668
Sory, to jsem přehlédl. Signály se vykonávají před render, takže ten
kód musí být v actionDefault
. Opravil jsem ten kód výše, aby
byl správně.
@vvoody: čtení z databáze patří do action.
Editoval HosipLan (29. 7. 2012 12:00)
- iskejp
- Člen | 41
Máš vlastně, pravdu, vyřešil to přesun do actionDefault. Proč je továrna lepší?
vvoody napsal(a):
iskejp napsal(a):
Teď se hezky vypíše tabulka a checkbox s ID, ale po odeslání tlačítkem to skončí na tom, že $this->articles je prázdný a neprojde dále. Zachytí to ta přidaná kontrola chyb (díky za ní).
Preco nacitavanie dat z db nepresunies do tovarnicky? Evidentne tvoj form nieje v akcii default takze sa tie data nenacitaju.
Měl jsem za to, že se po stisku odesílacího tlačítka volá metoda uvedená v callbacku a pak po přesměrování $this->redirect(‚this‘); opět celý presenter, takže se načtou opět data z DB.
Ano, je to tak.
- iskejp
- Člen | 41
Díky pomohlo to. Mohl bych ještě dostat vysvětlení k této konstrukci?
<?php
$form->onSuccess[] = function ($form) {
$selected = $form['select']->getValues(TRUE);
// array(1 => TRUE, 2 => TRUE, 4 => FALSE, ...)
$ids = array_keys(array_filter($selected));
// array(1, 2, ...)
};
?>
Není mi zcela jasné jak funguje onSuccess[] = function ($form). Zbytek je v pohodě.