Jak spravne vytvaret formulare?
#1 před 6 měsíci
- tomasnikl
- Člen

- Registrovaný: 23. 11. 2009
- Příspěvky: 123
Jak spravne vytvaret formulare?
Ahoj,
chci se zeptat, zda je zpusob, ktery pouzivam na vytvareni formularu spravny. Pro kazdy formular na webu mam vlastni tridu umistenou v
app/FrontModule/forms
a jednoduchy formular vypada takto:
<?php
use Nette\Application\UI,
Nette\ComponentModel\IContainer;
class TestForm extends UI\Form
{
public function __construct(IContainer $parent = NULL, $name = NULL)
{
parent::__construct($parent, $name);
$this->addText('name', 'Jméno:');
$this->addSubmit('submit', 'Odeslat');
}
public function testSubmitted($form)
{
echo 'jo jo, formular byl odeslan';
}
}
v Presenteru mam pote uz jen:
protected function createComponentTest($name)
{
$form = new TestForm();
$form->onSuccess[] = callback($form, 'testSubmitted');
return $form;
}
a v sablone:
{control test}
Je takovyto postup spravny? Mit pro kazdy formular vlastni tridu a v spolu s formularem metodu, ktera se provede po odeslani? Nebo je by bylo lepsi formulare vice „seskupovat“. Tim myslim to, ze pokud se formular tyka napr uzivatele (login, registrace, editace uctu apod) tak vsechny tyto 3 formulare dat do jedne tridy?
Je vubec takovyto zpusob vytvareni formularu spravny? Kdyz jsem je vytvarel primo v presenteru a jeden formular mel napr 20 inputu, tak presenter mel najednou 500 radku a clovek se v nem uz dost ztracel.. rozdeleni formularu do samostatnych souboru mi tedy prislo jako dobre reseni a dokonce to je zminovane i v dokumentaci..
Dekuju za tipy a rady
#2 před 6 měsíci
- Tharos
- Nette guru

- Registrovaný: 9. 10. 2009
- Příspěvky: 377
Re: Jak spravne vytvaret formulare?
Z mého pohledu na to jdeš velmi dobře. Já osobně mám vlastní třídy nejen pro formuláře, ale i pro obslužné handlery. To mimo jiné velmi zvyšuje znovupoužitelnost kódu, protože mám například nějaký potvrzovací formulář, kterému jen pokaždé nastavím jinou otázku k potvrzení a jiný handler.
Dávat definice a obsluhy formulářu do Presenteru je z mého pohledu nevhodná praktika, protože to do Presenteru vůbec nepatří a stávají se pak z nich 500+ řádkové třídy, ve kterých se je těžké vůbec vyznat.
Pokud si vyseparuješ samostatné třídy pro definice formulářů (a třeba i pro obsluhu formulářů), je už jenom na Tobě, jak je provážeš dědičností/kompozicí. Uričtě je vhodné neopakovat kód a společné prvky formulářů seskupit do nějaké vlastní třídy. K tomu se dá použít dědičnost (třeba nějaký BaseForm) nebo kompozice. Kompozice je zde flexibilnější, dědičnost asi zase používanější, to už je na Tobě…
#3 před 6 měsíci
- tomasnikl
- Člen

- Registrovaný: 23. 11. 2009
- Příspěvky: 123
Re: Jak spravne vytvaret formulare?
Dekuju za nazor,
mel bych k tomu dotaz. Co myslis tou Kompozici?
…K tomu se dá použít dědičnost (třeba nějaký BaseForm) nebo
kompozice…
Muzes me nasmerovat nekam, kde bych si o tom mohl precist, co je tim
mysleno?
Dekuju
#4 před 6 měsíci
- HosipLan
- Nette guru

