Jak na odeslání formuláře z komponenty

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

Ahoj, měl bych dotaz: jak z komponenty správně odeslat formulář a zároveň ho ve stejné komponentě odchytnout a zpracovat? Je lepší v komponentách používat Form neboo AppForm?

MartinJanda
Člen | 60
+
0
-

Ještě doplním, že se snažím o odeslání formuláře přes javascript:

$form->addSelect('numberRows', 'Show entries:', $select)->controlPrototype->onchange("submit();");
$form->onSubmit[] = 'changeNumRows';

Chtěl bych to odchytit v metodě changeNumRows v dané komponentě, jen se mi to stále nedaří.

Díky za každou radu.

Panda
Člen | 569
+
0
-
<?php
class Komponenta extends Control
{
	...

	public function metodaKomponenty(...)
	{
		// ...
		$form->onSubmit[] = array($this, 'changeNumRows');
		// ...
	}

	public function changeNumRows(Form $form)
	{
		// ...
	}
}
?>

A používá se AppForm, stejně jako v presenteru.

MartinJanda
Člen | 60
+
0
-

Opravil jsem to na AppForm, ale vrací mi to výjimku:
 InvalidArgumentException - Component with name 'numRowsSelect' does not exist.

Kde ‚numRowsSelect‘ je pojmenování formuláře ve vytváření objektu AppForm, tedy:
 $this->form = new AppForm($this, 'DataGridNumRows');

Díky moc

Editoval MartinJanda (25. 3. 2009 11:39)

jasir
Člen | 746
+
0
-

MartinJanda napsal(a):

InvalidArgumentException - Component with name 'numRowsSelect' does not exist.

Kde ‚numRowsSelect‘ je pojmenování formuláře ve vytváření objektu AppForm, tedy:
 $this->form = new AppForm($this, 'DataGridNumRows');

No mě připadá, že se jmenuje DataGridNumRows a ne numRowsSelect, co myslíš?

MartinJanda
Člen | 60
+
0
-

Aha, promiň, já to pak přejmenoval a vložil to špatně. Správně ten název má být stejně:

InvalidArgumentException - Component with name 'DataGridNumRows' does not exist

Kde ‚DataGridNumRows‘ je pojmenování formuláře ve vytváření objektu AppForm, tedy:
$this->form = new AppForm($this, 'DataGridNumRows');

jasir
Člen | 746
+
0
-

MartinJanda napsal(a):

Aha, promiň, já to pak přejmenoval a vložil to špatně. Správně ten název má být stejně:

InvalidArgumentException - Component with name 'DataGridNumRows' does not exist

Kde ‚DataGridNumRows‘ je pojmenování formuláře ve vytváření objektu AppForm, tedy:
$this->form = new AppForm($this, 'DataGridNumRows');

A kde se vyhazuje ta chyba? Registruješ ten AppForm v komponentě? Kdyžtak sem dej vetší čášt kódu – ten Control (ve kterém registruješ formulář) a to, kde a jak ho registruješ v presenteru.

Editoval jasir (25. 3. 2009 14:09)

MartinJanda
Člen | 60
+
0
-

Díky za snahu o pomoc.

Výjimka nastane, když pošlu data z formuláře zpět na server. Vznikne v Nette/ComponentContainer.php, Line: 153

Komponentu registruju v presenteru v:

public function actionDefault()
{
...
$dataGrid = new DataGrid('operators', $columns, $operations);
$this->addComponent($dataGrid, 'operators');
...
}

App form registruju v renderGrid()

$this->form = new AppForm($this, 'DataGridNumRows');

$this->form->addSelect('numberRows', 'Show entries:', $select)->controlPrototype->onchange("submit();");

$this->form->onSubmit[] = array($this, 'changeNumRows');
$template->numRows = $this->form;

a odchytávat bych to chtěl v metodě v changeNumRows v té komponentě.

Díky

kravčo
Člen | 721
+
0
-

MartinJanda napsal(a):

App form registruju v renderGrid()

AppForm treba vytvoriť & zaregistrovať pred fázou spracovania signálov – napr. v metóde prepareGrid() alebo ešte lepšie pomocou továrničky.

jasir
Člen | 746
+
0
-

Hele, zkus to přepsat na použití továrniček, viz zde (dole kapitola Továrnička na komponenty).
Pak nemusíš řešit kde co registrovat, všechny komponenty v Presenterech i Controlech registruješ v jedné metodě createComponent daného Controlu/Presenteru a když si na ní potřebuješ sáhnout (a nebo nette :), zavoláš jen $this->getComponent('jmenoComponenty').

Edit: Tak Kravco byl rychlejsi :)

Editoval jasir (25. 3. 2009 14:57)

MartinJanda
Člen | 60
+
0
-

Pročtu si to a zkusím. Díky moc.

MartinJanda
Člen | 60
+
0
-

Předěláno do továrničky, ale chyba pořád stejná.

InvalidArgumentException - Component with name 'DataGridNumRows' does not exist

MartinJanda
Člen | 60
+
0
-

OK, jsem debil. Nedošlo mi, že ten formulář nemůžu vytvářet až ve fázi render té komponenty. Já jsem to původně měl v actionGrid(), ale nevěděl jsem, že komponenta má jiné životní fáze než presenter tzn. že toto je nesmysl. Když vytvořím formulář v konstruktoru, už to funguje jak potřebuju.

Díky všem za pomoc

kravčo
Člen | 721
+
0
-

Dôležité je, že pri prepísaní na továrničku ho nepotrebuješ vytvárať v konštruktore – vytvorí sa „sám“ a až v momente, keď bude potrebný (ak nebude potrebný, nevytvorí sa vôbec).

class MyControl extends Control
{
	protected function createComponent($name)
	{
		// kód vytvárajúci komponent ...
	}

	public function __toString()
	{
		// toto volanie vytvára komponent (ak ešte neexistuje)
		$this->template->form = $this->getComponent('DataGridNumRows');
		// ...
	}
}

Teda v prípade, že komponent je príjemcom signálu, ten nemusí byť „natvrdo“ vytvorený (napr. v konštruktore), ale vytvorí sa automaticky (volaním createComponent()), pretože potrebuje prijať signál. Elegantné, lazy, šetrí písanie a hodiny trieskania hlavy o stenu…

Editoval kravco (26. 3. 2009 2:20)