Vlastní JS kód po úspěšné JS validaci formuláře

dakur
Člen | 493
+
0
-

Zdravím,

mám manuálně vykreslovaný Nette formulář, po jehož úspěšné validaci skrze netteForms.js bych rád provedl nějaký JS kód. Vymyslel jsem něco následujícího, problém je ale v tom, že vyskakují validační alerty dvakrát – jednou díky automatické validaci, podruhé díky podmínce v kódu níže.

<script>
$('form').submit(function () {
		if(window.Nette.validateForm(this)) {
			// some action
		}
	});
</script>

Neexistuje nějaká možnost jak „some action“ navěsit na úspěšnou validaci v netteForms, např. pomocí listeneru? Nebo nemáte nějaký jiný nápad, jak to vyřešit? Díky.

Honza Kuchař
Člen | 1662
+
0
-

netteforms.js nemá „validate“ event, nic takového tedy není možné.

Naštěstí Jahudka napsal mnohem pokročilejší implementaci formulářového skriptu. Implementace

dakur
Člen | 493
+
0
-

Nittro je pro mé použití příliš robustní, nakonec jsem se zavrtal do netteForms.js a vyřešil to vlastním hackem (přikládám níže). Nejsem v JS příliš zběhlý, tak prosím omluvte případnou nepěknost mého řešení.

<script>
/**
 * Attaches a listener to an event for a form.
 */
Nette.addListener = function(on, callback) {
	if(typeof Nette.listeners === 'undefined') {
		Nette.listeners = {};
	}
	if(!Nette.isArray(Nette.listeners['on' + on])) {
		Nette.listeners['on' + on] = [];
	}
	Nette.listeners['on' + on].push(callback);
};

...

Nette.validateForm = function(sender) {
	var form = sender.form || sender,
		scope = false;

	if (form['nette-submittedBy'] && form['nette-submittedBy'].getAttribute('formnovalidate') !== null) {
		var scopeArr = Nette.parseJSON(form['nette-submittedBy'].getAttribute('data-nette-validation-scope'));
		if (scopeArr.length) {
			scope = new RegExp('^(' + scopeArr.join('-|') + '-)');
		} else {
			Nette.afterValidationSuccess(form); // přidáno
			return true;
		}
	}

	...

		if (!Nette.validateControl(elem)) {
			return false;
		}
	}
	Nette.afterValidationSuccess(form); // přidáno
	return true;
};

/**
 * Fires listeners for after form is successfully validated.
 */
Nette.afterValidationSuccess = function (form) {
	if(!Nette.isArray(Nette.listeners.onvalidatesuccess)) {
		return;
	}

	for(var i in Nette.listeners.onvalidatesuccess) {
		var listener = Nette.listeners.onvalidatesuccess[i];
		if(typeof listener === 'function') {
			listener(form);
		}
	}
};
</script>

Ve svém JS kódu poté volám:

<script>
window.Nette.addListener('validatesuccess', function (form) {
	// ...
});
</script>
Honza Kuchař
Člen | 1662
+
0
-

@dakur neches poslat git-patch? Nebo přímo pull request?

U tohoto řešení jsem si všiml, že addlister funguje globálně; tj. s AJAXovou stránkou je treba nejak (např. pomocí třídy) rozlisovat mezi instancemi formularu a odregistrovavat ty, ktere uz nejsou na strance

To se u komplikovanějších AJAXových webů nehodí. Nešlo by registrovat ten event na konkrétní instanci formuláře? To na druhou stranu u jednoduchých stránek situaci zkomplikuje. (budu muset čekat, až bude k dispozici DOM instance formuláře)

radas
Člen | 221
+
+1
-

A co tak jít na to z druhé strany?
http://tvaroha.cz/…-validation/

Bajaja
Člen | 22
+
-1
-

Ja osobne jsem to teda vyresil doplneni 3 radku do Nette.validateForm() a formularoveho attributu onValidForm

Na konec metody Nette.validate form jsem pridal:

<script>
	...
	if (sender.getAttribute('onValidForm')) {
	    eval(sender.getAttribute('onValidForm'));
    }
	return true;
};
</script>

a do formulare kde chci spustit kod po validaci

{form myForm onValidForm => "alert('My form is valid');"}
...
{/form}

Editoval Bajaja (4. 5. 2018 12:37)