- Registrovaný: 1. 6. 2009
- Příspěvky: 2637
Re: Jak spravne vytvaret formulare?
Dědičnost
class PersonForm extends Nette\Application\UI\Form
{
public function __construct()
{
parent::__construct();
$this->addText('name', 'Jméno');
$this->addSubmit('submit', 'Odeslat');
}
}
class PersonWithAddressForm extends PersonForm
{
public function __construct()
{
parent::__construct();
$this->addText('city', 'Město');
$this->addText('street', 'Ulice');
}
}
Kompozice
class PersonContainer extends Nette\Forms\Container
{
public function __construct()
{
parent::__construct();
$this->addText('name', 'Jméno');
$this->addText('surname', 'Příjmení');
}
}
class AddressContainer extends Nette\Forms\Container
{
public function __construct()
{
parent::__construct();
$this->addText('city', 'Město');
$this->addText('street', 'Ulice');
}
}
class PersonWithAddressesForm extends Nette\Application\UI\Form
{
public function __construct()
{
parent::__construct();
$this['user'] = new PersonContainer();
$this['user']['address'] = new AddressContainer();
$this['user']['correspondence'] = new AddressContainer();
$this['user']['billing'] = new AddressContainer();
$this->addSubmit('submit', 'Odeslat');
}
}
Co myslíš, že je lepší? :)
Editoval HosipLan (30. 11. 2011 14:45)
Neptej se, jestli se můžeš ptát | Blog | Twitter | GitHub | CMS Kdyby
Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítáni
Online
#5 před 6 měsíci
- tomasnikl
- Člen

- Registrovaný: 23. 11. 2009
- Příspěvky: 123
Re: Jak spravne vytvaret formulare?
Na prvni pohled se mi libi vic skladani jednotlivych prvku formulare pomoci kompozice, ale urcite to ma nejake nevyhody (vzdycky nejake ALE je :o)).
#6 před 6 měsíci
- Tharos
- Nette guru

- Registrovaný: 9. 10. 2009
- Příspěvky: 377
Re: Jak spravne vytvaret formulare?
@HosipLan: Díky za doplnění :).
@tomasnikl: Kompozice je skoro všude lepší, jen ji řada vývojářů nemá prostě „moc zažitou“ (a i v důsledku toho se dědičnost dost nadužívá). Kompozice zpravidla vede ke znovupoužitelnějšímu kódu, protože nějakou funkcionalitu můžeš zakomponovat kamkoliv. U dědičnosti musíš pak sáhnout k dědění od nějaké třídy, která třeba ale k té rodičovské vůbec nemá vztah „is a“.
Nejlepší je používat dědičnost skutečně jenom pro případy typu
Škoda Octavia extends Auto a pochopitelně také tam, kde Tě
k tomu třeba nějaký framework vyloženě nutí.
Ještě bych k tomu dodal, že i některé návrhové vzory, které tak trochu specifickým způsobem využívají (rozuměj zneužívají) dědičnost, jsou dnes některými programátory brány s rezervou a často je doporučují nahradit řešením založeným na kompozici. Já se řadím mezi ně. :)
Editoval Tharos (30. 11. 2011 15:15)
#7 před 6 měsíci
- pawouk
- Člen

- Registrovaný: 22. 5. 2011
- Příspěvky: 82
Re: Jak spravne vytvaret formulare?
Rozhodně bych formulář nedědil přímo z UI\Form ale z nejakeho BaseForm, i kdyz bude prazdny, casem budes treba chcit neco udelat pro vsechny formulare (to muze byt cokoliv) a muze se to hodit. Ja mam svuj baseForm kde jsem si napsal par metod jako addTime, addDate, addAjaxUpload atd. a celkem se mi tim ulehcila prace. Ale jinak si myslim ze tvuj navrh je zcela vporadku.
#8 před 6 měsíci
- HosipLan
- Nette guru

- Registrovaný: 1. 6. 2009
- Příspěvky: 2637
Re: Jak spravne vytvaret formulare?
@pawouk: Tvé addTime má ovšem zásadní
nevýhodu. Nezavoláš to totiž ve form containeru :)
Správně tedy
Nette\Forms\Container::extensionMethod('addTime', function ($_this, $name, $arg1, ...) {
return $_this[$name] = new TimeControl($arg1, ...);
});
Neptej se, jestli se můžeš ptát | Blog | Twitter | GitHub | CMS Kdyby
Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítáni
Online
#9 před 6 měsíci
- Nox
- Nette guru

- Registrovaný: 16. 10. 2010
- Příspěvky: 319
Re: Jak spravne vytvaret formulare?
Ad HosipLan: BaseForm by se dalo snad využít na @method, aby byla takhle přidaná metoda v našeptávači (snad ty magický metody umí IDE i dědit)
Editoval Nox (1. 12. 2011 8:20)
#10 před 6 měsíci
- pawouk
- Člen

- Registrovaný: 22. 5. 2011
- Příspěvky: 82
Re: Jak spravne vytvaret formulare?
@HosipLan Souhlas, to by asi bylo lepší.
#11 před 6 měsíci
#12 před 6 měsíci
- tomasnikl
- Člen

