[2009–09–13] Velký update formulářů

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

Během víkendu došlo k podstatnému vylepšení formulářů.

Začnu trošku neskromně – formuláře v Nette jsou ve srovnání s obdobami v jiných frameworcích v mnoha směrech šikovnější. Přesto s nimi nejsem spokojen a jsem si vědom několika věcí, které potřebují nové nápady: renderer, validace na klientovi a serveru a životní cyklus.

S životním cyklem jsem byl nespokojen skoro dva roky a teprve teď přišel nápad, jak ho vlastně udělat. Cílem byla maximální dynamika a především odstranění známých úskalí. O co konkrétně go:

  • problém „předčasného volání setDefaults“ – https://forum.nette.org/…ni-pozadavku
  • problém volání handlerů událostí v „předčasném“ isSubmitted()
  • neintuitivní tvorba dynamicky se měnících formulářů (např. řada selectboxů vzájemně provázaných)
  • nová možnost volat setValues, getValues, setDefaults, isValid i na FormContainer – https://forum.nette.org/…addcontainer

Nová implementace všechny zmíněné problémy řeší. V tuto chvíli můžete libovolně míchat metody isSubmitted(), setDefault(), přidávat prvky dříve nebo později, odebírat je atd. Implementace zhusta využívá možností komponentového modelu Nette, takže mám pocit, že nový kód je dokonce kratší, čitelnější a snad i srozumitelnější.

Dynamická tvorba je podporována tak, že ihned po přidání nového prvku do formuláře dostane tento svou odeslanou hodnotu, takže je možné volat getValue() a podle hodnoty ovlivnit zbytek formuláře.

FormContainer se pomalu stává plnohodnotným sub-formulářem, protože umožňuje pracovat s hodnotamy (setValues, getValue), nastavovat výchozí hodnoty (setDefaults) a své prvky validovat.

Zpětná kompatibilita

Změny jsou jako obvykle co nejvíce zpětně kompatibilní, ale je tu pár výjimek (a doufám, že spíš drobností):

Odstraněn addTracker(): tracker musí být první prvek přidaný do formuláře. Původně jsem chtěl metodu zachovat a doplnit o kontrolu, zda je prvním prvkem, ale jelikož je dlouhodobě preferovaný postup formuláře pojmenovávat (v konstruktoru), raději jsem smrt metody addTracker urychlil.

Volání setMethod() nejlépe hned po vytvoření objektu. Před změnou metody musí být formulář buď prázdný, nebo neukotvený (tj. AppForm, který není ještě připojen k presenteru, zjišťuje se metodou isAnchored()).

Volat fireEvents(): pokud používáte Form (tohle se netýká AppForm) a řízení pomocí obsluh událostí, tak už neplatí, že se handlery zavolají při prvním volání isSubmitted(). Je potřeba je vyvolat manuálně metodou $form->fireEvents(). Funkční je i původní metoda processHttpRequest() ale vzhledem k jejímu nevhodnému názvu je lepší použít novou fireEvents().

Vlastní controls: Pokud jste si napsali vlastní formulářové prvky, je možné, že budou potřebovat upravit. Pokud implementujete attached(), musíte zavolat i parent::attached(…). Metoda loadHttpData() už nedostává data jako parametr, ale bere si je sama z formuláře ($this->form->httpData), nejlépe se podívejte do zdrojáku. V TextBase už není protected $tmpValue (jak název naznačuje, byla tam vážně jen dočasně).

Testujte

Poprosil bych o co nejdůkladnější otestování.

před 9 lety

PetrP
Člen | 587
+
0
-

Ať nemusím zakládat nové téma, tak jen doplním takové malinké nedůležité typos: špatnéj typ v phpdoc na tomto řádku.

před 9 lety

Jakub Šulák
Člen | 223
+
0
-

Asi tomu úplně nerozumím, jakým způsobem lze nyní nastavit default hodnoty pro formulář?
Pokud použiji:

<?php
protected function createComponentGalleryForm()
{
        $form = new AppForm;
        $form->addText('name', 'Název');
         if (isset($this->idGallery)){
            $g = new Gallery($this->idGallery);
            $form->setDefaults(array('name'=>$g->name, 'type'=>$g->type));
        }
        $form->addSubmit('save', 'Uložit')
             ->onClick[] = array($this,'onSave');
        return $form;
}
?>

Tak mi to vyhodí vyjímku „Form is not anchored and therefore can not determine whether it was submitted.“

Kde v továrničce má tedy být setDefaults?

Díky

před 9 lety

Ondřej Brejla
Člen | 748
+
0
-

A co $form = new AppForm($this, 'galleryForm');, nezabere?

před 9 lety

Jakub Šulák
Člen | 223
+
0
-

ano, zabere! díky.

Ale chci si ujasnit jednu věc. V tom konstruktoru AppForm předávám objekt rodiče komponenty a její označení ve stromu komponent – tedy napojení na presenter… chápu-li dobře?

Při použití jiných komponent však toto není nutné použít. V čem jsou formuláře jiné, že je nutné toto uvádět?
Nebo v tom mám úplný guláš?

před 9 lety

Ondřej Brejla
Člen | 748
+
0
-

Ano. Dle API, rodič a jméno.

Pokud tuto konstrukci neuvedeš, tak se AppForm stane anchored – ukotveným až po return. Když uvedeš rodiče a jméno v konstruktoru, pak je ukotven ihned. Snad to vysvětluji dobře, nové chování jsem zatím netestoval.

Pokud by si chtěl omezit duplicitu „názvu komponenty“, tak to lze udělat také následovně (pokud se něco nezměnilo):

protected function createComponentGalleryForm($name)
{
        $form = new AppForm($this, $name);
        $form->addText('name', 'Název');
         if (isset($this->idGallery)){
            $g = new Gallery($this->idGallery);
            $form->setDefaults(array('name'=>$g->name, 'type'=>$g->type));
        }
        $form->addSubmit('save', 'Uložit')
             ->onClick[] = array($this,'onSave');
}

Editoval Warden (14. 9. 2009 13:11)

před 9 lety

LM
Člen | 206
+
0
-

PetrP napsal(a):

Ať nemusím zakládat nové téma, tak jen doplním takové malinké nedůležité typos: špatnéj typ v phpdoc na tomto řádku.

A ještě https://github.com/…ontainer.php#L35 má být Nette\IComponentContainer.

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

Jakub Šulák napsal(a):

Asi tomu úplně nerozumím, jakým způsobem lze nyní nastavit default hodnoty pro formulář?

Tohle dřív vyhodilo výjimku Component is not attached to 'Presenter'.

Výchozí hodnoty se ihned přiřadí prvkům formuláře – nebo se zahodí, podle toho, zda byl formulář odeslán či nikoliv. Aby to bylo možno zjistit, musí být ukotven, nemůže to být jen nějaký objekt „ve vzduchu“, tedy v lokální proměnné. Proto se buď v konstruktoru nebo přiřazením $this['name'] = $form spojí s presenterem a pak se z něj stane konkrétní formulář, u kterého je možné říct, zda byl odeslán a jaká jsou jeho data.

před 9 lety

Honza Kuchař
Backer | 1648
+
0
-

Na žádnou chybu jsem zatím nenarazil.

Jenom mě tak napadlo. Neobalit form do snippetu? Mělo by to výhodu, např.: u odesílání souborů, kde se nedá validovat na straně klienta. Při onSubmit a onInvalidSubmit by se snippet invalidoval. Zatím to dělám vždy ručně. (kde používám MultipleFileUpload)

MultipleFileUpload už je upravený, aby s touto změnou fungoval.

před 9 lety

Honza Marek
Člen | 1674
+
0
-

