User Warning: Form was submitted but there are no associated handlers
- David Grudl
- Nette Core | 8218
Formuláře od verze 3.1.4 kontrolují, zda mají nějaký obslužný
handler, tj. je zavěšené volání metody pro onSuccess
,
onSubmit
nebo onClick
na tlačítku:
$form->onSuccess[] = [$this, 'formSucceeded'];
Pokud chybí, vyhodí varování
Form was submitted but there are no associated handlers
.
Důvod je ten, že se stává, že programátor, zejména začátečník, zapomene asociovat obslužný handler a pak složitě pátrá, proč odesílání formuláře nefunguje. Tohle by mu mělo usnadnit vývoj.
- Marek Bartoš
- Nette Blogger | 1260
Upozornění je to fajn, ale myslím že začátečník si bude pořád říkat, co má být ten associated handler a bude muset sám zjistit, jak problém vyřešit. Moc by se mi líbilo, kdyby Nette v chybách vysvětlovalo jaká událost nastala, co je v ná za problém a jak ji vyřešit. Momentálně je třeba si řešení domyslet.
Context: Form with ID product-form was submitted.
Problem: Form has no handler to process it on success.
Solution: Add callback to Form->onSuccess[] or Form->onSubmit[] to process sent data.
Editoval Marek Bartoš (29. 8. 2021 15:01)
- David Grudl
- Nette Core | 8218
Ono to vysvětlení obvykle nejde udělat jednou větou, proto jsem vlastně založil tohle vlákno, aby se hláška dala vygooglit a tam najít řešení.
- Polki
- Člen | 553
Hm i když jsem začátečník od roku 2014, tak se mi zrovna minulý týden
podařilo přesně tuhle botu udělat.
Konkrétně jsem měl strukturu takovou, že jsem dělal formulář jako
komponentu a tedy jsem měl více navěšených onSuccess metod.
Jednu, která se v komponentě starala o zpracování dat a jednu, která se
v Presenteru starala o přesměrování po úspěšném dokončení.
Problém byl, že jsem navěštil tu událost z Presenteru, ale zapomněl jsem navěštit zpracování dat, takže redirect s flashMessage proběhl v pohodě, ale data se nezpracovala. Divil jsem se a docela dlouho na můj vkus jsem hledal kde je chyba a proč se mi nevolá update nad databází.
Když jsem si všiml, že mi tam chybí navěšení události, tak jsem se sám divil, že po takové době, kdy jsou formy denní chleba jsem udělal takovou chybu. A to, že to formuláře tvořím často přispělo taky k tomu, že jsem tuto konkrétní chybu nehledal.
Za mě rozhodně +.
Můj problém to sice neřeší, jelikož by to bralo, že mám vše ok,
jelikož by to bralo jako navěšenou událost z presenteru starající se
o přesměrování, ale i tak si myslím, že to je dobrý nápad.
- Michal Kumžák
- Člen | 106
Problém byl, že jsem navěštil tu událost z Presenteru, ale zapomněl jsem navěštit zpracování dat, takže redirect s flashMessage proběhl v pohodě, ale data se nezpracovala. Divil jsem se a docela dlouho na můj vkus jsem hledal kde je chyba a proč se mi nevolá update nad databází.
To by ti v tomto případě, ale tato úprava nepomohla, jestli sem to pochopil správně.
- Polki
- Člen | 553
Michal Kumžák napsal(a):
Problém byl, že jsem navěštil tu událost z Presenteru, ale zapomněl jsem navěštit zpracování dat, takže redirect s flashMessage proběhl v pohodě, ale data se nezpracovala. Divil jsem se a docela dlouho na můj vkus jsem hledal kde je chyba a proč se mi nevolá update nad databází.
To by ti v tomto případě, ale tato úprava nepomohla, jestli sem to pochopil správně.
Nepomohla. Proto jsem taky psal:
Můj problém to sice neřeší, …
Jen jsem chtěl poukázat na to, že to je dobrý nápad, jelikož když se to může stát někomu, kdo s Nette pracuje 7 let, tak se to určitě stává nováčkům.
Editoval Polki (30. 8. 2021 16:37)
- David Grudl
- Nette Core | 8218
U GET formulářů by se to asi kontrolovat nemuselo. Proč tam handler cpe parametr?
- MajklNajt
- Člen | 493
nazdar, už dlší čas pozorujem tento warning na jednom webe, kde handlery sú zavesené, bolo to ale len sporadicky, no dnes som po tom začal pátrať a zistil som, že mi tento warning generuje asi iba jeden návštevník (jeden typ návštevníka), ktorý má User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 – môže to s tým nejako súvisieť? v priebehu 3 dní to bolo z 50 prihlásení 8×, z toho 2× z jednej IP, 6× z druhej IP, pričom obe IP sú od rovnakého providera, takže považujem za možné sa domnievať, že ide o jednu osobu…
EDIT: project mám cez git nasadený na 10+ weboch, avšak robí mi to iba na jednom
Editoval MajklNajt (20. 1. 2023 8:02)
- MajklNajt
- Člen | 493
Podľa logov webservera však tu ide o bežného človeka, ktorý klikne na
prihlásenie a formulár odošle. Udalosť vešiam priamo v komponente, nie je
však navesená na Form::onSuccess
ale
SubmitButton::onClick
, no to sa tiež kontroluje, tak
nechápem :/
EDIT:
92.249.*.* - - [20/Jan/2023:07:03:43 +0100] "GET /catalog HTTP/2.0" 200 7134 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
92.249.*.* - - [20/Jan/2023:07:03:43 +0100] "GET /favicon.ico HTTP/2.0" 404 247 "https://***.hu/catalog" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
92.249.*.* - - [20/Jan/2023:07:03:46 +0100] "GET /sign/in HTTP/2.0" 200 4361 "https://***.hu/catalog" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
92.249.*.* - - [20/Jan/2023:07:03:47 +0100] "POST /sign/in HTTP/2.0" 200 4379 "https://***.hu/sign/in" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
92.249.*.* - - [20/Jan/2023:07:03:49 +0100] "POST /sign/in HTTP/2.0" 200 316 "https://***.hu/sign/in" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
92.249.*.* - - [20/Jan/2023:07:03:49 +0100] "GET /sign?_fid=uypu HTTP/2.0" 200 5585 "https://***.hu/sign/in" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
92.249.*.* - - [20/Jan/2023:07:04:00 +0100] "GET /catalog HTTP/2.0" 200 7441 "https://***.hu/sign?_fid=uypu" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
92.249.*.* - - [20/Jan/2023:07:04:35 +0100] "GET /catalog HTTP/2.0" 200 7444 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
Editoval MajklNajt (20. 1. 2023 10:54)
- Ozzrel
- Generous Backer | 54
Taky bych to potřeboval vypnout. Při použití metody Formulář pro vytvoření i editaci záznamu tak to právě nefunguje.
- m.brecher
- Generous Backer | 863
@MajklNajt
Udalosť vešiam priamo v komponente, nie je však navesená na Form::onSuccess ale SubmitButton::onClick, no to sa tiež kontroluje
To vypadá na robot, který posílá nestandardní request a proto se ten handler nezavolá. Máš tam asi nějakou skulinku v kódu. Zkus do kódu komponenty přidat navíc handler onSuccess, který zachytí vše, otestovat, kudy tam ten robot chodí.
$this->onSuccess[] = fn() => $this->logger->log('komplet info o requestu');
OnSuccess se volá až po onClick, takže by se teoreticky neměl zavolat nikdy, jedině v případě toho robota. Jednak Ti to pomůže najít chybu v kódu, jednak to můžeš použít pro potlačení té falešné hlášky:
$this->onSuccess[] = fn() => 'foo';
- m.brecher
- Generous Backer | 863
@Ozzrel
Taky bych to potřeboval vypnout.
Já mám občas formuláře, kde tlačítkem přidávám do formuláře dynamicky nějaký prvek. Toto tlačítko má vypnutou validaci a nemá handler, protože jeho úkolem není provést na serveru nějakou akci, ale pouze změnit stav formuláře (např. počet položek faktury). Abych potlačil warning o chybějícím handleru, musím přidat do formuláře zbytečný handler, který nic nedělá, jenom odstraní ten warning. Čistší řešení by bylo mít možnost tento warning v konfiguraci vypnout.
- mskocik
- Člen | 61
m.brecher napsal(a):
Já mám občas formuláře, kde tlačítkem přidávám do formuláře dynamicky nějaký prvek. Toto tlačítko má vypnutou validaci a nemá handler, protože jeho úkolem není provést na serveru nějakou akci, ale pouze změnit stav formuláře (např. počet položek faktury). Abych potlačil warning o chybějícím handleru, musím přidat do formuláře zbytečný handler, který nic nedělá, jenom odstraní ten warning. Čistší řešení by bylo mít možnost tento warning v konfiguraci vypnout.
A nestačilo by ti len nastaviť pre ten button type=button
?
Ten nesubmituje formulár
- m.brecher
- Generous Backer | 863
@mskocik
A nestačilo by ti len nastaviť pre ten button type=button? Ten nesubmituje formulár
V mém případě to není vhodné řešení. Potřebuji, aby formFactory měla hned na začátku když formulář sestavuje informace jak má formulář vypadat. Přesněji, kolik položek faktury má vykreslit. Formulář se sestavuje na serveru, proto když chci, aby klik na tlačítko přidal prvek do formuláře, musím to prohnat POST přes server, aby se současně neztratily data ve formuláři.
Kdybych přidal prvek do formuláře v prohlížeči javascriptem pomocí type=button, tak po odeslání dat nebude při zpracování na serveru formFactory vědět, že tam nějaký prvek/ky přibyl. Musely by se analyzovat odeslaná data POST a to vede na komplikované a nepřehledné řešení. Proto preferuji submit button, formulář si udržuje v pomocném input hidden stav a ten řídí sestavování formuláře ve form Factory.
Při přidávání nových feature do frameworku, je potřeba dát pozor, aby dobře míněná funkce nezpůsobila nezamýšlené potíže. Protože lidi framework používají různými způsoby. V případě upozornění na chybějící handler by bylo vhodné mít možnost tuto hlášku vypnout.
- elnathan
- Člen | 17
Tahle featura je taková nedomyšlená:
Všude používám ->onClick[], což je i dle nejnovější dokumentace
stále povoleno a v pořádku. Všechny formuláře jej mají korektně
vyplněný, takže nepotřebuji žádné upozorňování pro začátečníky
(jak tomu říkáte). Pro běžného návštěvníka vše funguje, ale pak na
web přijdou roboti, kteří se snaží projít formulářem a odesílají
prázdný POST případně GET ?do=form-submit (podle typu). Hádejte, co se
stane? Vyhodí to tuto chybu, protože chybí informace o kliknutí na
tlačítko a tudíž to hlásí, že neexistuje handler. Všechny weby, všechny
formuláře po aktualizaci Nette najednou hlásí desítky/stovky errorů do
logu, které mě ale vůbec nezajímají, protože to není „chyba“.
Ano, má to řešení: u jednotlačítkových přepsat $input->onClick[] na
$form->onSuccess[] … u více-tlačítkových doplnit prázdný
$form->onSuccess[] … ale proč mám přepisovat všechny formuláře
v aplikaci, které jsou fakticky správné? Tohle chování by mělo jít
globálně vypnout někde v konfiguraci projektu.
- m.brecher
- Generous Backer | 863
@elnathan
Všude používám ->onClick[], což je i dle nejnovější dokumentace stále povoleno a v pořádku.
Ve formulářích používám $form->onSuccess[] málokdy. Problém s warningem při chybějícím ovladači onSuccess[] jsem vyřešil ve vlastních abstraktních předcích FormControl a BaseForm – dvojice ze kterých dědí všechny formuláře. Tyto třídy řeší i jiné nepružnosti existující třídy Form a warning řeší nějak takhle:
if($form->onSuccess === []){
$form->onSuccess[] = fn() => null; // fix Nette warning
}
Tohle chování by mělo jít globálně vypnout někde v konfiguraci projektu.
Určitě by to bylo vhodné, protože warning jeden problém řeší a jiný vytváří a je otázka zda udělá více škody více než užitku? Přijít na to, že někde chybí ovladač formuláře je práce na minutu, ale přepsat po upgrade Nette všechny formuláře ve všech aplikacích může být práce na mnoho hodin.
Editoval m.brecher (5. 4. 10:31)
- Martk
- Člen | 661
Vypnout warningy jde snadno, ve FormFactory dáš toto:
$form = new Form();
$form->onSuccess[] = fn() => null;
return $form;
při nejhorším ve vlastní třídě Form. A když tvoje aplikace
nepoužívá ani jedno, tak si vytvoříš php script, který automaticky
vytvoří nové App\Forms\Form a nahradí v php souborech
use Nette\Application\UI\Form;
za
use App\Forms\Form;
.
- elnathan
- Člen | 17
Martk napsal(a):
Vypnout warningy jde snadno, ve FormFactory dáš toto:
$form = new Form(); $form->onSuccess[] = fn() => null; return $form;
při nejhorším ve vlastní třídě Form. A když tvoje aplikace nepoužívá ani jedno, tak si vytvoříš php script, který automaticky vytvoří nové App\Forms\Form a nahradí v php souborech
use Nette\Application\UI\Form;
zause App\Forms\Form;
.
Tady ale nejde o hledání toho, jak to obejít. Proč, když mám vše správně, bych měl dělat nějakou FormFactory, kterou ale k ničemu nepotřebuji? Proč bych měl nahrazovat výchozí Nette Form nějakou svojí Form třídou, když ji nepotřebuji? Jde o to, že v kódu není žádná chyba a jen „kvůli začátečníkům“ to v určitých případech (popsáno v předchozím komentáři) hlásí úplně zbytečně warning. Obcházet to není správný postup (což se přesně váš FormFactory), přepisovat validní formuláře zbytečným kódem taky ne. Tato validace by prostě měla jít vypnout v konfiguraci (neon) nebo tam nebýt vůbec, jelikož bohužel nefuguje dobře s roboty.
- David Grudl
- Nette Core | 8218
elnathan napsal(a):
Tahle featura je taková nedomyšlená:
Všude používám ->onClick[], což je i dle nejnovější dokumentace stále povoleno a v pořádku. Všechny formuláře jej mají korektně vyplněný, takže nepotřebuji žádné upozorňování pro začátečníky (jak tomu říkáte). Pro běžného návštěvníka vše funguje, ale pak na web přijdou roboti, kteří se snaží projít formulářem a odesílají prázdný POST případně GET ?do=form-submit (podle typu). Hádejte, co se stane? Vyhodí to tuto chybu, protože chybí informace o kliknutí na tlačítko a tudíž to hlásí, že neexistuje handler.
Chyby prosím hlas na GitHub, tady si jich všimnu spíš náhodou.
Opraveno