Chybové hlášky jinak než v JS alertu

ForestCZE
Člen | 209
+
0
-

Ahoj, prošel jsem fórum, pochytal střípky, ale nejsem z toho vůbec moudrý.

NetteForms ve formuláři defaultně vyhazuje chybové hlášky do alertu. Za normálních okolností je to ok. Můj problém je ten, že tvořím web do hry, kde ho poté načtu do iframe. Ve chvíli, kdy vyskočí JS alert, hra se z fullscreenu hodí do okna a hláška není vidět, jelikož je v dalším okně.

Proto by bylo asi vhodné se těch alertů zbavit. Hlášky vypsat do FM nebo do nějakého jiného divu. Také se mohu zbavit netteForms úplně, ale to se mi nehodí, protože z toho používám například toggle. Dočetl jsem se tedy, že cesta je upravit/přepsat netteForms. Na to si úplně netroufám. Nevěděl by někdo, jak to upravit co nejjednodušeji? Děkuji předem za opověď/pomoc.

Editoval ForestCZE (27. 10. 2020 3:22)

Mistrfilda
Člen | 76
+
0
-

Ahoj, https://github.com/…m-validation – tohle dela presne co potrebujes :)

Šaman
Člen | 2632
+
+1
-

@ForestCZE
Jestli chceš úplně zrušit JS validaci a vše si validovat v PHP, tak nastav formuláři atribut novalidate="novalidate".
Já to dělám v upraveném rendereru

$this->form->getElementPrototype()->novalidate = "novalidate";

Na PHP validaci to nemá vliv, takže po odeslání to vrátí případné chyby které si můžeš vykreslit kam chceš. Funguje i ajaxově.

P.S. Tohle mi (snad) funguje na Nette 2.4 Dělal jsem to už dávno, tak nevím, jestli tam není ještě nějaký háček. Zkus to a kdyby to nefugnovalo, zkusím ještě zapátrat. Ale mám Nette 2.4 projekt bez validačních alertů a s originálním netteForms.js, které také používám na toogle.

Editoval Šaman (27. 10. 2020 12:17)

ForestCZE
Člen | 209
+
0
-

@Šaman Tak vypnutí validace funguje. Jen mi není jasné, jak si teď sám ohlídat ty chyby, tedy alespoň v Nette. Momentálně, když nevyplním nějaké políčko a odešlu to, tak mě form vrátí na stránku, odkud jsem klikl na tlačítko, že chci formulář.

Kdysi dávno bez OOP jsem ošetřoval chyby na straně serveru ve stylu něco jako:

<input type="text" name="firstname">
<input type="submit" name="send" value="Odeslat">

if(isset($_POST["send"]))
{
	$firstname = $_POST["firstname"];

	if(strlen($firstname) == 0)
		echo "Zadejte jméno.";
	else
		// Všechno v pohodě, např. insert do DB, cokoliv...
}

Nemám tušení, jak to funguje v souladu s OOP a s Nette především. Mám pořád k dispozici ty hlášky, které by jinak JS vyhodil? (podle zdrojáku nejspíš ano)

Jak je získat a zpracovat? Byla by nějaká ukázka, třeba jednoho inputu? Budu vděčný. Díky moc.

Editoval ForestCZE (27. 10. 2020 15:37)

Šaman
Člen | 2632
+
+1
-

Ty chyby jsou normálně po odeslání v $form->getErrors(). Když používáš defaultní renderer, tak se vypíšou, jinak si ty chyby musíš někam vypsat sám: https://doc.nette.org/…ms/rendering#…
Je to až po odeslání, ale při zajaxování formuláře to funguje bez překreslení celé stránky.

Výhoda tohoto řešení je i to, že nemusíš rozlišovat chyby které dokáže zachytit JS a ty, které jsi vyhodil až při nějaké vlastní složitější validaci v onValidate.

Jen to myslím nevypne přímo validaci prohlížeče, která vyhodí vlastní okno pokud nějaké pole je required a není vyplněno. To je ale věc každého prohlížeče.

Editoval Šaman (27. 10. 2020 19:33)

ForestCZE
Člen | 209
+
0
-

Šaman napsal(a):

Ty chyby jsou normálně po odeslání v $form->getErrors(). Když používáš defaultní renderer, tak se vypíšou, jinak si ty chyby musíš někam vypsat sám: https://doc.nette.org/…ms/rendering#…
Je to až po odeslání, ale při zajaxování formuláře to funguje bez překreslení celé stránky.

Výhoda tohoto řešení je i to, že nemusíš rozlišovat chyby které dokáže zachytit JS a ty, které jsi vyhodil až při nějaké vlastní složitější validaci v onValidate.

