jednodussi formsy
- vlna
- Člen | 34
Ahoj, zacinam s Nette a trochu jsem se zastavil nad formsy (doufam, ze jako
zacatecnik nerejpu).
Uplne se mi nelibi ty if-bloky, ktere je potreba vytvaret, kdyz se zpracovava
form ve stejne metode, zajimalo by me, jestli by se neujal o neco jednodussi
PEAR/Html_QuickForm pristup.
Soucasny stav ( zdroj z: http://zdrojak.root.cz/…roduktivitu/ )
if ($form->isSubmitted()) {
// a jestliže jsou všechny položky vyplněny správně
if ($form->isValid()) {
echo '<h1>Formulář byl odeslán</h1>';
$values = $form->getValues();
Debug::dump($values);
exit;
}
} else { // a jestliže nebyl odeslán, nastavíme výchozí hodnoty
$form->setDefaults(
array( 'promo' => TRUE)
);
}
PEAR/Html_QuickForm pristup
$form = new Html_QuickForm();
$form->setDefaults($oDataObject->toArray());
$form->addElement('text', 'name', 'Jmeno:', array('maxlength' => 255));
# ...
$form->addRule('title', 'chybí nadpis', 'required');
# ...
if ($form->validate()) {
$submitValues = $form->getSubmitValues();
# ...
# napr. ulozim do db
# redirectuju
}
# jinak se form zobrazi
V Pearu proste validate() vrati true jenom pokud byly data odeslany a zaroven jsou validni. To je myslim to, co chceme v 90% osetrovat. setDefaults() je mozne nastavit kdykoliv po zalozeni formu.
- PetrP
- Člen | 587
Form::setDefaults
se nastavuje jen když není odesláno (viz api)
je možné ho nastavovat kdykoliv.
A podle api Form::isValid()
se může použít jen když bylo
zavoláno setDefaults nebo isSubmitted. Hádam že by tedy mělo být
v pořádku toto:
$form->setDefaults(
array( 'promo' => TRUE)
);
if ($form->isValid()) {
echo '<h1>Formulář byl odeslán</h1>';
$values = $form->getValues();
Debug::dump($values);
exit;
}
//EDIT když na to ale koukám dál, tak to v pořádku není ;] musi se použít isSubmitted
Editoval PetrP (19. 5. 2009 22:23)
- _Martin_
- Generous Backer | 679
V tom článku to není zmíněné, ale kód lze zapsat i pomocí obsluh
událostí stisknutí tlačítka. Taková obsluha se zavolá pouze, pokud je
formulář odeslán a je validní. Více v Best
practise: obsluha formulářů, v sekci S obsluhou
událostí. A protože v nových revizích frameworku už jde
setDefaults
volat přímo, kód bude ještě jednodušší.
PetrP napsal(a):
//EDIT když na to ale koukám dál, tak to v pořádku není ;] musi se použít isSubmitted
Jakto? setDefaults
přeci metodu isSubmitted
volá.
- PetrP
- Člen | 587
_Martin_ napsal(a):
Jakto?
setDefaults
přeci metoduisSubmitted
volá.
// V Form::validate()
596: if (!$this->isPopulated) {
597: throw new InvalidStateException('Form was not populated yet. Call method isSubmitted() or setDefaults().');
598: }
// Cesta k nastavení isPopulated je nássledující
Form::isSubmitted()
Form::processHttpRequest() // když není odesláno tak se tady zastaví
Form::loadHttpData()
480: $this->isPopulated = TRUE;
// takže i když je isSubmited zavolaný tak se nenastaví isPopulated a isValid skončí vyjímkou.
// nevim jestli je to bug, nebo požadované chování, protože formy jsem k něčemu většímu ještě nepoužil
- arron
- Člen | 464
Ha, setDefaults()
si samo zjisti
isSubmited()
…hezke:-) ale co kdyz budu chtit zavola
setDefault()
i kdyz bude formular submitnuty?
Ja bych prave radeji vyuzival ten styl udelat vsechno v jedne metode. Prijde mi to vic soudrzny a rozhrani te tridy mi pak prijde prehlednejsi, ale to je ciste nazor.
Priklad na zdrojaku je v podstate nejprimitivnejsim prikladem na pouziti
formularu. Pokrocile metody prace s formulari uz potom pouzivaji Obsluhu
udalosti tak, jak to tu psal _Martin_. Ma to nekolik naprosto zasadnich vyhod.
Hlavni je, ze se vubec nemusis starat o validaci, protoze prislusna udalost se
zavola jenom tehdy, kdyz je formular submitnuty a zaroven je validni. Takze Ti
odpada nejen volani isSubmited
, ale zaroven volani
isValid()
.
Co se prehlednosti tyce, tak u velmi jednoduchych formularu je zpracovani v jedne funkci asi opravdu prehlednejsi (ackoliv ja jsem liny myslet na vsechny ty validate apod.), ale obycejne je po submitu formulare treba udelat pomerne dost operaci, takze nakonec ten zpracovavaci blok celou funkci roztříští, cimz se stane neprehlednou. Pak se ukaze vyhoda oddeleni zpracovani do zvlastni funkce:-)
- vlna
- Člen | 34
arron napsal(a):
Hlavni je, ze se vubec nemusis starat o validaci, protoze prislusna udalost se zavola jenom tehdy, kdyz je formular submitnuty a zaroven je validni. Takze Ti odpada nejen volani
isSubmited
, ale zaroven volaniisValid()
.
Pokud se stara o validaci jenom jedna metoda, tak me to volani nijak
neobtezuje. Naopak jsem rad, kdyz v te funkci vidim takle vyjadreny
lifecyclus.
Pri komplikovanych formularich pravda metoda naroste, ale pokud se to pouziva
v celem projektu jako konvence, orientaci to nesnizi.
Vzdycky je mozne udelat neco jako:
if ($form->isValid())
{
$this->_formIsSubmited($form);
}
ale pokud jsou udalosti zase konvence v Nette, taky si na to asi zvyknu.
Editoval vlna (20. 5. 2009 10:27)
- PetrP
- Člen | 587
arron napsal(a):
Ha,
setDefaults()
si samo zjistiisSubmited()
…hezké:-) ale co když budu chtít zavolásetDefault()
i kdyz bude formular submitnuty?
Na to by si možná mohl použít Form::setValues(), otázka je existuje
situace kdy by si to potřeboval?
Než obsahoval setDefaults tu podmínku na neodeslání tak se tady na fóru
množily problémy.
Když na to ještě znova koukám tak se
$this->isPopulated = TRUE;
nastavuje i v
Form::setValues()
takže asi ten kód co jsem psal pár
příspěvků výše bude fungovat. Nemám chuť to zkoušet ;]
- vlna
- Člen | 34
Jod napsal(a):
a mať v jednom ife dve veci
if($form->isSubmitted() && $form->isValid())
je už príliš zložité? :D
Ne, problem to neni. V puvodnim dotazu jsem myslel, ze je potreba volat setDefaults v else … resp. pouzivat ten pomerne slozity if, coz mi slozite prislo.
Diky vsem za vysvetleni.
- _Martin_
- Generous Backer | 679
PetrP napsal(a):
…
Tak či onak, hláška té výjimky Form was not populated yet. Call
method isSubmitted() or setDefaults(). je trochu zavádějící, neb metoda
isSubmitted
musí být volána v podmínce, na které
isValid
závisí. Každopádně, asi je něco zle, když bychom pro
správný chod aplikace potřebovali znát implementační detaily jednotlivých
metod. Takže bych to uzavřel tím, že (jak říká výjimka)
setDefaults
nás zachrání=)
P.S. Zvláštní, kolik příspěvků se tu stačilo urodit, než jsem prošel API a sesmolil odpověď=D
- arron
- Člen | 464
Tak či onak, hláška té výjimky Form was not populated yet. Call method isSubmitted() or setDefaults(). je trochu zavádějící, neb metoda isSubmitted musí být volána v podmínce, na které isValid závisí.
Uf to je veta:-D Ctu ji uz po x-te a porad na ni nemam zadny poradny nazor;-)
Každopádně, asi je něco zle, když bychom pro správný chod aplikace potřebovali znát implementační detaily jednotlivých metod.
Jako v zasade nemusis, ze jo (ackoliv jsem zjistil, ze to rozhodne neni na skodu;-)). Staci v zasade respektovat pravidla pro pouzivani formularu:-) Ona Te v podstate tahle vyjimka jemne upozorni, ze to co delas odporuje dobrym mravum psani v Nette;-)
Ja napríklad pokiaľ robím v nette používam AppForm a tam neni treba ani jeden taký if :)
Ale jenom tehdy, kdyz pouzivas udalosti:-)
- _Martin_
- Generous Backer | 679
arron napsal(a):
Tak či onak, hláška té výjimky Form was not populated yet. Call method isSubmitted() or setDefaults(). je trochu zavádějící, neb metoda isSubmitted musí být volána v podmínce, na které isValid závisí.
Uf to je veta:-D Ctu ji uz po x-te a porad na ni nemam zadny poradny nazor;-)
Mě to po ránu vždycky chvilku trvá, než se naučím vyjadřovat=D Tu výjimku by si někdo mohl vyložit následovně:
$form->isSubmitted();
if ($form->isValid()) {
// ...
}
což by nefungovalo. Takže asi tak (těžko říct, jestli by někoho
napadlo volat isSubmitted
mimo podmínku, to těžko soudit
z pohledu zaběhlého Nettaře).
- arron
- Člen | 464
_Martin_ napsal(a):
Mě to po ránu vždycky chvilku trvá, než se naučím vyjadřovat=D Tu výjimku by si někdo mohl vyložit následovně:
$form->isSubmitted(); if ($form->isValid()) { // ... }
což by nefungovalo. Takže asi tak (těžko říct, jestli by někoho napadlo volat
isSubmitted
mimo podmínku, to těžko soudit z pohledu zaběhlého Nettaře).
Me zase zhruba do obeda trva, nez se probudim a zacnu chapat;-)
Vidim, kam miris. Ono asi dost zalezi na zkusenosti programatora, protoze
nazev isSubmitted
je dosti vymluvny, nicmene si dovedu predstavit,
ze to nekomu zpusobi zmatek…mozna tu vyjimku nejak preformulovat? Na druhou
stranu jsme sakra probramatori, cili zadne LAMY ne? :-D
- vlna
- Člen | 34
_Martin_ napsal(a):
Tak či onak, hláška té výjimky Form was not populated yet. Call method isSubmitted() or setDefaults(). je trochu zavádějící, neb metoda isSubmitted musí být volána v podmínce, na které isValid závisí.
Co kdyby se hodil boolean do isValid($bForce=false). Standardne by mohla
isValid vracet false
pokud:
formular jeste nebyl odeslany nebo neni validni
//sorry edited krkolomny vyjadreni :-)
Pokud by chtel nekdo validovat jeste pred odeslanim (tezko si predstavit duvod, ale vic by to kopirovalo soucasny princip), dal by isValid(true). Souhlasim, ze by bylo cistsi nemuset vedet, jak kod uvnitr funguje.
Editoval vlna (20. 5. 2009 12:15)
- _Martin_
- Generous Backer | 679
Když nad tím tak přemýšlím, začínám mít pocit, že jsme tady do hloubky rozebrali něco, s čím se nikdy nikdo nesetkal=D
Ono chování je asi správné, formulář svým způsobem nemůže o datech říct „nejsou validní“, když ve skutečnosti „nejsou žádná“. A kdyby někdo neznalý potkal tu výjimku a měl s ní problémy, tak díky tomuhle vláknu ho řešení přímo praští mezi oči=D Takže bych to nechal, jak to je.
P.S. Nejlépe se tomuto problému vyhneme přechodem na Zend Framework =P