předávání hodnot do formuláře – best practise?

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

Ahoj,
prosím jaké je best-practise při předávání hodnot do formuláře?
V současnosti znám tyto možnosti:

  1. vytvořit Control, který vytvoř formulář pomocí továrničky. Parametry předávat v šabloně, tyto parametry převezme metoda render Controlu.
  2. hodnoty do formuláře předávat v šabloně, příklad:
{? $control['form']['id']->value = $category->id}
{control form}

Jenže, u 1. způsobu se mi nelíbí, že Form, což je v podstatě taky Control obaluji dalším Controlem.
A u 2. způsobu se mi nelíbí, že hodnoty nastavuji tam, kde bych je měl jen vypsat.

Jak tohle řešíte vy, prosím?

nanuqcz
Člen | 822
+
0
-

Ahoj, tohle se pokud vím dělá většinou v presenteru:

public function renderShow($category_id)
{
    $category = $this->getService('CategoryModel')->getCategory($category_id);
    $this['categoryForm']->setDefaults($values);
}

public function createComponentCategoryForm()
{
    $form = new Form();
    ...
    return $form;
}

Nebo tenhle způsob u tebe z nějakého důvodu nejde?

Mesiah
Člen | 240
+
0
-

Přiznám se, že tohle jsem neznal. Prosím tě, u metody renderShow máš parametr $category_id, do tohoto parametru dostanu argument jak?

Editoval Mesiah (13. 7. 2011 15:19)

Filip Procházka
Moderator | 4668
+
0
-

Nette routování automaticky doplňuje do metod action<action> a render<view> argumenty, podle jmen parametrů presenteru. Jinými slovy, pokud budeš mít url

/presenter/akce/?category_id=1

pak se ti metoda renderAkce($category_id), bude volat s $category_id = 1

Petr Stribny
Člen | 16
+
0
-

Parametr ti tam dosadí Nette samo z URL, pokud máš patřičně nastavené routy.

Editoval Petr Stribny (13. 7. 2011 15:47)

Mesiah
Člen | 240
+
0
-

Jasný, vůbec mi to nedošlo.
Nicméně, v situaci, kdy formuláře generuji dynamicky, takový krásný příklad jsou produkty v e-shopu, kdy v seznamu produktu budu chtít mít miniform na přidání produktu do košíku, jaký je pro takový případ best-practise? Získat kolekci produktů a pak ji v presenteru projít a připojit tento miniform? V této situaci by se hodilo, aby Form() mohl přijímat argumenty, ne?

Filip Procházka
Moderator | 4668
+
0
-

To už se tu řešilo mockrát, buď konkrétní, nebo hledej na fóru.

Mesiah
Člen | 240
+
0
-

Nenapadá mě jak být konkrétnější, ale zkusím to rozepsat.
Jsou produkty v e-shopu zobrazeny na jedné stránce, u každého produktu budu chtít mít formulář na přidání produktu/ů do košíku (wireframe).
Teď jde o to jak to udělat?

1. můžu v šabloně přidat id ho hidden pole pomocí konstrukce

{? $control['form']['id']->value = $product->id}
{control form}

2. můžu v presenteru získat kolekci produktů, tuto kolekci projít a ke každému produktu přidat dynamicky vytvořený formulář, jak psal xxxObiWan a na ten šabloně vykreslit. (nezkoušel jsem to, jde jen o nástřel)

foreach ($products as $product) {

	$values = array('id' => $product->id);
	// add
	$product->form = $this['form']->setDefaults($values); // otázka je, jestli vůbec docílím vytvoření kopie a případně jaké
}

3. použít na to control jak jsem psal v prvním postu.

Teďkom mi jde o to, který směr je nejvhodnější z hlediska MVC?

Nejvíc by se mi líbilo, kdybych mohl v šabloně zavolat tvorbu formuláře z továrničky s parametrem(parametry) (ukázka na konci). A to z toho důvodu, že v controlleru/presenteru formulář nadefinuji, definuji co má obsahovat a co má udělat a v pohledu jej vykreslím s definovaným prvkem.
V současnosti bych toho docílil jedině pomocí použití dalšího Controlu, který formulář obalí, ale to mi přijde takové „ech :/“ řešení…

ukázka:

{foreach $products as $product}
	...info o produktu v HTML
	{control form $product->id}
{/foreach}

Editoval Mesiah (13. 7. 2011 22:18)

Filip Procházka
Moderator | 4668
+
0
-

Chtělo by to jednu komponentu, která bude umět vykreslit všechny produkty a ke každému formulář s akcí.

Ochutnávka: V mém Grinderu bys to zapsal cca takto

$products = new Grinder\Grid($model);
$products->setItemsPerPage(50);

$products->addColumn('name');
$products->addColumn('description');
$products->addColumn('image', function ($column) use ($image) {
	return '%basePath%/thumbs' . $column->value->thumb;
});

$products->addFormColumn('count', new Nette\Forms\Controls\TestInput('Počet'));
$products->addSubmit('addToCart', 'Přidat do košíku', array(
	'handler' => function ($action) {
		$count = $action->grid->getActiveRowValue('count');
		$product = $action->grid->currentRecord;
		$action->grid->model->addToCart($product, $count);

		$action->grid->presenter->redirect('this');
	}
));

+ přidání vlastní šablony/rendereru

Nemohl jsem si to odpustit, je to parádní cvičení na ucelování API :) Současná verze tohle neumí, refaktoruju, píšu testy, stay tuned ;)