Unobstrusive Client Form Validation

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

Zdravím,

asi bych měl spíš makat na NetBeans Nette pluginu, ale čas od času člověka něco napadne a musí to hned vyzkoušet. Před nějakou dobou tu byl nápad na něco podobného (na PS), slovo bylo, že to bude za 2 týdny hotové a ready pro přidání do Nette. Skutek utek.. Tak jsem se pustil do něčeho podobného. Výsledek je trochu jiné pojetí klientské validace formulářů (code-name ExFormValidation od slova external) Asi rovnou uvedu příklad:

Pravidla se zadávají naprosto stejně jako teď:

$form->addText("user", "Username")
    ->addRule(Form::FILLED, "Nutné vyplnit")
    ->addRule(Form::REGEXP, "Musí obsahovat pouze malá písmena", "/^[a-z]+$/")
    ->addRule(Form::MIN_LENGTH, "Minimálně %s znaky", 4);

$form->addPassword("password", "Heslo")
    ->addRule(Form::FILLED, "Heslo musí být vyplněno")
    ->addRule(Form::MIN_LENGTH, "Počet znaků musí být větší než %s", 5);

Render:

<input type="text" class="text ex_filled ex_regexp ex_minLength_4 ex" name="user" id="frmform-user" value="" />
<input type="hidden" id="frmform-user_regexp" value="/^[a-z]+$/" />

<input type="password" class="text ex_filled ex_minLength_5 ex" name="password" id="frmform-password" />

Všimněte si atributů class. Je tam plnou nehezkých věcí, začínající prefixem ex_. Ty určují pravidla, které jsou na prvku použity. A teď ta dobrá zpráva: všechen výkonný kód je v externím JS souboru a je nezávislý na formuláři (je konstantní). Za pomoci jQuery, se řeší samotná validace na základě informací v atr. class (tzn. parsování jednotlivých pravidel).

Je tu ovšem pár ale – některá pravidla jsou „proměnná“, tzn. nejsou stejná pro všechny případy a jejich definice naprosto odporuje použití v atributu class (např. Form::REGEXP). Ten se řeší tak, že se za prvek vloží hidden input (bez atr. name) a při validaci REGEXP operace onoho prvku použije obsah hidden inputu (kterým je onen regulární výraz; viz html kód výše).

Dalším problémem jsou různé podmínky, které se dají aplikovat. Můžu říct, že jsem vyřešil nejjednodušší případy podmínek condition a conditionOn. A to navíc přímo v attr class bez nutnosti nějakého externího zápisu:

$form->addPassword("passwordcheck", "* Heslo znovu")
    ->addRule(Form::FILLED, "Kontrola musí být vyplněna")
    ->addConditionOn($form['password'], Form::FILLED)
        ->addRule(Form::EQUAL, 'Neshodují se hesla', $form['password']);
<input type="password" class="text ex_filled ex_on_frmform-password_filled_equal_frmform-password ex" name="passwordcheck" id="frmform-passwordcheck" />

Zatím jsem neřešil chybové hlášky, specifikované při tvorbě formu a používám na tvrdo napsané v JS pro každou operaci (něco jako jsou default messages přímo v FW)

Ještě uvidíme kam zajdu se složitějšími podmínkami (a else a elseif atd. i když si myslím, že se používají v 1% případů).

Teď to hlavní – myslíte si, že je to dobré a mohlo by být k užitku? Nebo že je to hnusné, naprosto sprasující, nezpřehledňující blbost?

Sám se trochu přikláním k té druhé variantě :D ovšem vynahrazuje mi to myšlenka na NEopakující se validační JS pravidla pod každým formem a centralizace validačních pravidel v jediném JS souboru..

Now, hit me!

na1k
Člen | 288
+
0
-

Nebudu soudit použitelnost, protože mi současná propojenost pravidel a javascriptu nijak zásadně nevadí. Ikdyž pocitově se mi ta hromada css tříd moc nepozdává :-p

Jen bych ale podotknul, že se už nějakou dobu mluví o překopání formů i validací, a to Davidem a Danielem Steigerwaldem. Jak a jestli vůbec už se na něčem takovém pracuje, to opravdu netuším.

srigi
Nette Blogger | 558
+
0
-

Druha varianta je uz cca spravne, vid. link

redhead
Člen | 1313
+
0
-

Moc lidí o to nezavadilo, takže to zatím nechám být.

To o Danielu Steigerwaldovi vím, na tu PS jsem odkazoval v prvním postu. Ale že by se o tom nějak mluvilo?? Na PS říkal, že to bude za 2 týdny a už je to skoro půl roku..

Co se týče toho linku, asi by nebyl problém to předělat do podobné syntaxe, navíc by to vyřešilo pár
věcí..

blacksun
Člen | 177
+
0
-

A co ta pravidla navázat v propojovacím javascriptu, který bude u každého formuláře, pomocí ID prvků, například jako definici js polí, kde bude klíč ono ID?

Tzn. mít jeden centrální hlavní js, který bude obsahovat validační logiku a k formuláři generovat něco jako pole callbacku, které se budou na každý prvek dle jeho ID aplikovat.

redhead
Člen | 1313
+
0
-

Chtěl jsem se právě vyhnout co nejvíc JavaScriptu uvnitř stránky a jak je vidět někdo to už uvedl do docela použitelné syntaxe (viz link od srigi). Ovšem to, že to naprosto sprasí chudáka atribut class je taky špatně..

norbe
Backer | 405
+
0
-

Osobně bych se taky spíš přimlouval ke kombinaci obou řeší. Tedy přidat k formuláři třídy typu filled, integer, max_length, ..., ale pro podmínky apod bych volil spíše vygenerování JS, ale to je asi věc pohledu a každý má jinou představu.

Co se týče té práce na JS, kterou měl obstarat Daniel Steigerwald, tak na to je asi uvalené nějaké informační embargo, jelikož se k tomu nikdo nechce vyjádřit už skoro měsíc.

David Grudl
Nette Core | 8172
+
0
-

Na tohle vlákno jsem narazil až nyní, no každopádně myslím, že současná implementace v posledních revizích je asi lepší, ne?

ps. jestli Dan bude mít chuť a něco vytvoří, budu jen rád, stejně tak může do Nette přispět kdokoliv jiný. Ale netuším, jak bych se měl k tomu vyjadřovat.

redhead
Člen | 1313
+
0
-

David Grudl napsal(a):

Na tohle vlákno jsem narazil až nyní, no každopádně myslím, že současná implementace v posledních revizích je asi lepší, ne?

ps. jestli Dan bude mít chuť a něco vytvoří, budu jen rád, stejně tak může do Nette přispět kdokoliv jiný. Ale netuším, jak bych se měl k tomu vyjadřovat.

Ježiš! Zapoměň na tohle. Po tom co si vydal to svoje, jsem to smazal, jako největší fail.

David Grudl
Nette Core | 8172
+
0
-

Jako fail bych to rozhodně neviděl!