chybny Rule length?

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

Ahoj,
pokud si na formular pridam pravidlo:

<?php
->addRule(Form::LENGTH, 'PSČ musí obsahovat %d znaků.', 5);
?>

tak mi do formulare prida: maxlength="5" a pri validaci zkontroluje minimalni delku.
Ale pokud si vyrenderuji formular pomoci vlastni sablony (bez maxlength) tak mi projde validaci i delsi cislo, nez 5 znaku. Je to bug, nebo mam spatne napsane pravidlo?

Verze: Nette Framework 0.9.2

=======

Dodatek: Vypada to, ze si Nette nejprve text zkrati na spravnou delku a pak teprve validuje. Takze projde i PSC „12345ab“ (vrati „12345“). A to i pres addRule(Form::INTEGER). Nevim jak komu, ale me to pripada jako trochu zvlastni chovani. Pravidlo LENGTH se tak vlastne chova jako filtr.

Editoval Šaman (5. 3. 2010 10:45)

Ondřej Mirtes
Člen | 1536
+
0
-

Jakým způsobem renderuješ ten formulář? Renderuješ tam i begin, errors a end?

iguana007
Člen | 970
+
0
-

A jak vypadá ta tvoje „vlastní“ šablona?

Šaman
Člen | 2634
+
0
-
<?php
{control $form begin}
<form action="/?do=kalkulatorKrok1Form-submit" method="post">

	<p>{!$form->render('errors')}</p>

	<fieldset>
		<legend>Adresa:</legend>

		<p >
			<label for="frmkalkulatorKrok1Form-ulice">Ulice:</label>
			<input type="text" onchange="KalkulatorKrok1Form.validateControl(this);" onblur="KalkulatorKrok1Form.validateControl(this);" onkeyup="KalkulatorKrok1Form.validateControl(this, event);" class="text" name="ulice" id="frmkalkulatorKrok1Form-ulice" value="{!$form['ulice']->getValue()}" />
		</p>

		<p >
			<label for="frmkalkulatorKrok1Form-cisloPopisne">Číslo popisné:</label>
			<input type="text" onchange="KalkulatorKrok1Form.validateControl(this);" onblur="KalkulatorKrok1Form.validateControl(this);" onkeyup="KalkulatorKrok1Form.validateControl(this, event);" class="text" name="cisloPopisne" id="frmkalkulatorKrok1Form-cisloPopisne" value="{!$form['cisloPopisne']->getValue()}" />
		</p>

		<p >
			<label for="frmkalkulatorKrok1Form-cisloOrientacni">Číslo orientační:</label>
			<input type="text" onchange="KalkulatorKrok1Form.validateControl(this);" onblur="KalkulatorKrok1Form.validateControl(this);" onkeyup="KalkulatorKrok1Form.validateControl(this, event);" class="text" name="cisloOrientacni" id="frmkalkulatorKrok1Form-cisloOrientacni" value="{!$form['cisloOrientacni']->getValue()}" />
		</p>

		<p >
			<label for="frmkalkulatorKrok1Form-obec">Obec:</label>
			<input type="text" onchange="KalkulatorKrok1Form.validateControl(this);" onblur="KalkulatorKrok1Form.validateControl(this);" onkeyup="KalkulatorKrok1Form.validateControl(this, event);" class="text" name="obec" id="frmkalkulatorKrok1Form-obec" value="{!$form['obec']->getValue()}" />
		</p>

		<p >
			<label for="frmkalkulatorKrok1Form-psc">PSČ:</label>
			<input type="text" id="frmkalkulatorKrok1Form-psc" maxlength="9" onchange="KalkulatorKrok1Form.validateControl(this);" onblur="KalkulatorKrok1Form.validateControl(this);" onkeyup="KalkulatorKrok1Form.validateControl(this, event);" class="text" name="psc" value="{!$form['psc']->getValue()}" />
		</p>
	</fieldset>
	<fieldset>
		<legend>Akce:</legend>

		<p class="center">
			<input type="submit" onchange="KalkulatorKrok1Form.validateControl(this);" onblur="KalkulatorKrok1Form.validateControl(this);" onclick="return KalkulatorKrok1Form.validate(this)" class="button" name="ok" id="frmkalkulatorKrok1Form-ok" value="Najdi nejlevnější!" />
			<input type="submit" onchange="KalkulatorKrok1Form.validateControl(this);" onblur="KalkulatorKrok1Form.validateControl(this);" class="button" name="cancel" id="frmkalkulatorKrok1Form-cancel" value="Smaž formulář!" />
		</p>
	</fieldset>