Hlásim zpětnou nekompatibilitu. Pokud jsem nastavoval už v továrničce výchozí hodnotu pomocí metody FormControl::setValue u prvku, tak nyní se ta výchozí hodnota nepřehraje odeslanou. Musí se to nastavit pomocí Form::setDefaults.

před 9 lety

Ondřej Mirtes
Člen | 1539
+
0
-

Honza M. napsal(a):

Hlásim zpětnou nekompatibilitu. Pokud jsem nastavoval už v továrničce výchozí hodnotu pomocí metody FormControl::setValue u prvku, tak nyní se ta výchozí hodnota nepřehraje odeslanou. Musí se to nastavit pomocí Form::setDefaults.

To je IMHO očekávané chování, ne?

před 9 lety

Honza Marek
Člen | 1674
+
0
-

Tak částečně. Předtim jsem si byl jistej, že se data z postu do formuláře nahází až po jeho vytvoření. Čili jsem používal občas pro nastavení defaultní hodnoty metodu setValue, protože je to kratší. Teď už to nejde.

před 9 lety

DocX
Člen | 154
+
0
-

A co takhle udělat novou metodu setDefault() na FormControlu?

před 9 lety

Honza Marek
Člen | 1674
+
0
-

To by se mi taky líbilo, ale pojmenoval bych to setDefaultValue :)

před 9 lety

AceUnihoc
Člen | 23
+
0
-
  1. jsem pro přidání setDefaultValue do FormControl
  2. díval jsem se do zdrojáku jak funguje Form::setDefaults a taky používá FormControl::setValue, tak jsem zkoumal proč při použití setDefaults se hodnoty po submitu přepíšou, ale při samotném použití FormControl::setValue ne tzn. jsou na pevno (jak už psal Honza)!

přišel jsem na tohle:

<?php
// simuluje chovaní setDefaults, tzn. hodnota se POSTem přepíše
if (!$form->getForm()->isSubmitted()) {
    $form[$name]->setValue($value);
}

// ale v tomto případě ne, wtf??? ... a vlastně ani ve všech dalších ne, jen v tom prvním (ten je taky použit v setDefaults)
if (!$form->getForm()->isSubmitted()) {
}
$form[$name]->setValue($value);
?>

Nebude lepší ponechat původní chovaní setValue?

Editoval AceUnihoc (20. 9. 2009 15:15)

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

Honza M. napsal(a):

Hlásim zpětnou nekompatibilitu. Pokud jsem nastavoval už v továrničce výchozí hodnotu pomocí metody FormControl::setValue u prvku, tak nyní se ta výchozí hodnota nepřehraje odeslanou. Musí se to nastavit pomocí Form::setDefaults.

setValue není určeno pro nastavování výchozí hodnoty, tudíž se jednalo spíš o nějaký vedlejší efekt.

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

David Grudl napsal(a):

Jakub Šulák napsal(a):

Asi tomu úplně nerozumím, jakým způsobem lze nyní nastavit default hodnoty pro formulář?

Výchozí hodnoty se ihned přiřadí prvkům formuláře – nebo se zahodí, podle toho, zda byl formulář odeslán či nikoliv. Aby to bylo možno zjistit, musí být ukotven…

Aktuálně by setDefaults() mělo fungovat i když formulář ukotven není. Snad to nebude mít žádné vedlejší efekty.

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

setDefaultValue() jsem přidal.

před 9 lety

laada
Člen | 35
+
0
-

Ahoj,
pokud jiz v nejake komponente (someControl extends Control) vytvorim formular jako komponentu createComponentForm() a pouziju napr. v konstruktoru $this['form']->isSubmitted() tak:

<?php
$form = new AppForm;
?>

Vyhodi „Form is not anchored …“

Ovsem v komponente nemohu pouzit:

<?php
$form = new AppForm($this, 'kuk');
?>

To vyhodi „Component ‚kuk‘ already has a parent“.

Delam nekde nejakou botu? V presenteru to zadnou vyjimku nevyhodi.

