Zpracování formuláře – asi to moc nechápu
- Martin Mates
- Člen | 179
Zdravím všechny. Řeším teď můj druhý formulář v nette (první jsem více méně okopíroval z jednoho nette expamlu). Snad se správně zeptám, protože v tom mám ještě dost zmatek.
V nette examplu (nevím honem ve kterém) je presenter Auth a v něm metoda presentLogin, která sestaví formulář. Pak je zde obsluha události loginFormSubmitted, která kontroluje credentials, a pak přesměrovává jinam. To chápu, všechno funguje.
Jenže teď píšu jinou aplikaci. Mám na homepage složitější vyhledávací formulář. Vykresluje ho metoda renderHome. Mám tu zas obsluhu události searchFormSubmitted, která by měla přesměrovat jinam, jenže to nefunguje. Hledal jsem problém v tom, že v renderHome už se nedá přesměrovat. Tak jsem zkusil renderHome změnit na presentHome (pořád nechápu moc rozdíl). Měl jsem pocit, že v present se ještě přesměrovat dá. Přečetl jsem si tedy znovu životní cyklus presenteru a zjistil jsem, že medota present zmizela úplně (huh).
Best practice je dobrá věc, ale je to vytržené z kontextu nette aplikace, stejně tak nette form tutorial. Kam mám tedy dát skládání toho formuláře, aby potom fungovalo přesměrování?
Ještě dodám, že ten nette example o kterém mluvím bude už tak měsíc starý.
EDIT:
<?php
require_once dirname(__FILE__) . '/BasePresenter.php';
class MainPresenter extends BasePresenter {
public function startup() {
parent::startup();
}
public function renderHome() {
...
$form = $this->formHledani();
$this->template->form = $form;
}
private function formHledani() {
...
$form = new Form();
$form->addSelect('kategorie', 'kategorie:', $kategorieForm);
$form->addSelect('znacka', 'značka:', $znackaForm);
$form->addText('rokod', 'od:')
->addRule(Form::NUMERIC, 'Rok musí být číslo.')
->addRule(Form::RANGE, 'Rok musí být od %d do %d', array(1950, 2009));
$form->addText('rokdo', 'do:')
->addRule(Form::NUMERIC, 'Rok musí být číslo.')
->addRule(Form::RANGE, 'Rok musí být od %d do %d', array(1950, 2009));
$form->addSelect('cena', 'cena:', $ceny);
$form->addSelect('palivo', 'palivo:', $palivoForm);
$form->addSubmit('ok', 'Vyhledat');
//$form->onSubmit[] = 'hledaniSubmitted';
if ($form->isSubmitted()) {
$this->hledaniSubmitted($form);
}
return $form;
}
public function hledaniSubmitted(Form $form) {
$this->redirect('Main:nabidka');
}
}
?>
Tohle funguje. To, co je zakomentované ($form->onSubmit[] = ‚hledaniSubmitted‘;) ne.
Editoval Martin Mates (4. 2. 2009 10:33)
- vlki
- Člen | 218
Je tu problem ve dvou vecech.
Zaprve: pokud pouzivas formular v Nette aplikaci (a chces, aby se choval jako
komponenta, ktera muze prijimat signaly), pak ho musis mit jako instanci tridy
AppForm
. Trida Form
je pro pouziti samotneho
formulare, kde by sis zpracovani provadel sam.
Zadruhe: je rozdil mezi actionXYZ
(drive
presentXYZ
) a renderXYZ
. To prvni se vola jeste pred
zpracovanim signalu, coz submitnuti formulare je. Inicializovat formular tedy
musis jeste pred tim zpracovanim signalu.
Zkus tedy neco takoveho:
<?php
public function actionHome() { // zmena cislo jedna
...
$form = $this->formHledani();
$this->template->form = $form;
}
private function formHledani() {
...
$form = new AppForm($this, 'hledani'); // zmena cislo dve
...
?>
- Martin Mates
- Člen | 179
2vlki: Díky, ale to action nějak nefunguje. Když udělám toto:
<?php
public function actionHome() {
$form = $this->formHledani();
$this->template->form = $form;
}
?>
Tak mi to v šablone hlásí, že to nezná proměnnou form. Když ale zkusím toto:
<?php
public function presentHome() {
$form = $this->formHledani();
$this->template->form = $form;
}
?>
Tak to už funguje. problém byl zřejmě v tom appForm.
Editoval Martin Mates (4. 2. 2009 11:44)
- Martin Mates
- Člen | 179
nAS napsal(a):
To že nefunguje actionHome a funguje presentHome je známka, že tam nemáš nejnovější verzi Nette. Měnilo se to v revizi 203. Viz: 1267-rev-203-prejmenovani-v-zivotnim-cyklu-presenteru
Máš pravdu, mám revizi 200 z 24.1.2009. Ten vývoj jde nějak moc rychle :-)
- kravčo
- Člen | 721
Martin Mates napsal(a):
Máš pravdu, mám revizi 200 z 24.1.2009. Ten vývoj jde nějak moc rychle :-)
Ale to je predsa super ;-)
Možno ešte lepším, elegantnejším riešením je použitie továrničky,
ktorá komponenty (aj iné ako AppForm) vytvára lazy/on-demand spôsobom, teda
namiesto action***
implementuješ metódu
createComponent
:
class SomePresenter extends Presenter
{
protected function createComponentMyForm1($name)
{
$myform1 = new AppForm;
$myform1->addText('mytext1', 'My Text #1')
->addRule(Form::FILLED, 'Fill in!');
// ... ostatne prvky formulara
$myform1->addSubmit('mysubmit1', 'My Submit #1')
->onClick[] = array($this, 'eventMyForm1Click');
// pri odoslani spravne vyplneneho formulara
// sa zavola funkcia $this->eventMyForm1Click()
return $myform1;
}
public renderMyForm1()
{
$this->template->form = $this['myform1'];
}
public eventMyForm1Click($submitButton)
{
$myform1 = $this->getComponent('myform1');
// ... nejake akcie po odoslani
$this->redirect('Somewhere:else');
}
}
Editoval kravco (25. 3. 2009 14:51)