- Registrovaný: 23. 11. 2009
- Příspěvky: 123
Re: Jak spravne vytvaret formulare?
jeste jeden takovy dotaz, zdrojaky muzu pouzit z meho prvniho prispevku, takze:
<?php
use Nette\Application\UI,
Nette\ComponentModel\IContainer;
class TestForm extends UI\Form
{
public function __construct(IContainer $parent = NULL, $name = NULL)
{
parent::__construct($parent, $name);
$this->addText('name', 'Jméno:');
$this->addSubmit('submit', 'Odeslat');
}
public function testSubmitted(UI\Form $form)
{
if ($form->isSuccess()) {
echo 'jo jo, formular byl odeslan';
}
}
}
me vyhodi chybu:
Call to undefined method FrontModule\TipAddForm::isSuccess().
Jak tento problem prosim opravit?
#13 před 6 měsíci
- bojovyletoun
- Nette guru

- Registrovaný: 6. 10. 2010
- Příspěvky: 672
Re: Jak spravne vytvaret formulare?
Zkus využít laděnku, umí přece zobrazit call stack a hledat v argumentech issuccess. /Pidle mě buď si špatně nastavil handlery (záměna $this a $form), a nebo ti nějaký formulář nedědí od UI\FOrm ale třeba od containeru.
Nette 2dev from github/Netbeans 7.0.1/(Tortoise)git/
Apache 2.4/fcgid/PHP 5.3.9+xdebug+wincache
#14 před 3 měsíci
- joseff
- Člen

- Registrovaný: 11. 9. 2010
- Příspěvky: 163
Re: Jak spravne vytvaret formulare?
HosipLan napsal(a):
@pawouk: Tvé
addTimemá ovšem zásadní nevýhodu. Nezavoláš to totiž ve form containeru :)Správně tedy
Nette\Forms\Container::extensionMethod('addTime', function ($_this, $name, $arg1, ...) { return $_this[$name] = new TimeControl($arg1, ...); });
Zajímalo by mě, kde přesně by jsi toto rozšířšní definoval?
#15 před 3 měsíci
- HosipLan
- Nette guru

- Registrovaný: 1. 6. 2009
- Příspěvky: 2637
Re: Jak spravne vytvaret formulare?
Já bych ho definoval přesně v souboru, ve kterém mám vlastního potomka
Form, takže v momentě, kdy s ním budu pracovat, načtou se mi
vždy i rozšíření. No a nebo v app/boostrap.php
Neptej se, jestli se můžeš ptát | Blog | Twitter | GitHub | CMS Kdyby
Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítáni
Online
#16 před 3 měsíci
- joseff
- Člen

- Registrovaný: 11. 9. 2010
- Příspěvky: 163
Re: Jak spravne vytvaret formulare?
HosipLan napsal(a):
Já bych ho definoval přesně v souboru, ve kterém mám vlastního potomka
Form, takže v momentě, kdy s ním budu pracovat, načtou se mi vždy i rozšíření. No a nebo vapp/boostrap.php
Mě právě přijde ten bootstrap špatně, když máš pak 20 různých rozšíření v různých třídách, tak budeš v kařdém voání includovat 20 souboů ikdyž je nevyužiješ… Lepší mi tedy přijde první možnost, ale kde? To jako v __constructoru?
#17 před 3 měsíci
- HosipLan
- Nette guru

- Registrovaný: 1. 6. 2009
- Příspěvky: 2637
Re: Jak spravne vytvaret formulare?
Ne. Jako vedle třídy.
class Form extends Nette\Application\UI\Form
{
// ...
}
Nette\Forms\Container::extensionMethod('addTime', function ($_this, $name, $arg1, ...) {
return $_this[$name] = new TimeControl($arg1, ...);
});
Neptej se, jestli se můžeš ptát | Blog | Twitter | GitHub | CMS Kdyby
Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítáni
Online
#18 před 3 měsíci
- ruppy
- Nový člen

