Live form validace včetně callbacků na straně serveru!

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

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.

toka
Člen | 249
+
0
-

Vypadá to velmi dobře :-)

Teuzz
Člen | 1
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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.

Šaman
Člen | 2594
+
+1
-

Ahoj, je nějaký pokrok v té integraci do netteForms, pls? Bohužel javascriptem nevládnu, ale tato fičurka by se mi hodila již několikrát.