CheckboxList a jeho kompletní použití

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
iskejp
Člen | 41
+
0
-

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?

  1. Napojení záznamu o ID položky z DB do addCheckBoxList.
  2. 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
+
0
-

Myslim ze ten priklad pouzitia v tom linku je jasny.

  1. 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?
  2. Vypisat formularovy prvok? Kazdy input vypisujes zvlast? Alebo cely formular ako komponentu ({control ..})?
Filip Procházka
Moderator | 4668
+
0
-

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
+
0
-

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.

MartinitCZ
Člen | 580
+
0
-

Myslíš v templatě?

$this->template->radkyTabulky = $radkyTabulky;
Patrik Votoček
Člen | 2221
+
0
-

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
+
0
-

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
+
0
-
	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
+
0
-

OT:
Jaký je v tom rozdíl?

$form->onSuccess[] = array($this, 'actionArticleFormSubmitted'); // 1.
$form->onSuccess[] = callback($this, 'actionArticleFormSubmitted'); // 2.
iskejp
Člen | 41
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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.

vvoody
Člen | 910
+
0
-

@HospiLan: nvm, mne to tam nijak zvlast neprekaza pokial to je stale v presenteri. O starost menej s tym ci prebehla presne ta akcia v ktorej sa nacitaju data ktore v tovarnicke potrebujem.

iskejp
Člen | 41
+
0
-

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ě.