Best practice: obsluha formulářů
- David Grudl
- Nette Core | 8218
Životní cyklus formuláře se skládá:
- z jeho definice
- nastavení výchozích hodnot
- vykreslení uživateli
- validace
- získání dat
Existují v podstatě dva způsoby, jak cyklus implementovat: s využitím událostí nebo bez.
Bez obsluhy událostí
Doporučuji tento vzor:
// definice
$form = new Form();
$form->addText('name', 'Your name:');
$form->addSubmit('ok', 'Send');
$form->addSubmit('cancel', 'Cancel');
// byl odeslán?
if ($form->isSubmitted()) {
if ($form['cancel']->isSubmittedBy()) {
// process cancelled
redirect(...);
}
if ($form['ok']->isSubmittedBy() && $form->isValid()) {
// submitted and valid
save($form->getValues());
redirect(...);
}
} else {
// první zobrazení, nastavíme výchozí hodnoty
$form->setDefaults($defaults);
}
Tento způsob je vhodný pro použití v jednoduchých webových stránkách, kde se nevyužívá MVC.
S obsluhou událostí
Doporučuji tento vzor:
// definice
$form = new Form();
$form->addText('name', 'Your name:');
$form->addSubmit('ok', 'Send')
->onClick[] = 'OkClicked'; // nebo 'OkClickHandler'
$form->addSubmit('cancel', 'Cancel')
->setValidationScope(FALSE)
->onClick[] = 'CancelClicked'; // nebo 'CancelClickHandler'
// alternativa:
$form->onSubmit[] = 'FormSubmitted'; // nebo 'FormSubmitHandler'
if (!$form->isSubmitted()) {
// první zobrazení, nastavíme výchozí hodnoty
$form->setDefaults($defaults);
}
// zavolej obslužné handlery, pokud je formulář odeslán
$form->fireEvents();
// obslužné handlery:
function OkClicked(SubmitButton $button)
{
// submitted and valid
save($form->getValues());
redirect(...);
}
function CancelClicked(SubmitButton $button)
{
// process cancelled
redirect(...);
}
function FormSubmitted(Form $form)
{
// manual processing
if ($form['cancel']->isSubmittedBy()) ...
}
Tento způsob je vhodný pro použití v MVC implementacích jako Nette\Application.
Obslužný handler pro onSubmit lze použít v případě, kdy formulář nemá žádné nebo právě jedno tlačítko. V odstatních situacích bývá vhodnější využít handler onClick přímo na tlačítku.
Handler onClick se volá před handlerem onSubmit. Handlery se volají
pouze v případě, že je odeslání validní. Pokud
odeslání validní není, volají se handlery pro události
onInvalidClick
a onInvalidSubmit
. Uvnitř metody
OkClicked
tedy není nutné ověřovat validitu formuláře. Naopak
metoda FormSubmitted
může být zavolána i v případě
nevalidního formuláře, byl-li odeslán tlačítkem Cancel
.
V případě, že formulář nebyl odeslán tlačítkem (například byl
odeslán přes JavaScript), nebo se tak tváří kvůli chybě v Internet
Exploreru, bude Nette za odesílací tlačítko považovat první tlačítko
formuláře. Tudíž obsluha přes události onClick
je
spolehlivá.
Obslužné handlery se vyvolají při prvním volání metody
fireEvents()
, při použití uvnitř Nette\Application vyvolání
zajistí samotný presenter.
Přesměrování
Po odeslání POST formuláře a zpracování dat vždy přesměrujte na další stránku (v presenteru metodou redirect). Zamezíte tak situaci, že uživatel stisknutím tlačítka F5 nebo procházením historie v prohlížeči omylem odešle formulář znovu.
Callback
V uvedených ukázkách jsou jako handlery použity funkce, samozřejmě
pokud píšete objektový kód, je vhodnější volat metody (zejména ve
spojení s Nette\Application). Handler je nutno zapsat jako PHP typ callback, takže v případě
použití v presenteru například jako
$form->onSubmit[] = array($this, 'FormSubmitted')
.
- Vitek Jezek
- hledá kolegy | 285
znesvetim tento Best practice otazkou – mohu nejak v obsluznych handlerech brat promene, ktere jsou v kodu pred zavolanim obsluznych handleru (tedy ve funkci, ktera tvori form/vola handlery)?
Zatim to obchazim pres persistentni parametry, ale urcite by to slo vice Nette (cti [vice ciste / elegantne / lepe]) : )- David Grudl
- Nette Core | 8218
Pokud obslužné handlery představují metody objektu, tak můžeš používat třeba proměnné objektu.