</form>
{control $form end}

<script type="text/javascript">
	{!$script}
</script>
?>

Pokud mam zapnutou live validaci, tak to funguje podle predpokladu (kdyz presahnu 5 znaku, tak mi to vyhodi chybu a nedovoli odeslani). Vypada to, ze test na delku funguje spravne, ale zmatlo me, ze pri odeslani formulare se vracena hodnota nejprve zkrati na spravnou delku a pak teprve validuje. Takze se vlastne ignoruje vsechno pres pet znaku.
Chyba to zrejme neni, ale vlastnost :) ktera me trochu zmatla.

P.S.

Delka inputu PSC je schvalne delsi, kvuli testovani.

Vlastni renderovani zkousim, protoze chci na inputy navesit vlastni JS naseptavac, takze budu potrebovat zmenit obsluhu udalosti. Ted je to upravene tak, ze funguje LiveValidator z Addons.

Editoval Šaman (5. 3. 2010 11:47)

redhead
Člen | 1313
+
0
-

Podle mě by to feature být neměl. Situace – heslo při registraci nesmí být delší než 20 znaků. Pokud zadám 25 (a JS validace nebude fungovat = vypnutý JS). Tak se do DB pošle zkrácené heslo. Potom při přihlášení bych zadával to své dlouhé a divil se proč se nemůžu přihlásit.. Nevim nevim (je to sice trochu nadnesené, díky maxlenght=„20“, ale stejně pokud u manuál renderingu nejede)

Šaman
Člen | 2634
+
0
-

No, pri konvencnim renderovani formulare je to osetreno delkou inputu. Ale jak vidno, muze nastat situace kdy se obe kontroly obejdou (maxlength v HTML i JS validace) a pak nastane situace popsana vyse.

Anebo delam neco blbe.

Ondřej Mirtes
Člen | 1536
+
0
-

Máš to špatně. Takovýhle zápis neexistuje:

{contol $form end}

To by znamenalo, že ve $form máš uložen název komponenty (formuláře) – v továrničce.

Navíc tam všechny inputy vykresluješ doslova "ručně, což je taky špatně. Má to vypadat takto:

{widget kalkulatorKrok1Form begin}

        {widget kalkulatorKrok1Form errors)

        <fieldset>
                <legend>Adresa:</legend>

                <p>
                        {$form['ulice']->label}
                        {$form['ulice']->control}
                </p>

                <p >
                        {$form['cisloPopisne']->label}
                        {$form['cisloPopisne']->control}
                </p>

                <p >
                        {$form['cisloOrientacni']->label}
                        {$form['cisloOrientacni']->control}
                </p>

                <p >
                        {$form['obec']->label}
                        {$form['obec']->control}
                </p>

                <p >
                        {$form['psc']->label}
                        {$form['psc']->control}
                </p>
        </fieldset>
        <fieldset>
                <legend>Akce:</legend>

                <p class="center">
                        {$form['ok']->control}
                        {$form['cancel']->control}
                </p>
        </fieldset>

</form>
{control kalkulatorKrok1Form end}

Z toho, že sis to špatně, doslova ručně vykreslil (proboha, kdybys změnil název toho formuláře, budeš celou tu šablonu ručně přepisovat, jako kdyby to bylo špatné procedurální PHPčko?), pramení ty problémy.

