Zpracování formuláře – asi to moc nechápu

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

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
+
0
-

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
+
0
-

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)

nAS
Člen | 277
+
0
-

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

Martin Mates
Člen | 179
+
0
-

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
+
0
-

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)