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 | GitHubCMS 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 | GitHubCMS 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

HosipLan
Nette guru
Registrovaný: 1. 6. 2009
Příspěvky: 2637

Re: Jak spravne vytvaret formulare?

Ano máš pravdu, @method annotace se tam výborně hodí :)


Neptej se, jestli se můžeš ptát | Blog | Twitter | GitHubCMS Kdyby

Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítáni

Online

 

#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é 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, ...);
});

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 | GitHubCMS 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 v app/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 | GitHubCMS 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ý

 

#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 | GitHubCMS 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)

 

Zápatí