form action – podivná filtrace vygenerovaného linku
- maarlin
- Člen | 207
Při nastavení action formuláře:
$form->setAction($this->link('Uzivatel:submitLoginForm'));
NDebug::dump($form->getAction());
Dostanu z laděnky správný výpis:
"/uzivatel/submit-login-form/"
Ovšem když se podívám následně do kódu, je tam toto:
<form action="/?do=smallLoginWindow-submit"...
Tedy URL aktuální strany s jedním parametrem ‚do‘…
Čili odeslání formuláře na zpracovací metodu pak nefunguje… :(
Formulář je generován továrničkou v BasePresenteru:
abstract class BasePresenter extends NPresenter
{
public function createComponentSmallLoginWindow()
{
Editoval maarlin (1. 1. 2010 18:08)
- Ondřej Mirtes
- Člen | 1536
Zdá se mi, že mícháš actiony a handlery (pro signály a zpracování formulářů). Nemůžeš vytvářet link na adresu, kam se odesílá formulář.
- Ondřej Mirtes
- Člen | 1536
Jaký widget? Popiš, co potřebuješ udělat :) Jestli potřebuješ nějakou zpracovávací metodu pro odeslaný formulář, tak v továrničce napiš:
$form->onSubmit[] = array($this, 'formSubmitted');
A metoda má pak vypadat nějak takto:
public function formSubmitted(AppForm $form) {
$values = $form->values;
//...zpracování
$this->flashMessage('Úspěch!');
$this->redirect('this');
}
Editoval Ondřej Mirtes (1. 1. 2010 19:57)
- maarlin
- Člen | 207
Ano, pochopil jsi mě :) Ovšem potíž vzniká pro mě v tom, že ta zpracovávací metoda pro odesílací formulář je v jiném presenteru, než je samotný formulář…
Tudíž logicky nefunguje toto, protože odesílací metoda formSubmitted se hledá v aktuálním presenteru:
$form->onSubmit[] = array($this, 'formSubmitted');
Formulář se generuje v BasePresenteru, aby se mohl zobrazovat na všech stranách webu a zpracovávací metoda zůstává v UzivatelPresenteru.
Dělám to špatně?
- Tomik
- Nette Evangelist | 485
maarlin napsal(a):
Taky mě to napadlo, ovšem to zrovna nezní jako DRY… :)
To opravdu není jiné řešení, než zkopírovat stejnou část kódu na dvě místa?
Nerozumím. Definice formuláře i jeho zpracování bude pouze jednou a to v BasePresenteru. Ostatní presentery to budou pouze vypisovat, přesně podle DRY.
- maarlin
- Člen | 207
V UzivatelPresenteru to zpracování formuláře není jen tak pro srandu
králíkům :)
Existuje samostatný formulář, resp. samostatné view –
//Uzivatel:prihlasitSe , což je výchozí stránka pro přihlášení a
především vypisování chyb, ovšem z praktických důvodů je k dispozici
to malé přihlašovací okno na každé straně. Tudíž formuláře jsou dva,
prakticky stejné, jen jinak vykreslené – malý formulář, co se zobrazuje
na každé straně webu někde po straně a pak formulář pro jediné view, kde
se zobrazí ty chybové hlášky – //Uzivatel:prihlasitSe
- Tomik
- Nette Evangelist | 485
maarlin napsal(a):
V UzivatelPresenteru to zpracování formuláře není jen tak pro srandu králíkům :)
Existuje samostatný formulář, resp. samostatné view – //Uzivatel:prihlasitSe , což je výchozí stránka pro přihlášení a především vypisování chyb, ovšem z praktických důvodů je k dispozici to malé přihlašovací okno na každé straně. Tudíž formuláře jsou dva, prakticky stejné, jen jinak vykreslené – malý formulář, co se zobrazuje na každé straně webu někde po straně a pak formulář pro jediné view, kde se zobrazí ty chybové hlášky – //Uzivatel:prihlasitSe
Pak budeš mít dvě definice formuláře, tomu se nevyhneš, chceš-li mít dva formuláře, ale metoda pro zpracování stačí jedna. Tedy DRY. :)
Jak na to?
V BasePresenteru budeš mít jak továrničku na nějaký
loginForm
, pak metodu doLogin
, která zpracovává
data z loginovacího formuláře. V té továrničce pak nastavíš
$form->onSubmit[] = array($this, 'doLogin');
. Zatím ok. Tento
widget (resp. formulář) pak můžeš vykreslit úplně všude (protože díky
tomu, že je definován v BasePreseteru, je všude dostupný – tedy za
předpokladu, že Tvé Presentery od BasePresenteru dědí – což by
měly :D).
Nyní k tomu konkrétnímu Presenteru, např. tedy
UsersPresenter
, ten bude mít továrničku na ten velký
loginovací formulář, a v ní se bude definovat opět
$form->onSubmit[] = array($this, 'doLogin');
a díky tomu, že
tento presenter dědí od Basu, sdědil i metodu doLogin
, tudíž
pokud budou mít oba formuláře stejné prvky, bude vše fungovat, jak to bylo
zamýšleno. Tedy za předpokladu, že jsem to, co chceš udělat, pochopil
správně. :)
- maarlin
- Člen | 207
Jo, to je fajn, ani mi v tu chvíli (rozuměj v zápalu boje) nedošlo, že ostatní Presentery dědí od BasePresenteru všechny metody… :)
Ale stejně by se mi to víc líbilo, kdyby ta zpracovací metoda byla v UsersPresenteru, jelikož se to týká Users, a nikoliv všech presenterů… ale to už je spíš polemizování nad tím, jak lze chápat logiku frameworku… :)
- Ed
- Člen | 5
Tento topik se asi nejvice blizi memu problelmu s formulari, tak se pokusim
popsat s cim valcim a pokud by nekdo vedel v cem je zakopany pes…
tedy.. nevim jak pridat do action fromulare nejaky GET parametr :)
pro nastaveni akce je treba $form->setAction($url), ale to mi nenastavi
potrebny obzlusny signal (tj chyb do=…). url se snazim ziskat pres
$this->link() ($this je neni presenter ale potomek Control)
pokud v sablone zavolam jen {$form} a nenastavim svou url do url se pouziji jen
perzistentni parametry + signal do… ovsem pokud je zobrazeni formulare
podmineno vyskytem parametru v get, tak se formular nezobrazi jak ma…
konkretni priklad url:
url stranky je: /admin/pages/?activeItem=2&subMod=local&lg=cz
url formulare je:
/admin/pages/?activeItem=2&subMod=local&do=sub_pages-editCategoryForm-submit
vypadne tedy parametr lg, ktery nevim jak pridat. parametr lg je podstatny jen
pro tento formular a tedy davat ho perzistentni mi neprijde vhodne.
predpokaldam ze problem bude asi nekde v tom, ze obsluzna funkce signalu neni namem jak se vsude uvadi v presenteru, ale v primo v objektu formulare a jen nevim jake predat parametry funkci ->link(..) pro vytvoreni signalu …
predem dik za radu
- Ondřej Mirtes
- Člen | 1536
Filozofie formulářů v Nette MVC je taková, že vygenerovanou URL by ses vůbec neměl zabývat, prostě seš od tvorby URL odstíněný a framework ti zařídí, že se ti zavolá taková metoda, jakou potřebuješ. Proto ty čachry, když saháš na setAction, způsobují, že to přestane fungovat – tahle metoda je primárně určená pro práci s Form, tj. bez MVC :) (v MVC se dá použít např. pro přidání anchoru, ale rozhodně ne pro přidávání parametrů).
Ten parametr lg bych předával asi jako hidden pole.
$form->addHidden('lg')->setValue('cz');
- PetrP
- Člen | 587
Taky by se mi hodilo odesílat formulář na url u ze všema parametrama.
Jinak když si chceš upravit action u AppForm tak to musíš udělat až po připojení na presenter, protože po tom připojení si form nastaví action automaticky sám a přepíše ti ho.
Protože se action nastavuje jako třída Link tak mužeš snadno přidat parametry.
protected function createComponentForm($name)
{
$form = new AppForm($this, $name); // ted je pripoji na presenter a nastavi action
$form->action->setParam('sameParam', $this->getParam('sameParam'));
...
}
Editoval PetrP (20. 1. 2010 9:56)
- Ondřej Mirtes
- Člen | 1536
A nefunguje to tak náhodou? Jsem například na
?presenter=Test&action=test&id=5
, odešlu formulář a na
tom samém linku se zase objevím…
- Filip Procházka
- Moderator | 4668
Moje oblíbená rada, aktualizuj framework, mě to taky funguje tak, že to předá celou aktuální url a přidá DO :)
- Ondřej Mirtes
- Člen | 1536
Možná bude problém v tom, že nepředáváte ty GET parametry jako parametry render metod, ale nějak obcházíte framework…
- PetrP
- Člen | 587
Tuhle mi to nefungovalo ani když jsem to měl v renderDefault($neco), byla ± týden stará verze. Poznamenávám si to a hned jak budu mít chvilku tak to vyzkouším a dám vědět jestli to je bug u mě.
Ondřej Mirtes napsal(a):
Možná bude problém v tom, že nepředáváte ty GET parametry jako parametry render metod, ale nějak obcházíte framework…
Jinak to podle mě obcházení FW není, protože já osobně mívám render metody dost vyjímečně, většinu řesím přes supertovárničky (a nebudu sám.)
Editoval PetrP (21. 1. 2010 11:16)
- Ondřej Mirtes
- Člen | 1536
Máš parametry render metod, máš parametry signálů (a parametry signálů komponent) a máš persistentní parametry. Tohle jsou frameworkem podporované cesty a díky nim se nemusíš starat o tvar URL. Co víc potřebuješ? :)