Jeste dodam ze to patrne souvisi s tim volanim v konstruktoru. Existuje tedy nejaka metoda ktera se v komponente volana automaticky (stejne jako render()), ale je volana drive nez v render fazi?

dik

Editoval laada (25. 9. 2009 17:23)

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

U formuláře, který „existuje jen ve vzduchu“ nelze rozhodnout, jestli byl odeslán. Takže musí být připojen ke komponentě a ta musí být připojená (třeba i přes další komponenty) k presenteru.

V komponentě lze použít $form = new AppForm($this, 'kuk'), pokud ti to nefunguje, nejspíš děláš něco špatně. Zkus sem (příp do nového vlákna) poslat kód.

před 9 lety

redhead
Člen | 1315
+
0
-

óo, sem si ani nevšiml, že jsi odkazoval na moji live validaci.

Jsem poctěn. :)

před 9 lety

Honza Kuchař
Backer | 1648
+
0
-

Čím se dá nahradit metoda isPopulated? (bez ní nefunguje datagrid)

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

Nemůžu ji v datagridu najít, takže neznám kontext. Možná by šlo použít isAnchored()

před 9 lety

Honza Kuchař
Backer | 1648
+
0
-

To se omlouvám. Moje chyba. datagrid.php:922 (SVN:rev51) – metoda regenerateFormControls()

isAnchored() jsem zkoušel, to bylo první co mě napadlo. (pouze jsem nahradil isPopulated() – nepochopil jsem totiž její funkci, tak proto sem kladu otázku, možná hloupou)

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

Aha, na stránce SVN se mi stáhla nějaká hodně stará verze.

Teď jsem ale nepochopil, jestli nahrazení za isAnchored() pomohlo nebo ne?

před 9 lety

Honza Kuchař
Backer | 1648
+
0
-

Bohužel. Žádná chyba se sice neobjevila. (metoda existuje) Ale při změně počtu položek na stránku / filtrování to neudělá nic.

před 9 lety

laada
Člen | 35
+
0
-

David Grudl napsal(a):

U formuláře, který „existuje jen ve vzduchu“ nelze rozhodnout, jestli byl odeslán. Takže musí být připojen ke komponentě a ta musí být připojená (třeba i přes další komponenty) k presenteru.

Je to trochu zamotany, tak to snad nezamotam jeste vic ;)

Cely vtip je v tom ze volam metodu isSubmitted() v konstruktoru komponenty a ten formular v komponente pripojuju jako komponentu.

Jestli jsem dobre to pochopil tak komponenta se k presenteru pripoji ve chvili volani napr. $this[‚name‘] = new Component, ale v tuto chvili (provadeni konstruktoru) dochazi teprve k ‚pripojovani‘, takze isSubmitted() spravne vyhodi vyjimku.

Da se to resit externim volanim nejake metody v komponente po pripojeni, kam presunu isSubmitted(), ale neprijde mi to ulpne cool. Proto jsem se ptal jestli se FW nesnazi volat nejakou metodu v komponente automaticky, jako je tomu treba u render().

priklad kodu:
presenter

<?php
highlevelPresenter extends lowlevelPresenter {
    function actionOne(){
        $component = new myComponent;
        $this['component'] = $component;
    }
}
?>

komponenta

<?php
myComponent extends Control{
    function __construct(){
        .....
        if($this['form']->isSubmitted()){ // vyhodi vyjimku '...not anchored...'
            ...
        }
    }

    function createComponentForm(){
        $form = new AppForm;
        ...
        $this['form'] = $form;

    }
}
?>

>

V komponentě lze použít $form = new AppForm($this, 'kuk'), pokud ti to nefunguje, nejspíš děláš něco špatně. Zkus sem (příp do nového vlákna) poslat kód.

Lze, ale ne pokud ho pripojuju pres createComponent<name>() (viz vyse). Tam projde pouze $form = new AppForm, jinak vyhodi vyjimku ‚…already has parent…‘

před 9 lety

Ondřej Brejla
Člen | 748
+
0
-