iguana007
Člen | 970
+
0
-

To jsem si myslel, že ten form vykresluješ doslova „ručně“ – zbytek viz. post od Ondry

Jan Endel
Člen | 1016
+
0
-

Díky ti Ondro za objasnění vlastního vykreslování formuláře, celý včerejšek jsem se s tím mordoval a nemohl ani za boha nic na foru najit a dokumentace mi zrovna v tom místě házela 404 :(

Šaman
Člen | 2634
+
0
-

2 Ondřej Mirtes: No, tovarnu pouzivam (asi proto mi to funguje – vypisuje validacni chyby). V tom pouzivani sablon pro formulare plavu – inspiraci jsem bral tady . (Po tvem upozorneni ji trochu upravim, diky.)
Postupne jsem ale cely formular prepsal konvencne, protoze volanim {$form['ulice']->control} neumim osetrit obsluhu udalosti onKeyNeco. To, co navrhujes mi vytvori stejny vysledek jako Davidova sablona nebo ConventionalRenderer (s upravenymi pravidly jako <tr>=><p>).

Chapu spravne, ze pes je zakopan v tom, ze jsem zapomnel nastavit maxlength u inputu PSC, zatimco kdybych postupoval podle best practice, tak se toto nestalo? To uznavam.
Proc se ale hodnota z formulare zkracuje? (ciste hypoteticka otazka: Co kdybych se rozhodl podvrhnout POSTovane hodnoty, nebo na stranku presmeroval z jineho formulare?)

Nicmene diky vsem za cas, beru si z toho pouceni ze mam poradne nastudovat sablony a pro priste si (snad:) budu pamatovat jak se chova ta validace. (Netvrdim ze je spatne, jen jsem jeji chovani nechapal, nez jsem zjisti proc.)

Editoval Šaman (5. 3. 2010 14:32)

Ondřej Mirtes
Člen | 1536
+
0
-

Pokud do toho tagu input potřebuješ něco přidat, slouží k tomu tato syntaxe (v továrničce):

$form['ulice']->getControlPrototype(); //Nette\Web\Html objekt, na něm můžeš dělat, co chceš

Nicméně nějaké onKey události by se měly navěšovat úplně mimo HTML, v nějakém jQuery.

Nette ty hodnoty ořezává právě z důvodu ochrany proti podvrženým formulářům.

Editoval Ondřej Mirtes (5. 3. 2010 14:35)

Šaman
Člen | 2634
+
0
-

Diky, to bude ono. :p
(Me to pripadalo trochu nepekne reseni – prepsat sablonu uplne rucne. Ale sef chtel mit ten formular hned a tak jsem to lehce zbastlil. Mile me prekvapilo, ze validace fungovala – a to i ta live. A getValue() taky.)

norbe
Backer | 405
+
0
-

To nějak moc nechápu, z důvodu ochrany proti podvržení formuláře ořízne hodnotu a uloží? Mělo by to snad spíš hodit chybu, nebo mi něco uniká?

Takhle mi to přijde stejně špatné jako kdybych nastavil, že checkbox musí být zaškrtnutý a nette to z důvodu ochrany proti podvrhnutí samo zaškrtlo.

redhead
Člen | 1313
+
0
-

Souhlasím, že by to spíš mělo hodit chybu a to i v případě, že by se formulář měl podvrhnout (!!!)

Ondřej Mirtes
Člen | 1536
+
0
-

To chování jsem nezkoumal, mohlo tam být ještě něco špatně. Třeba to neprojde validací (což nemá vůbec smysl do values pak sahat), ale do values se ta hodnota dá oříznutá… A jelikož Šaman pak na value toho inputu sahal, vyplnila se mu ta oříznutá hodnota.

David Grudl
Nette Core | 8111
+
0
-

Berte to tak, že nikdy nelze odeslat hodnotu delší než stanovený počet znaků. Pokud to někdo přesto odešle, je jakékoliv řešení stejně správné.