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
render
Controlu. - 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 ;)