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

- Mesiah
 - Člen | 240
 
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:
- vytvořit Control, který vytvoř formulář pomocí továrničky. Parametry
	předávat v šabloně, tyto parametry převezme metoda 
renderControlu. - 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
 
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?

- Filip Procházka
 - Moderator | 4668
 
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
 
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
 
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?

- Mesiah
 - Člen | 240
 
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
 
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 ;)