jeden formulář jako základ pro další

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

Zdravím,
chtěl bych se zeptat, jestli je možné (resp. asi je, ale jak) udělat jeden základní formulář, který se bude nadále využívat s dalšími formuláři. Asi uvedu příklad:
Řekněme, že budu chtít v aplikaci vytvářet různé uživatele. V db mám tabulku uzivatele a dále mám tabulky studenti a ucitele, které mají společné atributy s tab. uzivatele.
Teď mi jde o to, abych nemusel vytvářet dva formuláře pro vytvoření uživatele, které budou mít 80% společného. Moje představa je, že bych vytvořil formulář uzivatele, student a ucitel a pak bych vzdycky spojil form uzivatele+student. Otázka zůstává jak je spojit.
Snad jsem to moc nezamotal. Budu rád za každou radu.
Díky

jtousek
Člen | 951
+
0
-

Zkoušels dědičnost?

lvq
Člen | 47
+
0
-

@vivanatura: ja jsem u nette chvilku, tak nevim, jestli nebudu radit nejakou blbost, ale ja jsem taky pouzil dedicnost. Vytvoril jsem tridu, ktera dedila od NAppForm, tam jsem dal ty spolecne veci a potom jsem vytvoril dalsi tridy (delily z te predchozi vytvorene) a tam jsem pridal uz jen ty specificky policka.

Filip Procházka
Moderator | 4668
+
0
-

uživatel obecně

class UzivatelContainer extends Nette\Forms\FormContainer
{
	protected function attached($obj)
	{
		parent::attached($obj);
		if (!$obj instanceof Nette\Forms\FormContainer) {
			return ;
		}

		$this->addText('name', 'Jmeno');
		$this->addText('name', 'Prijmeni');
	}
}

formulář pro uživatele

protected function createComponentUzivatelForm($name)
{
	$form = new AppForm($this, $name);
	$form['user'] = new UzivatelContainer;
	$form->addSubmit('save', 'Uložit');
}

student

class StudentContainer extends UzivatelContainer
{
	protected function attached($obj)
	{
		parent::attached($obj);
		if (!$obj instanceof Nette\Forms\FormContainer) {
			return ;
		}

		$this->addText('cscs', 'Neco od studenta');
	}
}

formulář pro studenta

protected function createComponentUzivatelForm($name)
{
	$form = new AppForm($this, $name);
	$form['user'] = new StudentContainer;
	$form->addSubmit('save', 'Uložit');
}

učitel

class UcitelContainer extends UzivatelContainer
{
	protected function attached($obj)
	{
		parent::attached($obj);
		if (!$obj instanceof Nette\Forms\FormContainer) {
			return ;
		}

		$this->addText('gfgf', 'Neco od učitele');
	}
}

Tohle je asi tak nejlepší řešení, ještě by jsi si mohl napsat nějaký builder, ale nevím kolik tam toho chceš, takže nevím co je pro tebe jednodužší.

Editoval HosipLan (23. 3. 2011 8:02)

22
Člen | 1478
+
0
-

Neni jednodušší si udělat základní form a potom podle typu usera?

...
if($this->user->isInRole('ucitel') {
$form = $this->getComponent('form');
$form->addText('ucitel', 'Jméno učitele:');
...
}
Filip Procházka
Moderator | 4668
+
0
-

Je to jednodušší, ale tomuhle se říká znovupoužitelnost.

Tharos
Člen | 1030
+
0
-

Já si ale taky trochu rejpnu :), je metoda attached opravdu vhodným místem k inicializaci vlastních polí formuláře? Ta varianta, co jsi napsal, například vygeneruje jiný formulář (respektive s jiným pořadí polí) při připojení k presenteru přes return. Nevidím jedinou výhodu oproti konstruktoru. :)

Filip Procházka
Moderator | 4668
+
0
-

Ono je to v podstatě jedno, ale pokud začneš používat monitory, aby jsi tak řídil sestavené opravdu složitých formulářů, pak to má význam. Napsal jsem to tak spíše ze zvyku :)

Hlavně jsem chtěl poukázat na to, že tohle imho patří do Containerů né do Formuláře :)

Editoval HosipLan (23. 3. 2011 9:25)

Tharos
Člen | 1030
+
0
-

Vím, jak to myslíš a asi se jen rozcházíme na filosofické úrovni. S tím se dá žít :). Mně totiž přijde, že attached je určená především pro případy, kdy připojení nějaké komponenty do stromu komponent znamená nějaké změny i pro její okolí. Úplně klasickým příkladem je pak připojení FileUpload k formuláři, kdy je zapotřebí obalujícímu formuláři nastavit enctype="multipart/form-data".

Inicializaci vlastních polí formuláře mi logicky stále nejvíc sedí v konstruktoru. Nemáš třeba v Kdyby nějaký příklad toho pokročilého použití monitorů? Zní to inspirativně, rád bych se podíval.

Editoval Tharos (23. 3. 2011 10:13)

Jod
Člen | 701
+
0
-

Ja mám nadefinovanú v BaseForm abstraktnú metódu setup, ktorá sa volá z konstruktoru.

Filip Procházka
Moderator | 4668
+
0
-

V Kdyby nic nemám, bohužel. Nejjednodušším příkladem je asi monitorovat Presenter a připojovat pravidla na toggle až v závilosti na presenteru. Kontroloval jsem tak, jestli je formulář už kompletně vytvořený a podle toho připojoval ty toggle (komponenty se, v mém problému, teoreticky mohly připojovat v libovolném pořadí, tak bylo potřeba to ošetřit).

vivanatura
Člen | 3
+
0
-

Díky moc za rady, určitě se to bude hodit do budoucna, ale nakonec jsem tento problém vyřešil tak, že formulář pro vytvoření uživatele budu mít ve dvou krocích.