setRequired prvku nastavený addConditionOn() není k dispozici v property $required v Latte šabloně

m.brecher
Generous Backer | 758
+
0
-

Ahoj,

narazil jsem na tento problém (bug) v Nette formulářích. Potřebuji aby byl podmíněně required prvek ‘name’, je-li v jiném prvku ‘type’ selectu vybrána konkrétní hodnota ‘IndividualEntity’. Použil jsem metodu addConditionOn() a formulář validuje správně – pokud je vybrána hodnota ‘IndividualEntity’, je prvek ‘name’ required, ale ve vykreslovací šabloně Latte je v property $required prvku ‘name’ hodnota false. Tato property řídí vykreslování červené hvězdičky, která indikuje, že je prvek required. Důsledkem je, že hvězdička která by se vykreslit měla se nevykresluje. Prvek validuje správně, ale červená hvězdička se vykresluje nesprávně.

Od pohledu bych řekl, že je to bug Nette formulářů, ale třeba jsem něco přehlédl, nebo udělal nesprávně. Proto bych rád získal z komunity zkušenosti jak ostatní řeší tento problém.

Kód (zjednodušený):

$form = new Form;
$form->addSelect('type', 'Type', $typeItems)
    ->setRequired('Vyber typ');

$form->addText('name', 'Jméno')
    ->addConditionOn($form['type'], $form::Equal, 'IndividualEntity')
    ->setRequired('Doplň jméno');        // $input->required  false

$form->addText('surname', 'Jméno')
    ->setRequired('Doplň jméno');        // $input->required  true

Šablona Latte (zjednodušený kód)


{foreach $form->getControls() as $input}

    <tr n:class="$input->required ? 'required'">  {* false, má být true *}

        {* ..... *}

    </tr>

{/foreach}

Prvky, které mají setRequired() nastaveno přímo bez podmínky addConditionOn() mají hodnotu $input->required správnou.

Díky za jakékoliv komentáře.

Pepino
Člen | 249
+
+1
-

Pokud je prvek závislý na hodnotě jiného prvku tak není přeci required.

Tohle by si měl řešit spíše nějakým dodatečným javascriptem, který ti tu hvězdičku dynamicky doplní na základě hodnoty v závislém prvku.

ZahorskyJan
Člen | 55
+
0
-

Řešení je dopsat si vlastní javascript, protože i ta validace se řeší v javascriptu. Nette si dává do data-atributu ty pravidla a parsuje to JS a validuje JS. Kdyby to měl dělat backend a latte šablona mít co tam čekáš, tak by každou změnu musel poslat zpět na server. To už ale je, dle mého názoru, trochu mimo práci frameworku.

Stejně jako není vyřešené, jestli má jít do $values po odeslání hodnota těch prvků, které byly podle addConditionOn skryté přes toggle. Někdo řekne, že určitě nemají a někdo zas, že záleží na použití. Takže to Nette neřeší a každý si musí dořešit podle svého. I když se přiznám, že by bylo super, kdyby to formuláři šlo nastavit, jak se to má chovat a nemusel si člověk psát svoje vyhodnocení těch podmínek.

m.brecher
Generous Backer | 758
+
0
-

@Pepino

Pokud je prvek závislý na hodnotě jiného prvku tak není přeci required.

Jeden prvek je required nebo není required v závislosti na vybrané hodnotě jiného prvku, takhle se to docela často v praxi vyskytuje.

m.brecher
Generous Backer | 758
+
0
-

@ZahorskyJan

Řešení je dopsat si vlastní javascript, protože i ta validace se řeší v javascriptu.

Nette formuláře mají hlavní validaci ne serveru a javascriptová validace jenom zrychluje odezvu a nemá z hlediska bezpečnosti žádný význam, protože útočník javascript obejde velmi snadno. Nastavení hvězdičky javascriptem nevyřeší případ, kdy si uživatel vypne javascript a Nette potom validuje na serveru.

Marek Bartoš
Nette Blogger | 1173
+
0
-

Required definované na inputu říká jen, zda je input required, bezpodmínečně.
Pokud je prvek required v závislosti na dalších podmínkách, tak je třeba to vyčíst z těch podmínek.
Nette by nejspíš mohlo poskytnout funkci, která z odeslaných hodnot (nebo výchozích hodnot, pokud formulář nebyl odeslán) vyčte, zda je prvek required v aktuálním stavu, s ohledem na podmínky. Aby se mohla hvězdička vypsat správně i při renderu html formuláře na serveru.
A v js mít live validaci, která umožní při změně v závislých podmínkách přidat či odebrat atribut required (nebo custom css třídu, …)
Je to však nová feature, nikoli bug v té stávající.

Editoval Marek Bartoš (28. 12. 2023 16:09)

m.brecher
Generous Backer | 758
+
0
-

@MarekBartoš

Je to však nová feature, nikoli bug v té stávající

Property $required je součástí veřejného api a měla by vyjadřovat skutečný stav prvku – včetně vyhodnocení podmínek, jinak to nedává smysl. Jenže teď mě napadá, když mám custom latte šablonu formuláře a custom html + css na zobrazení hvězdičky, tak NetteForms javascript neví, jakou strukturu html a css tam mám. Takže obecně funkční řešení v javascriptu asi ani nebude možné.

steelbull
Člen | 240
+
-1
-

…a namiesto addConditionOn doplniť vlastnú validáciu vo form onValidate?

m.brecher
Generous Backer | 758
+
+1
-

@steelbull

vlastnú validáciu vo form onValidate

tuto cestu jsem nezkoušel, ale custom zapsané pravidlo v onValidate[] by se asi nepromítlo do javascriptu. A když tu podmíněnou červenou hvězdičku nejde udělat 100% tak radši vůbec. Nette formuláře validují výborně, takže problém je jenom ve snížení komfortu uživatele, ale velký problém to není.

Marek Bartoš
Nette Blogger | 1173
+
+1
-

Property $required je součástí veřejného api a měla by vyjadřovat skutečný stav prvku

Z prvku se čte nepodmíněné nastavení. Z podmínek se čte podmíněné nastavení. To co chceš je prostě úplně nová funkce.

m.brecher
Generous Backer | 758
+
0
-

@MarekBartoš

To co chceš je prostě úplně nová funkce.

Ano, je to nová funkce a důležitá. Po automatickém generování červených hvězdiček ve formulářích toužím cca od roku 2007 a pevně věřím, že doba, kdy se to stane realitou je již blízko.

steelbull
Člen | 240
+
0
-

@mbrecher

m.brecher napsal(a):

@steelbull

vlastnú validáciu vo form onValidate

tuto cestu jsem nezkoušel, ale custom zapsané pravidlo v onValidate[] by se asi nepromítlo do javascriptu. A když tu podmíněnou červenou hvězdičku nejde udělat 100% tak radši vůbec. Nette formuláře validují výborně, takže problém je jenom ve snížení komfortu uživatele, ale velký problém to není.

…áno, formuláre fungujú skvele, ale ak si prajete vyriešiť podmienené zobrazenie „*“ a validáciu (na strane klienta), vlastnému JS sa zatiaľ nevyhnete. Dalo by sa ho ale tiež obaliť do snippetu a prekresliť (namiesto reloadu stránky, ak bude hodnota chýbať).

m.brecher
Generous Backer | 758
+
0
-

@steelbull

vlastnému JS sa zatiaľ nevyhnete

ano, je to tak, ale zase ta červená hvězdička není tak důležitá :)