Jen to myslím nevypne přímo validaci prohlížeče, která vyhodí vlastní okno pokud nějaké pole je required a není vyplněno. To je ale věc každého prohlížeče.

bdump($form->getErrors());

bdump() nic nevypíše, nicméně, když jsem si nastavil správný odkaz v setAction(), tak mi to vyhazuje ty chyby přímo k inputům do

<span class="error"></span>

Proč v getErrrors() nic není?

Šaman
Člen | 2632
+
0
-

ForestCZE napsal(a):

Proč v getErrrors() nic není?

Kdy? V tom odkazu do dokumentace je vidět ten blok, který chyby vypisuje (v šabloně zkráceně $form->errors). Kde to dumpuješ? A čemu říkáš odkaz v setAction? Používáš celé Nette, nebo jen Nette Forms?

Editoval Šaman (27. 10. 2020 21:29)

ForestCZE
Člen | 209
+
0
-

@Šaman
Při stisknutí tlačítka nastane toto. Už to tedy nějak vypisuje. Ale chci to vypsat jinde. Jak to mohu odchytit? Psal jsi, že jsou ty chyby ve $form->getErrors(), tak jsem si je dumpnul v metodě xxxSucceeded(Form $form), ale nic tam neni.

EDIT: Všiml jsem si, že ty hlášky se hází do

<span class="error"></span>

Už jsem začal pracovat na JS řešení, který projede všechny ty spany a hlášky to hodí do jednoho divu nad ten form, což se mi už i povedlo, ALE nevím, jak odchytit událost toho kliku (obecně nezávisle na konkrétním formuláři), aby ten div nebyl viditelný pořád.

EDIT2: Vymyslel jsem něco takového:

function showFormsErrors()
{
    const errors = document.getElementsByClassName("error"); // spany se třídou "error"
    if(errors !== null)
    {
        const getErrors = document.querySelector(".form-errors"); // můj div, kam chci vypsat všechny hlášky
        for(var i = 0; i < errors.length; i++)
        {
            getErrors.innerHTML += errors[i].innerHTML + "<br>";
        }
    }
}

Editoval ForestCZE (27. 10. 2020 21:57)

Šaman
Člen | 2632
+
+1
-

Hlášky se nehází automaticky do divu. Tam je jen vykreslí defaultní renderer. Mohou být ale vykresleny úplně jinde.
Jestli ta tvoje xxxSucceeded je navěšená na onSuccess, tak tam se chyby nemohou ukázat. Ta událost se provede jen pokud byl formulář odeslán úspěšně, tedy bez chyb.

$form->onSuccess[] = [$this, 'xxxSucceeded'];

To co asi hledáš je událost $form->onError[]. Já v ní právě třeba překresluji ajaxový formulář, aby se vykreslily chyby.

$form->onError[] = function($form) {
	$this->redrawControl('form');
	bdump($form->getErrors()); # tady by to mělo fungovat
};

Editoval Šaman (27. 10. 2020 23:48)

ForestCZE
Člen | 209
+
0
-

Šaman napsal(a):

Hlášky se nehází automaticky do divu. Tam je jen vykreslí defaultní renderer. Mohou být ale vykresleny úplně jinde.
Jestli ta tvoje xxxSucceeded je navěšená na onSuccess, tak tam se chyby nemohou ukázat. Ta událost se provede jen pokud byl formulář odeslán úspěšně, tedy bez chyb.

$form->onSuccess[] = [$this, 'xxxSucceeded'];

To co asi hledáš je událost $form->onError[]. Já v ní právě třeba překresluji ajaxový formulář, aby se vykreslily chyby.

$form->onError[] = function($form) {
	$this->redrawControl('form');
	bdump($form->getErrors()); # tady by to mělo fungovat
};

Ano, už to ty chyby vypisuje v poli. Pořád mi ale není jasné, co s tím dál a jak se zbavit těch spanů, ve kterých jsou ty errory po vypnutí validace. A dá se to nastavit globálně pro všechny formuláře nebo to musí být u každého zvlášť?

Šaman
Člen | 2632
+
0
-

Hledej v dokumentaci manuální vykreslování formulářů a vlastní renderer. To vykreslování uz jsem ti i posílal. Hned první blok v první ukázce kódu je vykreslení chyb. https://doc.nette.org/…ms/rendering#…
Jestli prostě vykresluješ formulář pomocí makra {control xxxForm} tak se nediv, že ty chyby jsou vypsané nějak defaultně. Konkrétně to dělá https://api.nette.org/…enderer.html