A co zkusit toto?

highlevelPresenter extends lowlevelPresenter {
        function actionOne(){
                $component = new myComponent($this, 'myComponent');
                $this['component'] = $component;
        }
}
myComponent extends Control{
        function __construct($parent, $name){
                parent::__construct($parent, $name);

                if($this['form']->isSubmitted()){ // vyhodi vyjimku '...not anchored...'
                        ...
                }
        }

        function createComponentForm($name){
                $form = new AppForm($this, $name);
                ...
        }
}

To taky nejde?

Editoval Warden (29. 9. 2009 10:18)

před 9 lety

laada
Člen | 35
+
0
-

Warden napsal(a):

A co zkusit toto?

highlevelPresenter extends lowlevelPresenter {
        function actionOne(){
                $component = new myComponent($this, 'myComponent');
                $this['component'] = $component;
        }
}
myComponent extends Control{
        function __construct($parent, $name){
                parent::__construct($parent, $name);

                if($this['form']->isSubmitted()){ // vyhodi vyjimku '...not anchored...'
                        ...
                }
        }

        function createComponentForm($name){
                $form = new AppForm($this, $name);
                ...
        }
}

To taky nejde?

ted nevim na kterou cast si reagoval nicmene je to stale rozbity ;). Ve vsech moznych kombinacich to vyhodi ‚…already has a parent…‘. Pri volani parent::__construct($parent, $name); se problem posune o level vys tedy ‚myComponent … has a parent‘.

Zatim to obchazim extra volanim metody po pripojeni komponenty k presenteru.

před 9 lety

Ondřej Brejla
Člen | 748
+
0
-

Ještě jsem přehlédl…když místo $this['component'] = $component; napíšeš $this['myComponent'] = $component; respektive spíš celý ten řádek s $this['component'] = $component; zakomentuješ?

Editoval Warden (29. 9. 2009 10:56)

před 9 lety

laada
Člen | 35
+
0
-

Warden napsal(a):

Ještě jsem přehlédl…když místo $this['component'] = $component; napíšeš $this['myComponent'] = $component; respektive spíš celý ten řádek s $this['component'] = $component; zakomentuješ?

Zda se ze tohle klaplo. Budu to jeste testit.

Dik

před 9 lety

Ondřej Brejla
Člen | 748
+
0
-

To by mělo fungovat ;-) Všechno v podstatě zařadíš do stromu komponent v okamžiku vytvoření, tedy ještě před další prací s danou komponentou, musí to tedy fungovat…;-)

Editoval Warden (29. 9. 2009 11:37)

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

laada napsal(a):

Cely vtip je v tom ze volam metodu isSubmitted() v konstruktoru komponenty a ten formular v komponente pripojuju jako komponentu.

Jestli jsem dobre to pochopil tak komponenta se k presenteru pripoji ve chvili volani napr. $this[‚name‘] = new Component,

Přesněji řečeno, připojí se takto k rodičovské komponentě, která nutně nemusí být presenter a nemusí být ani sama k presenteru připojena.

ale v tuto chvili (provadeni konstruktoru) dochazi teprve k ‚pripojovani‘, takze isSubmitted() spravne vyhodi vyjimku.

Lze to řešit tak, že se konstruktoru předají parametry $parent, $name a připojení se provede už v něm, ještě před vytvořením formuláře. Nicméně stále je potřeba otestovat, zda presenter existuje (rodič > presenter).

Da se to resit externim volanim nejake metody v komponente po pripojeni, kam presunu isSubmitted(), ale neprijde mi to ulpne cool. Proto jsem se ptal jestli se FW nesnazi volat nejakou metodu v komponente automaticky, jako je tomu treba u render().

Ano, od toho jsou metody (nebo řekněme události) attached(), detached() a monitor(). Viz třeba zdrojový kód třídy AppForm, která si začne v konstruktoru monitorovat, kdy se připojí v presenteru a poté načte (v metodě attached) odeslaná data.

