rozny redirect rovnakeho formulara podla render metod

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

Zdravim,

cez tovarnu si vyrabam formular. Presenter ma dve render metody. Kazda render metoda vykresli ten isty formular. Na spracovanie formulara mam callback funkciu, ktora na konci spracovania formulara presmeruje uzivatela na nejaku stranku. Chcem, aby bol po skonceni jednej render metody uzivatel presmerovany na jednu stranku, a pri skonceni druhej render metody presmerovany na inu stranku. Neviem ako to mam spravit. Kam mam dat tie konkretne redirecty? Diky za odpoved

Mikulas Dite
Člen | 756
+
0
-

Jestli to dobře chápu, tak jde o to, že jednen formulář je použitý ve dvou action (tzn. ve dvou šablonách, to je asi ten render) a po odeslání se v tom callbacku (onSuccess[]) má přesměrovat?

Jestli takhle, tak to nejde. Nejsnažší je udělat si předka a potom z něj udělat dvěma továrničkama dvě komponenty. V každé bude nastavený jiný callback. Společná část toho callbacku se dá dát to nějaké samostatné metody a zbyde tam jenom tohle volání a redirect.

stewe
Člen | 20
+
0
-

Mikulas Dite napsal(a):

Jestli to dobře chápu, tak jde o to, že jednen formulář je použitý ve dvou action (tzn. ve dvou šablonách, to je asi ten render) a po odeslání se v tom callbacku (onSuccess[]) má přesměrovat?

Jestli takhle, tak to nejde. Nejsnažší je udělat si předka a potom z něj udělat dvěma továrničkama dvě komponenty. V každé bude nastavený jiný callback. Společná část toho callbacku se dá dát to nějaké samostatné metody a zbyde tam jenom tohle volání a redirect.

jasne, dobry napad.

Neda sa to spravit tak, ze si spravim toho predka a v metode formularSubmitted (aka ta callback funkcia) bude volanie napr. $this->redirect($this->getView()) a getView() bude len metoda predka vracajuca string, ktory bude definovat ten samotny redirect? Nastavit by sa to dalo napr. cez setView() tej triedy, hned ako si ten formuar vyrobim v render metode … Idem na to dobre?

edit, no, netreba tam ani predka … proste trieda s formularom, kde bude este funkcia setView a getView, po vytvoreni formulara nastavim cez set string po redirecte a potom vo formularSubmitted si bude redirect brat string kam sa ma presmerovat cez $this->redirect($this->getView())

Editoval stewe (13. 8. 2011 22:45)

Mikulas Dite
Člen | 756
+
0
-

Zní to funkčně, ale musel bych to asi zkusit používat abych viděl jestli je to dobré. Vždycky mi stačil $this->redirect('this'), resp. $this->redirect(':konkretni:vec:', $id) třeba po vytvoření entity, takže jsem to takhle neřešil, ale tohle by mohlo být ok.

voda
Člen | 561
+
0
-

Podle mě by se stačilo rozhodnout při zpracování formuláře podle Nette\Application\UI\Presenter::getView().

frosty22
Člen | 373
+
0
-

Jako špatný nápad, bych možná i neviděl nějakou FormFactory, jelikož s formuláři, které jsou na více místech se člověk potkává relativně často (např. admin a front), čili by i šlo něco ve smyslu:

<?php
class FormFactory {

private $db;

//Předání závislostí
public function __construct(Db $db, ...)
{
  $this->db = $db;
  ... předání případných dalších závislostí - DI contructor injection ...
}

//Továrna na formulář
public function login(Form $form)
{
  $form->addText("login", "Login:")->setRequired("Musí být vyplněno");
  $form->addPassword("password", "Heslo:")->setRequired("Musí být vyplněno");
  $form->addSubmit("log", "Přihlaš");
  $form->onSuccess[] = array($this, "loginSuccess");
}

//Základ po úspěšném odeslání
public function loginSuccess()
{
  ... zpracování ...
}

... další formuláře ...

}
?>

Zaregistrovat jako službu v contextu, např:

<?php
$container->addService("formFactory", function($c) { return new FormFactory($c->db, ...); })
?>

Následně v presenterech:

<?php
protected createComponentLoginForm($name)
{
  $form = new Form($this, $name);
  $this->context->formFactory->login($form);
  $form->onSuccess[] = array($this, "loginFormSuccess");
}

public function loginFormSuccess($submit)
{
  ... flash zprávy, přesměrování, atd. vše závislé na konkrétním presenteru ...
}

?>

Tímto způsobem by to šlo, pouze bych se nad tím ještě více zamyslel, ale nevidím v tom zrovna problém..

Editoval frosty22 (13. 8. 2011 23:27)

Filip Procházka
Moderator | 4668
+
0
-

A víte, že formulář může mít i více callbacků?

// akce foo
public function actionFoo()
{
	$this['myForm']->onSuccess[] = callback($this, 'GoToTamATam');
}

public function GoToTamATam()
{
	$this->redirect(':Tamten:Presenter:');
}

// akce bar
public function actionBar()
{
	$this['myForm']->onSuccess[] = callback($this, 'GoToJinam');
}

public function GoToJinam()
{
	$this->redirect(':Jiny:Presenter:');
}

// továrnička a zpracování
protected function createComponentMyForm()
{
	$form = new Form();
	$form->addT...
	// ... atd

	$form->addSubmit('send', 'Odeslat');
	$form->onSuccess[] = callback($this, 'MyFormSubmitted');
}

public function MyFormSubmitted(Form $form)
{
	$this->model->save($form->values);
	// prostě klasické zpracování
}
frosty22
Člen | 373
+
0
-

„A víte, že formulář může mít i více callbacků?“

Příklad, který jsem uváděl vychází z toho, že je možné přidat více callbacků, pouze jsem ukazoval případ, kdy je potřeba i formulář ve více presentrech a dávat je všechny do BasePresenteru, není hezké řešení.

Majkl578
Moderator | 1364
+
0
-

frosty22 napsal(a):
a dávat je všechny do BasePresenteru, není hezké řešení

A proč ty formuláře nemáš jako samostatnou třídu? Pak bys nemusel mít ani tu věc pojmenovanou FormFactory.

frosty22
Člen | 373
+
0
-

Ano, tak tento způsob jsem již jednou též aplikoval, kde bylo asi 5 podstatně rozsáhlých formulářů, ale opakovali se na několika místech. Pouze tuto věc FormFactory, jsem použil nyní u jednoho projektu, což je jen intranetová aplikace, která ale má opravdu mnoho formulářů, všechny s pár elementama (v průměru 3) čili to by bylo zbytečně zdržující vytvářet pro každý vlastní objekt, a v tomto řešení též nevidím, žádný problém, tedy v praxi funguje a je to i relativně pohodlné, ale máš pravdu se samostatnými třídami je to jistě hezčí řešení.