- Registrovaný: 15. 2. 2012
- Příspěvky: 1
Re: Jak spravne vytvaret formulare?
Dobrý den, vzhledem k tomu že hodně moc oprašuji znalost php a rozhodl
jsem si to „ulehčit“ s Nette :)
tak jsou mi některé věci trošku nejasné. Formuláře už zvladam, vkladat
přez ně a tak, ale když už je mám dělat, chci se to učit rovnou co
nejvhodněji.
Kompozice se mi líbí ale krapet tápu v tom jak to v této podobě oživit.
Formulář mám v samostatném souboru a potřeboval bych poradit jak jej
zavolat z presenteru.
HosipLan napsal(a):
Kompozice
class PersonContainer extends Nette\Forms\Container { public function __construct()
Editoval ruppy (20. 2. 17:06)
#19 před 3 měsíci
- pilec
- Nette guru

- Registrovaný: 12. 11. 2009
- Příspěvky: 495
Re: Jak spravne vytvaret formulare?
S presenteru jednoduše, vytvoříš ho v továrničce takto:
protected function createComponentMyForm()
{
return new TestForm();
}
a pak v šabloně vykreslíš:
{control myForm}
Nejčastější problémy: voláš parent::__construct()? Vymazal jsi cache?
#20 před 3 měsíci
- RDPanek
- Člen

- Registrovaný: 29. 3. 2010
- Příspěvky: 190
Re: Jak spravne vytvaret formulare?
HosipLan napsal(a):
Dědičnost
class PersonForm extends Nette\Application\UI\Form { public function __construct() { parent::__construct(); $this->addText('name', 'Jméno'); $this->addSubmit('submit', 'Odeslat'); } } class PersonWithAddressForm extends PersonForm { public function __construct() { parent::__construct(); $this->addText('city', 'Město'); $this->addText('street', 'Ulice'); } }Kompozice
class PersonContainer extends Nette\Forms\Container { public function __construct() { parent::__construct(); $this->addText('name', 'Jméno'); $this->addText('surname', 'Příjmení'); } } class AddressContainer extends Nette\Forms\Container { public function __construct() { parent::__construct(); $this->addText('city', 'Město'); $this->addText('street', 'Ulice'); } } class PersonWithAddressesForm extends Nette\Application\UI\Form { public function __construct() { parent::__construct(); $this['user'] = new PersonContainer(); $this['user']['address'] = new AddressContainer(); $this['user']['correspondence'] = new AddressContainer(); $this['user']['billing'] = new AddressContainer(); $this->addSubmit('submit', 'Odeslat'); } }Co myslíš, že je lepší? :)
Moc pěkný
{ DeveloperHub | Spaghetti
Code | NetteTestCase | ProjectGit
.
.
#21 před 3 měsíci
- HosipLan
- Nette guru

- Registrovaný: 1. 6. 2009
- Příspěvky: 2637
Re: Jak spravne vytvaret formulare?
Díky, ale je nutné, abys to celé citoval?
Editoval HosipLan (20. 2. 20:17)
Neptej se, jestli se můžeš ptát | Blog | Twitter | GitHub | CMS Kdyby
Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítáni
Online
#22 před 3 měsíci
- Ivorius
- Člen

- Registrovaný: 16. 7. 2005
- Příspěvky: 18
Re: Jak spravne vytvaret formulare?
HosipLanova ukázka by měla jít do FAQ ne?
#23 před 3 měsíci
- MelkorNemesis
- Člen

- Registrovaný: 22. 2. 2009
- Příspěvky: 38
Re: Jak spravne vytvaret formulare?
Urcite bych dal HosipLanuv kod do FAQ, ikdyz ta dedicnost vs kompozice neukazuji stejny vystup, tak ale ukazuji silu kompozice a zanorovani komponent.
#24 před 3 měsíci
- PavelJurasek
- Člen

- Registrovaný: 5. 12. 2011
- Příspěvky: 16
Re: Jak spravne vytvaret formulare?
Rád bych upozornil na to, že pokud chci přiřadit kompozicí container do nějaké Group, musím nejdříve ve formu vytvořit Group a poté ji předat containeru:
$phone = $this->addGroup('phone');
$this['phone'] = new PhoneContainer(…, $phone, …);
který si musí tuto Group nastavit jako současnou
public function __construct(…, \Nette\Forms\ControlGroup $group = null, …) {
if (!is_null($group)) {
$this->setCurrentGroup($group);
}
…
}
Je nějaká možnost, jak to vyřešit?
Nejspíše to bude způsobeno tím, že v containeru nelze zavolat parent::__construct() s parametry a tím pádem se okamžitě nepřipojí k formu. Teda pokud tomu správně rozumím…
Editoval PavelJurasek (26. 2. 12:34)