Lze, ale ne pokud ho pripojuju pres createComponent<name>() (viz vyse). Tam projde pouze $form = new AppForm, jinak vyhodi vyjimku ‚…already has parent…‘

Lze tam psát samozřejmě obojí, podívej se dobře do backtrace výjimky, ta chyba ti vzniká jinde, při duplicitním přiřazení $this['name'] = $form.

před 9 lety

laada
Člen | 35
+
0
-

vse vyresilo prirazeni komponenty v jejim konstruktoru, diky.

před 9 lety

Honza Kuchař
Backer | 1648
+
0
-

Ahoj, jenom se připomínám s tím datagridem. Napadá někoho něco?

před 9 lety

romansklenar
Člen | 657
+
0
-

Díval jsem se na to a žádné řešení jsem nenašel :( Nesouvisí to jen s isPopulated(), ve formulářích se změnilo něco, kvůli čemu celkově DataGrid nefunguje…

Editoval romansklenar (2. 10. 2009 11:54)

před 9 lety

romansklenar
Člen | 657
+
0
-

Rozdíly v chování, které jsem našel jsou tyto:

  1. Dump zde:

Starší verze Nette:

Debug::dump($form->values);
array(4) {
   "operations" => NULL
   "page" => string(0) ""
   "items" => string(1) "5"
   "filters" => array(6) {
      "position" => string(0) ""
      "phone" => string(0) ""
      "addressLine1" => string(0) ""
      "city" => string(0) ""
      "country" => NULL
      "postalCode" => string(0) ""
   }
}

Vývojová verze Nette:

Debug::dump($form->values);
array(4) {
   "operations" => NULL
   "page" => string(1) "1"
   "items" => int(15)
   "filters" => array(6) {
      "position" => string(0) ""
      "phone" => string(0) ""
      "addressLine1" => string(0) ""
      "city" => string(0) ""
      "country" => NULL
      "postalCode" => string(0) ""
   }
}

Debug::dump($form->httpData);
array(3) {
   "itemsSubmit" => string(6) "Change"
   "filters" => array(6) {
      "position" => string(0) ""
      "phone" => string(0) ""
      "addressLine1" => string(0) ""
      "city" => string(0) ""
      "country" => string(0) ""
      "postalCode" => string(0) ""
   }
   "items" => string(1) "5"
}
  1. Dump proměnné $paramssaveState:

Starší verze Nette:

array(4) {
   "page" => NULL
   "order" => NULL
   "filters" => NULL
   "itemsPerPage" => int(5)
}

Vývojová verze Nette:

array(4) {
   "page" => NULL
   "order" => NULL
   "filters" => NULL
   "itemsPerPage" => NULL
}

Nasimulováno na demu na 2. datagridu při změně počtu položek zobrazovaných na stránku z defaultních 15 na 5. Stejně se to chová například při změně filtru.

před 9 lety

Honza Kuchař
Backer | 1648
+
0
-

To je opravdu divné chování. Ale nevšiml jsem si, že by formuláře někde jinde nefungovali.

// EDIT: Udělal jsem takový mix – Nette 0.9.2-dev + Staré formuláře. Chodí to suprově. http://projekty.mujserver.net/…OldForms.zip

Editoval honzakuchar (3. 10. 2009 11:46)

před 9 lety

Honza Marek
Člen | 1674
+
0
-

David Grudl napsal(a):

setDefaultValue() jsem přidal.

Nemohl by některý vývojář přidat ještě getter, aby bylo možné použít magic property?

$formControl->defaultValue = "výchozí hodnota";

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

romansklenar napsal(a):
Nasimulováno na demu na 2. datagridu při změně počtu položek zobrazovaných na stránku z defaultních 15 na 5. Stejně se to chová například při změně filtru.

Mohl bys mi prosím oba kódy poslat emailem?

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

Honza M. napsal(a):

Nemohl by některý vývojář přidat ještě getter, aby bylo možné použít magic property?

Getter přidat nelze, default value je write-only. Takže leda povolit write-only magic property, což se mi moc nechce…

před 9 lety

Smitka
Člen | 2
+
0
-

honzakuchar: děkuji za mix, dočasně mi to vytrhlo trn z paty

před 9 lety

Honza Kuchař
Backer | 1648
+
0
-

Smitka napsal(a):

honzakuchar: děkuji za mix, dočasně mi to vytrhlo trn z paty

Není za co. Doteď to mám nasazeno, ale přece jenom nefunguje to dokonale. Nefunguje ukládání stavu datagridu do session. Ale už se mi to nechce zkoumat proč. (zdá se, že datagrid už bude brzo opraven)

před 9 lety

romansklenar
Člen | 657
+
0
-

David Grudl napsal(a):

romansklenar napsal(a):
Nasimulováno na demu na 2. datagridu při změně počtu položek zobrazovaných na stránku z defaultních 15 na 5. Stejně se to chová například při změně filtru.

Mohl bys mi prosím oba kódy poslat emailem?

Chyba byla v nastavování hodnot formulářovým prvkům – setValue() se muselo nahradit setDefaultValue() a na Containerech nastavovat přes setDefaults().

před 9 lety

Jose
Člen | 1
+
0
-

Mám problém se zpětnou kompatibilou u 0.8 na Nette Framework 0.9.1 (revision dc607f0 released on 2009–09–18), nefunguje navázání HTML elementu do „labelu“ formuláře

<?php
$label =Html::el()->setHtml( $columnLabel.'<img src="'.Environment::getVariable('baseUri').$item['local'].'.png">' );
$this -> addText( '0_label', $label ) ;
?>
$form['0_label'] ---  "caption" => <span>object</span>(Html) (4) <code>{
      "name" <span>private</span> => <span>string</span>(0) ""
      "isEmpty" <span>private</span> => <span>bool</span>(FALSE)
      "attrs" => <span>array</span>(0)
      "children" <span>protected</span> => <span>array</span>(1) <code>{
         0 => <span>string</span>(51) "&lt;img src="/caaf/_public/upload/flags/en.png"&gt;"
      }</code>

   }</code>

<th><label for="frm-0_label"></label></th>
<td><input type="text" class="text" name="0_label" id="frm-0_label" value="" /></td>

Text funguje:

<?php
$this -> addText( '0_label', 'AAAAA') ;
?>
$form['0_label'] --- "caption" => <span>string</span>(3) "AAAAA"
<th><label for="frm-0_label">AAAAA</label></th>
<td><input type="text" class="text" name="0_label" id="frm-0_label" value="" /></td>

Vyřešeno( obejito ) přes

$this['0_label']->setOption('description',$label);

Editoval Jose (30. 10. 2009 10:20)

před 9 lety

edke
Člen | 198
+
0
-

Ako je mozne v poslednej revizii vypnut JS validaciu a cely clientScript() ? Predtym fungovalo toto:

$form->render('null');
$form->getrenderer->clientScript->validateScript= ' ';

před 9 lety

David Grudl
Nette Core | 6770
+
0
-

To je takový podivný trik, mělo by fungovat $form->renderer->clientScript = NULL

před 9 lety

edke
Člen | 198
+
0
-

David Grudl wrote:

To je takový podivný trik, mělo by fungovat $form->renderer->clientScript = NULL

A aj funguje :)

před 8 lety

Oggy
Člen | 314
+
0
-

Dynamická tvorba je podporována tak, že ihned po přidání nového prvku do formuláře dostane tento svou odeslanou hodnotu, takže je možné volat getValue() a podle hodnoty ovlivnit zbytek formuláře.

Můžu se zeptat jaká dynamická tvorba je tu myšlena? Je někde nějak zdokumentováno jak lze např. dynamicky vytvářet další položky atd. Na fóru je toho „spoustu“ ale většinou vlastně jen dotazů.
děkuju