Formulář jako znovupoužitelná komponenta

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

Nějak jsem se úplně ztratil :(

Potřeboval bych nějaký příklad znovupoužitelné komponenty kde bych po zadání {control MyForm} do šablony na stránce vykreslil formulář. Díval jsem se tady po foru, ale používají se tam nějaké callbacky a onSubmit a protože to jsou starší příspěvky, nevím, jestli se od té doby ještě něco nezměnilo.

Zatím mám toto.

V presenteru mám továrničku na komponentu. (Jestli chápu dobře, tak je to tam protot, abych mohl v šabloně tohoto presenteru napsat {control Form} ?)

public function createComponentForm() {
        return new FormControl;
    }

FormControl vypadá takto:

use Nette\Application\UI;

class FormControl extends Nette\Application\UI\Control{

    /** @var UI\Form */
    private $form;

    public function __construct() {
        parent::__construct();
        $form = new UI\Form;
        $form->addText('text','Zadejte text');
        $form->addSubmit('send','odeslat');
        $form->onSuccess[] = $this->formSucceeded;
        $this->addForm = $form;
    }

    public function formSucceeded($form){
        //Toto se po odeslání nestane :(
    }

    public function render(){
        $this->template->setFile(__DIR__ . '/form.latte');
        $this->template->form = $this->form;
        $this->template->render();
    }
}

A form.latte.

{form $form}
	Zadej něco {input text}
	{input send}
{/form}

Nevím jestli je základ dobrej, nebo jestli to je úplně celé špatně, navíc bych tam potřeboval přidat ošetření formuláře a vypsání chyb. Např. formSucceeded() se po odeslání vůbec neprovede. Formulář se vykreslí.

Vycházím z dokumentace kde se v příkladu vrací $form rovnou z metody createComponentSignForm() rovnou z presenteru – tam $form->onSuccess[] = $this->signInFormSucceeded; funguje, zavolá tuto metodu (Takto formuláře už používám).

Ale já bych potřeboval vytvořit komponentu i v jiných presenterech. Prosím o nakopnutí, protože mě trknout asi nepůjde.

David Matějka
Moderator | 6445
+
0
-

ten formular si definuj v tej komponente jako subkomponentu v tovarnicce createComponent*

duke
Člen | 650
+
0
-

Důvod proč ti to nefunguje je, že komponenty, které nejsou připojené ke stromu komponent presenteru (což je v tvém případě komponenta UI\Form), nepřijímají signály.

Asi by stačilo změnit:

$form = new UI\Form;

Za:

$form = new UI\Form($this, 'form');

nebo alternativně za:

$form = new UI\Form;
$this->addComponent($form, 'form');

Ale raději na to jdi přes tovární metodu, jak radí @matej21. Pak se bude volat addComponent() automaticky a navíc v případech, kdy formuláře nebude třeba, se vůbec nebude instanciovat, takže kód bude o něco efektivnější.

Editoval duke (29. 5. 2013 16:28)

thm
Člen | 147
+
0
-

Díky za rady, určitě se to pokusím udělat přes tovární metodu. Jenom nevím úplně přesně jak :) – budu si s tím muset nějak pohrát. Asi to bude vytvořením metody createComponentAddForm() v komponentě FormControl. Nevím jak se to pak bude volat ze šablony presenteru. A vůbec jak to tam s tím „vnořováním“ komponent funguje.

Nicméně, ještě se mrknu na video s Tvrdíkem o komponentách, snad to nějak poberu. Jinak díky moc za tip.

(ale asi to bude hodně užitečný, takhle – jestli to dobře chápu bych si mohl udělat třeba různé verze jedné komponenty)

duke
Člen | 650
+
0
-

Pokud použiješ továrničku createComponentAddForm(), tak z šablony FormControl to bude {control addForm}, případně {form addForm} pro ruční renderování. Nevím, proč bys to chtěl renderovat přímo z šablony presenteru a obcházet FormControl, ale i to by mělo jít, a sice takto: {control formControl-addForm}.