Live form validace včetně callbacků na straně serveru!
- Ondřej Mirtes
- Člen | 1536
Ahoj,
konečně mě napadlo, jak jednoduše podporovat validaci uživatelských
callbacků u formulářů i na straně klienta. Nyní byly všechny ty
live form validation pluginy pouze náhradou současného alert okna
z Nette, podporovaly pouze jednoduchá pravidla.
Já jsem do AppForm přidal podporu pro další signál, kromě submit nyní podporuje i validate, který na POST požadavek odpoví polem chybových hlášek v JSONu:
/**
* This method is called by presenter.
* @param string
* @return void
*/
public function signalReceived($signal)
{
if ($signal === 'submit') {
$this->fireEvents();
} else if ($signal == 'validate') {
$post = $this->presenter->request->post;
if (!isset($post['name']) || !isset($post['value'])) {
throw new BadSignalException('Bad POST data format.');
}
$control = $this[$post['name']];
$control->value = $post['value'];
$control->rules->validate();
$this->presenter->terminate(new JsonResponse(array('errors' => $control->errors)));
} else {
throw new BadSignalException("There is no handler for signal '$signal' in {$this->reflection->name}.");
}
}
Pokusně jsem implementoval i validaci na straně klienta, ale chtělo by to někoho, kdo Javascript umí :o)
if (typeof $ === "function") {
$(function() {
$("input[type=text]").blur(function(event) {
el = event.target;
action = $(el.form).attr("action");
$.post(action.replace("-submit", "-validate"), {
name: el.name,
value: $(el).val(),
}, function(data, textStatus, xhr) {
if (textStatus == "success" && data !== null && typeof data["errors"] !== "undefined") {
$(el).next('.verror').remove();
$.each(data["errors"], function(index, error) {
$(el).after('<label for="' + $(el).attr('id') + '" class="verror">' + error + '</p>');
});
}
}, "json");
});
});
}
Správnou implementaci bych si představoval tak, že by využívala
netteForms.js a na server by sahala jen v případě, že projdou ta základní
pravidla. Pro ušetření zbytečných requestů bych do
data-nette-rules
přidal ještě informaci o tom, že formulář
má na serveru přiřazené nějaké uživatelské callbacky.
- Teuzz
- Člen | 1
Ahoj, pěkné, zkusil jsem trochu mrknout na ten JS, neměl jsem to kde ozkoušet, takže tam jsou možná nějaké překlepy: http://pastebin.com/HRFa9i4X
minimálně pořád dokola instancuješ $(el)… taky nemám patent na JS, jen jsem zkusil opravit, co mi „vadilo“ :-)
- Majkl578
- Moderator | 1364
Něco takového už jsem kdysi dělal, bohužel to bylo ignorováno. Holt nemám takovou pověst na to, aby se tím někdo vůbec zabýval, natož to zkusil. :))
- Dr.Diesel
- Člen | 53
Majkl578 napsal(a):
Něco takového už jsem kdysi dělal, bohužel to bylo ignorováno. Holt nemám takovou pověst na to, aby se tím někdo vůbec zabýval, natož to zkusil. :))
Kluci zajimalo by me, kolik veci se dela takto nekolikrat jen kvuli tomu, ze se drtiva vetsina veci resi jen pres forum. Imho je prave to dost velky „problem“ nette :-(
- bojovyletoun
- Člen | 667
Ahoj, právě jsem si teď v noci vzpomněl na typickou úlohu: například registrace mailu, zadáváte mail a ono to živě ukazuje ,zda je mail ještě neregestrovaný. Tohle vypadá jako přesně, co tomu odpovídá?
Proto mě zajímá nějaké best practise této úlohy. Je tohle řešení něčím překonáno (vzhledem k stáří příspěvku,… ikdyž 4 měsíce)
- Ondřej Mirtes
- Člen | 1536
Ahoj,
co já vím, tak principiálně nic lepšího zatím neexistuje. Ten uvedený
javascriptový kód by si samozřejmě zasloužil přepsat a zaintegrovat do
aktuálního netteForms.js (tím způsobem, že na server se sáhne až
v momentě, když daná validační funkce není k dispozici na klientovi –
což vyřadí sahání na server pro jednoduchá pravidla jako filled, equal,
pattern apod.), ten uvedený kód do Nette\Application\AppForm
(resp. do vlastního potomka, nekuchat do frameworku!) je v pořádku.