Flash zprávy a vícenásobné použití formulářů
- Vojtěch Dobeš
- Gold Partner | 1316
Úplně je nejlepší je dědit od čehokoliv, ale UI reakci (redirect,
flashMessage…) řešit na odpovídající úrovni. Tzn. ve svém formuláři
si přidat tzv. událost (public $onSomething
), do ní
v továrničce v presenteru zaregistrovat nějakou metodu presenteru, a v ní
volat flashMessage, kde je tato metoda normálně dostupná.
Případně ano, lze dědit od UI\Control
, který potřebnými
metodami disponuje taky.
- vvoody
- Člen | 910
Takze zhruba takto?
Davidova slzbotovarnicka
class CreateOrEditUserFormFactory extends Nette\Object
{
private $db;
public function __construct(Nette\Database\Connection $db)
{
$this->db = $db;
}
public function createForm($userId)
{
return new CreateOrEditUserForm($this->db);
}
}
Komponenta s formularom
class CreateOrEditUserForm extends Nette\Application\UI\Control
{
private $db;
public function __construct(Nette\Database\Connection $db)
{
$this->db = $db;
}
public function createComponentForm($userId)
{
$form = new Form;
...
$form->addHidden('userId', $userId);
$form->addSubmit('send', 'Update Account');
$form->addSubmit('sendandview', 'Update Account and continue editing')
->onClick[] = $this->process;
return $form;
}
public function process($button)
{
...
}
public function render(){
$template = $this->template;
$template->setFile(dirname(__FILE__) . '/CreateOrEditUserForm.latte');
$template->render();
}
}
CreateOrEditUserForm.latte
{control Form}
alebo
{form Form}
...
{/form}
Edit: to je asi volovia, teraz sa z toho vytratila ta znovupouzitelnost
Editoval vvoody (9. 9. 2012 22:15)
- 22
- Člen | 1478
a toto je co?
...
public function createComponentForm($userId)
...
@vojtech.dobes: Jinak asi bych so vytvořil potomky Form\Container a v UI\Control to seskládal nebo klasicky podědit UI\Form do nějakeho BaseForm a pak jen v případě potřeby manuálního renderu to obalit UI\Control.
Editoval 22 (9. 9. 2012 23:05)
- Vojtěch Dobeš
- Gold Partner | 1316
Pozor, je to hrozně témat, co se míchá dohromady :). Dědit od
Nette\Forms\Form
nebo Nette\Forms\Container
nepomůže, protože ty nemají metody
flashMessage
atd., což je issue tohoto vlákna.
Editoval vojtech.dobes (9. 9. 2012 23:07)
- 22
- Člen | 1478
@vojtěch.dobeš: já ale navrhoval dědit od
UI\Form
, ten má getPresenter()
a pak se už
k flashMessage dostaneš nebo pro manuál render, vytvořit
UI\Control
obálku, ať už jsou to Form\Containery
nebo extendnuté UI\Form.
Form\Container
mi přijde
vhodný kvůli znovupoužitelnosti a je jedno, jestli to ve finále seskládš v
UI\Form
nebo UI\Control
extendované třídě,
záleží na způsobu renderu už jen potom.
- Pan Dobrman
- Člen | 45
Mě napadlo něco takového.
FormFactory:
<?php
use Nette\Application\UI\Form
class FormFactory
{
/** @var Model\Model */
private $model;
public function createForm()
{
$form = new Form;
$form->addText('text');
$form->addSubmit('submit');
//žádný onSuccess
return $form;
}
public function process(Form $form)
{
$this->model->save($form); //v případě neúspěchu vyhodí výjimku
}
}
Presenter:
<?php
use Nette\Application\UI\Form
class FormPresenter extends BasePresenter
{
/** @var FormFactory */
private $formFactory;
public function actionForm()
{
$form = $this->formFactory->createForm();
$form->onSuccess[] = callback($this, 'processForm');
$this->addComponent($form, 'form');
}
public function processForm(Form $form)
{
try
{
$this->formFactory->process($form);
$this->flashMessage('Formulář byl odeslán', 'success');
}
catch(\Exception $e)
{
$this->flashMessage('Formulář se nepodařilo se odeslat', 'error');
}
}
public function injectFormFactory(FormFactory $formFactory)
{
$this->formFactory = $formFactory;
}
}
Je to možné použít?
Editoval Pan Dobrman (15. 9. 2012 15:52)
- Patrik Votoček
- Člen | 2221
Pan Dobrman napsal(a):
Mě napadlo něco takového.
Já bych na to šel asi takhle:
FormFactory:
use Nette\Application\UI\Form
class FormFactory extends \Nette\Object
{
/** @var Model\Model */
private $model;
public function createForm()
{
$form = new Form;
$form->addText('text');
$form->addSubmit('submit');
$from->onSuccess[] = callback($this, 'process');
return $form;
}
public function process(Form $form)
{
try {
$this->model->save($form); //v případě neúspěchu vyhodí výjimku
} catch (ModelException $e) {
$this->addError($e->getMessage());
}
}
}
Presenter:
<?php
use Nette\Application\UI\Form
class FormPresenter extends BasePresenter
{
/** @var FormFactory */
private $formFactory;
public function createComponentMyForm()
{
$presenter = $this;
$form = $this->formFactory->createForm();
$form->onSuccess[] = function($form) {
if ($form->valid) {
$presenter->flashMessage('Fuk Yea!');
$presenter->redirect('this');
}
}
return $form;
}
public function injectFormFactory(FormFactory $formFactory)
{
$this->formFactory = $formFactory;
}
}
- Pan Dobrman
- Člen | 45
Téma bylo o odesílání flashMessage, takže proto jsem odchytával výjimky až v presenteru. V továrničce je lze odesílat (alespoň co vím) jen pomocí dědění například od Nette\Application\UI\Control. V tom mi mé řešení přijde hezčí, ale budu rád opraven, pokud se mýlím.
Editoval Pan Dobrman (15. 9. 2012 17:33)