Autor Zpráva
anonymníí
Profil *
Ahoj,

je prosím nějak možné zjistit, jakým ze submitů byl odeslán formulář?

Schéma je následující:
<form onsubmit="return validate(this);">
    ... <!-- formularova pole -->

    <input type="submit" name="submit" value="Odeslat">
    <input type="submit" name="submit" value="Submit 2">
</form>

Potíž je v tom, že když kliknu na "Odeslat", potřebuju validovat data ve formuláři (proto onsubmit na formu). Při druhém submitu je validovat nepotřebuji/nechci.

Moje myšlenka tak je přidat do JS podmínku, kterým submitem byl form odeslán (případně jako další parametr validační funkce).

Jak na to?
Napadlo mě obejít to jedním submitem a jedním buttonem, ale pořád to neřeší situaci, kdy bych těch submitů bylo více, třeba 5 a takto obejít by to nešlo.

Děkuji za rady.


Druhý submit má samozřejmě jiné jméno (name), překlepl jsem se v příkladu výše.
_es
Profil
Nedávaj elementom formulára name=submit, inak nebude fungovať metóda formulára submit. Okrem udalosti formulára onsubmit použi aj udalosť onclick odosielacieho tlačítka či tlačítiek, aby si dosiahol potrebné overenie.
anonymníí
Profil *
_es:
potřebuji používat metodu submit? Nepotřebuji v tomto případě, ne?

Okrem udalosti formulára onsubmit použi aj udalosť onclick odosielacieho tlačítka či tlačítiek, aby si dosiahol potrebné overenie.
to je dobrý postřeh, vyzkouším.

Co se aplikuje v případě, že formulář odešlu enterem? První submit, který je ve formu? Mohl bych vyzkoušet, ale nejsem si jist, jestli v nějakém prohlížeči neexistuje nějaká vyjímka, apod.

Díky.
_es
Profil
anonymníí:
Co se aplikuje v případě, že formulář odešlu enterem?
Čo tak zapojiť do uvažovania aj to, čo sa kedy „neaplikuje“?

potřebuji používat metodu submit? Nepotřebuji v tomto případě, ne?
Možno áno, možno nie, viď napr. Jméno prvku jako "submit", jquery - automatické odesláné formuláře po vypršení času. Dať formulárovému prvku name=submit má asi taký zmysel, ako keď tu niektorí experti dávajú name=name, id=id a pod. Čo ak by si chcel spraviť skriptom ovládané tlačítko (<input type=button>) odosielajúce formulár? To je tiež jeden zo spôsobov riešenia tohoto dotazu.
anynomníí
Profil *
_es:
Čo tak zapojiť do uvažovania aj to, čo sa kedy ‚neaplikuje‘?
To nechápu, co tím myslíš? Že enter není ekvivalentem k odeslání formuláře submitem, ale další možnost (tzn. při dvou submitech jsou tři možné způsoby odeslání - enter (validovat vstup), 1. submit (validovat vstup), 2. submit (nevalidovat vstup).

Z toho mi vyplývá, že onsubmit na formuláři být musí, právě kvůli tomu odeslání enterem, aby se vstup validoval.

Dať formulárovému prvku name=submit má asi taký zmysel, ako keď tu niektorí experti dávajú name=name, id=id a pod.
To si nemyslím. Kvůli PHP zpracování mají všechny formulářové submity se stejnou funkcí stejný name, nevidím na tom nic špatného. Pokud mám políčko pro vstup, kde očekávám jméno, nevidím na name=name nic špatného, ba naopak. Pokud potřebuji políčko pro vložení identifikátoru (ne ID v databázi, ale prostě nějaké ID), a potřebuji k danému poli připojit label (a pole v něm není vnořené), je pak i id=id naprosto korektní zápis.

Tento útok byl tedy naprosto zbytečný.

Čo ak by si chcel spraviť skriptom ovládané tlačítko (<input type=button>) odosielajúce formulár?
Nechci, to jsem psal výše. Nyní by to teoreticky byla možnost, ale neřeší situaci, kdy submitů bude více. Toto tedy není relevantní.

Dotaz z [#1] tedy stále trvá, řešení naznačené v [#2] řešením není (onclick použít nejde právě kvůli enteru).
_es
Profil
anynomníí:
To nechápu, co tím myslíš?
Že je trebárs nejasné, čo myslíš pod „aplikovaním“, či „aplikovanie“ onsubmit, „aplikovanie“ onclick, „aplikovanie“ odoslania formulára a pod. Keď si to ujasníš, môžeš uvažovať nad tým, čo sa kedy „aplikuje“ či „neaplikuje“.

Kvůli PHP zpracování mají všechny formulářové submity se stejnou funkcí stejný name, nevidím na tom nic špatného.
Akosi nevidím zmysel v tom, dávať na formulár viacero odosielacích tlačítiek s rovnakou funkciou. Ak by mali rozdielne funkcie, tak je logické im dať rozdielne názvy - budú rozlíšiteľné aj bez JS - len na serveri.

Dotaz z [#1] tedy stále trvá, řešení naznačené v [#2] řešením není (onclick použít nejde právě kvůli enteru).
Neviem, aké použitie enteru myslíš. Ak má tlačítko focus, tak sa vyvolá pri stlačení enteru aj jeho udalosť onclick. Ak myslíš odoslanie enterom z nejakého textového inputu, tak sa vyvolá udalosť onsubmit.

Toto tedy není relevantní.
Samozrejme, že je. Ak by si si metódu submit vedome neznefunkčnil, mohol by si využiť aj to, že nevyvolá udalosť onsubmit. V každom prípade máš dosť rád na vyriešenie a to aj viacerými spôsobmi.
anonymnníí
Profil *
_es:
dávať na formulár viacero odosielacích tlačítiek s rovnakou funkciou.
Každý má jinou funkci, proto jsou tam dva.

Ak by mali rozdielne funkcie, tak je logické im dať rozdielne názvy
Však v jednom fomruláři mají jiné názvy, vit dodatek k #1.

budú rozlíšiteľné aj bez JS - len na serveri.
Potřebuju JS validaci, na serveru validace problém není. Možná proto jsme v sekci JS a řeším JS validaci.
_es
Profil
anonymnníí:
Ak som to pochopil, chceš práve na konkrétne tlačítko „JS validáciu“ nepoužiť. Najjednoduchšie, tak aby tlačítko fungovalo aj bez JS, by mohlo byť:
<input type="submit" name="tlac2" value="tlac2" onclick="this.form.submit();return false">
Samozrejme, funkčnosť metódy submit nesmie byť „sabotovaná“.

, nevidím na tom nic špatného. Pokud mám políčko pro vstup, kde očekávám jméno, nevidím na name=name nic špatného, ba naopak.
Je to hlúpy nápad, podobne ako sa trebárs v JS snažiť pomenovať premennú while. Na rozdiel od toho prípadu je to však potenciálny zdroj ťažko odhaliteľných chýb. Skús si vyskúšať:
<form name=f onsubmit="alert(this.name); return false;">
ak je vo formulári element s name=name a ak tam taký element nie je.
Chamurappi
Profil
Reaguji na anonymníího, anynomníího a anonymnníího:
Co se aplikuje v případě, že formulář odešlu enterem? První submit, který je ve formu?
Nevím, co myslíš aplikováním. Prakticky odjakživa platí, že enter odesílá formulář prvním tlačítkem — jeho jméno=hodnota se posílá na server, na něm vzniká onclick. Můžeš si to zkusit.

Jedinou výjimkou je (zřejmě jen starší) Explorer: když je ve formuláři pouze jedno editovatelné políčko, tak se tlačítko enterem neproklikne a formulář se stejně odešle. Svého času této divné vlastnosti využíval Google, že zobrazoval uživatelům mačkajícím tlačítko tip ve smyslu „formulář můžete odeslat klávesou Enter“.

Řešení, které navrhuje _es, je možné také. Ale to bys nesměl trvat na tom, aby políčko mělo name="submit" (což je opravdu neprozíravé, přestože zatím to možná ničemu nevadí).
_es
Profil
Chamurappi:
Prakticky odjakživa platí, že enter odesílá formulář prvním tlačítkem — jeho jméno=hodnota se posílá na server, na něm vzniká onclick.
Iba že by malo focus druhé tlačítko. Nie je jasné, či anonymnníí nevedel, že onclick sa dá vyvolať aj klávesnicou, alebo myslel odoslanie enterom z iných formulárových prvkov. Je vôbec isté, že vo všetkých prehliadačoch vznikne pri odoslaní formulára z iného formulárového prvku enterom udalosť onclick práve na prvom odosielacom tlačítku, alebo že vôbec udalosť na tlačítku vznikne (iné ako desktopové prehliadače a pod.)? Má to „oporu“ v nejakých špecifikáciách?
anonymníí
Profil *
Chamurappi:
Prakticky odjakživa platí, že enter odesílá formulář prvním tlačítkem
Děkuji, to je to, co jsem potřeboval vědět.

Vyzkoušení, jak jsem psal, není dost dobře možné, nemám a neznám chování všech prohlížečů ve všech verzích. Poznámka o (asi jen starším) IE je pro mě velice platná, to bych stejně neodzkoušel.

_es:
alebo myslel odoslanie enterom z iných formulárových prvkov.
Přesně tak. Mám formulář o X textových inputech a myslel jsem stisk enteru, když jsem v některém z těch textových inputů. O situaci, kdy jde o focus submit inputu mi nejde.

Jak to tedy je v tomto případě (stisk enteru při focusu některého (nejediného) textového inputu)? Je to totéž jak prokliknout první submit input? To asi ne.
_es
Profil
anonymníí:
Je to totéž jak prokliknout první submit input? To asi ne.
Podľa Chamurappiho vraj áno - až na nejakú výnimku nejakého staršieho IE. Spoľahlivé by mohlo byť riešenie z [#8], return false je potrebné pre niektoré prehliadače, ktoré „stihnú“ okrem udalosti onclick aj udalosť onsubmit.
1Pupik1989
Profil
Já bych zkusil v onsubmitu použít "document.activeElement".

Píšou o něm i na stránkách Mozilly

Při enteru se totiž nemusí nutně prokliknout první button. Záleží na focusu. A právě na to vlastnost "document.activeElement". V té se uchovává aktivní element.

Já to řešil trochu jinak.

var target_button;

var el = document.getElementById('formular');
el.onsubmit = function(){
  var clicked_button = document.activeElement;
  
  console.log(target_button);
  
  return false;   
};

var button_good = document.getElementById('good');
var button_bad = document.getElementById('bad');

button_good.onfocus = function(e){
  target_button = e.target;
};

button_bad.onfocus = function(e){
  target_button = e.target;
};

Jediné co jsem si musel uvědomit, že vždycky jeden submit musí být aktivní. Dalo to ale hodně googlení. :D

Chamurappi:
Prakticky odjakživa platí, že enter odesílá formulář prvním tlačítkem

Čili to nemusí platit v žádném prohlížeči nebo jen při prvním odeslání formuláře.
_es
Profil
1Pupik1989:
Při enteru se totiž nemusí nutně prokliknout první button.
Podľa [#9] Chamurappi vraj áno.

Záleží na focusu. A právě na to vlastnost "document.activeElement". V té se uchovává aktivní element.
To by bolo len ďalšie zbytočné komplikovanie a ďalšia nekompatibilita, lebo IE nielen vyvolá kliknutie na tlačítko, ale aj zmení focus a tým aj zmení document.activeElement.
1Pupik1989
Profil
_es:
To by bolo len ďalšie zbytočné komplikovanie a ďalšia nekompatibilita
Nevidím na tom nic nekompatibilního. Samozřejmě jsem myslel použít jen jednu variantu. Osobně používám tu druhou co jsem napsal. Žádné kliknutí pak není třeba odchytávat. Akorát do proměnné "target_button" dám první submit button. Pro jistotu kdyby někdo odesílal enterem z textového pole.
Chamurappi
Profil
Omlouvám se, pokud jsem příspěvek [#9] napsal nesrozumitelně.


Reaguji na anonymníího:
Poznámka o (asi jen starším) IE je pro mě velice platná
Má-li tvůj formulář víc jak jedno textové políčko, tak se tě tato anomálie netýká.


Reaguji na 1Pupika1989:
Při enteru se totiž nemusí nutně prokliknout první button. Záleží na focusu.
Má-li focus jiné tlačítko, tak pak není, o čem spekulovat, enter vyvolá onclick na něm, to je přání uživatele srovnatelné s tím, jako by na to jiné tlačítko kliknul. Bavili jsme se zde o tom, co se děje, pokud uživatel stiskne enter při vyplňování — tedy při situaci, kdy běžně vzniká onsubmit. Já tvrdím, že se enterem proklikne první tlačítko. Tím jsem si stoprocentně jistý a miliony serverových skriptů rozhodujících se podle toho, zda jim přijde jméno=hodnota odesílacího tlačítka, by bez této vlastnosti nefungovaly správně.

O nepatrný ždibec méně jsem si jistý, že vznikne i událost onclick na tom prvním tlačítku. Proto jsem vyrobil výše odkázanou ukázku, aby kdokoliv mohl otestovat svoji armádu testovacích prohlížečů a prokázat, zda se pletu.

Tvému hraní s vlastností document.activeElementem bych věřil méně, než obyčejnému onclicku na tlačítku, částečně kvůli dávným zkušenostem s ní v Exploreru, částečně kvůli nulovým zkušenostem v ostatních prohlížečích (netušil jsem, že už ji znají, díky za informaci).

e.target
Nepojede v Exploreru 8 a nižším.


Reaguji na _es:
Má to ‚oporu‘ v nejakých špecifikáciách?
Netuším. Ani nevím, kde jsem vzal své (silné) přesvědčení, že tomu tak spolehlivě je. Ale prostě to tak je :-)
1Pupik1989
Profil
Chamurappi:
Nepojede v Exploreru 8 a nižším.

To jsem napsal ve fofru. Řešení je jednoduché.

button_good.onfocus = function(){
  target_button = button_good;
};

Co jsem si všiml, tak třeba IE8 při kliku na textové pole ve formuláři automaticky označí první submit. Takže tam není co řešit. Zdá se, že onclick bude opravdu asi jednodušší. Netušil jsem, že i při entru se zavolá onclick, měl jsem pořád zafixované, že ta událost platí jen pro klik myší. Díky za info.

je tedy pravda, že převážně při řešení tohoto problému jsem viděl něco ve stylu:
<input type="submit" onclick="validate(1);">
<input type="submit" onclick="validate(2);">

a

function validate(id){
  if(id === 1){
    //možnost 1
  }else if(id === 2){
    //možnost 2
  }
};
_es
Profil
1Pupik1989 [#17]:
Kód zo [#17] je problematický v tom, že po spustení funkcie validate nastane odoslanie formulára bez ohľadu na to, čo tá funkcia spraví. A ak by si to aj vylepšil, tak nie je isté, v akom poradí budú udalosti odoslania a kliknutia spustené v rôznych prehliadačoch. Riešenie je niečo ako v [#8], prípadne so zamenením za type=button, alebo sa spoľahnúť na chovanie prehliadačov, popísané Chamurappim.
1Pupik1989
Profil
No to tak úplně není pravda. Nevím jak IE < 8, ale IE8 vyvolá onclick na tom prvním submit elementu, čili zavolá na prvním buttonu onclick. Pokud ie zavolá událost na jiném buttonu, tak se ozve správně. Kontrolování onkeyup asi neuškodí. Nejspíš tam bude asi navíc. Co jsem četl, tak se onclick vyvolá i v IE5+.
_es
Profil
1Pupik1989:
Čo z toho, že sa zavolá onclick, keď aj tak dôjde vždy k normálnemu odoslaniu formulára, lebo ide o input s type=submit a normálne odoslanie formulára nie je zrušené?
1Pupik1989
Profil
"return false" v onsubmitu samozřejmě mám, akorát jsem sem nedal celý kód. V Chamurappiho ukázce je, takže jsem to nepovažoval za nutnost. Akorát jsem psal, jaké volání funkcí jsem nacházel na internetu při vyhledávání.
_es
Profil
1Pupik1989:
"return false" v onsubmitu samozřejmě mám
Akurát. že nie je isté, či sa onclick vykoná pred alebo za onsubmit a ak je v onsubmit return false „natvrdo“- bez podmienok, tak zase treba použiť formulár.submit(), čo koliduje s tým, že anonymníí tam chce mať tlačítko s name=submit.
1Pupik1989
Profil
_es:
Tak tam je jediná možnost. Přejmenovat v běhu name inputu a uložit si submit funkci formuláře do proměnné. Teoreticky by to mělo jít. Prakticky jsem to netestoval.

Ať se onclick vyvolá před nebo po onsubmit by mělo být jedno. return false v onsubmit by mělo každopádně blokovat odeslání.
_es
Profil
1Pupik1989:
by mělo být jedno. return false v onsubmit by mělo každopádně blokovat odeslání.
Tak ale predsa ten formulár nie je len na parádu a niekedy by snáď odoslaný byť mal. Kde a kedy?
1Pupik1989
Profil
No jo, to už bude větší sranda.

Onsubmitu bych nechal funkci, která vrací false. A potom v jednotlivých onclickách nastavoval onsubmit. Formulář bych odeslal a vrátil zpět původní funkci. Čili v reálu by byly 3 cachované funkce. Jedna defaultní a dvě dle submitu.

Nebo lépe. Input submit co nemá blokovat odeslání, tak prostě funkci nastaví na nul.

Moje vysvětlení není zrovna extra. Až budu u pc, tak sem dám příklad.
Chamurappi
Profil
Reaguji na 1Pupika1989:
Řešení je jednoduché.
Jo, použít this.

Input submit co nemá blokovat odeslání, tak prostě funkci nastaví na nul.
Jakmile se pak uživatel v prohlížeči vrátí zpět a prohlížeč mu obnoví kompletní DOM tak, jak z něj odešel, bude mít onsubmit nastavený na null i v případě, že klikne na první tlačítko.


Reaguji na _es:
nie je isté, či sa onclick vykoná pred alebo za onsubmit
Myslím, že před a že to je jisté. Vylepšená ukázka.
Pokud se stornuje onclick odesílacího tlačítka, formulář se nezačne odesílat, tudíž nedojde k onsubmitu.
_es
Profil
Chamurappi:
Pokud se stornuje onclick odesílacího tlačítka
Vtedy je jedno, aké je teoreticky poradie onclick alebo onsubmit, ide o to, že je zrušená východzia akcia kliknutia na tlačítko, preto nenastane odoslanie formulára. Prehliadač ešte pred odoslaním vykoná všetky udalosti, ktoré majú pred tým nastať.

„nie je isté, či sa onclick vykoná pred alebo za onsubmit
Myslím, že před a že to je jisté.
V jednej literatúre (knihy.cpress.cz/javascript-pro-webove-vyvojare.html) je písané, že to vraj u niektorých prehliadačoch hrozí. Nepíše však pri ktorých, možno ide o už nepoužívané verzie, alebo je problém v tom, že nepoužíva na registráciu ovládačov udalostí atribúty onclick a onsubmit, ale gist.github.com/objectfoo/4144898 - EventUtil.addHandler.
1Pupik1989
Profil
Pokud se onclick provede pře onsubmitem, tak by teoreticky mohlo fungovat co jsem myslel.

Zhruba jako je to v ukázce.

Výchozí u onsubmitu zůstane hodnota null.
Chamurappi
Profil
Reaguji na _es:
ide o to, že je zrušená východzia akcia kliknutia na tlačítko, preto nenastane odoslanie formulára
Ale nenastane ani ten onsubmit. Kliknutí (případně vyvolání enterem) je základní operace, jejímž důsledkem je teprve odeslání formuláře či odchod ze stránky. Pokud se výchozí děj stornuje, nevznikají další události — je to stejné, jako kdyby se nekliklo vůbec.

V jednej literatúre […] je písané, že to vraj u niektorých prehliadačoch hrozí.
Knihu jsem nečetl, ale předpokládám, že tam autor naráží na nejisté pořadí při probublávání při zpracování událostí přes attachEvent/addEventListener. U přiřazování do onudálost by pořadí mělo být jisté (tj. zevnitř ven). Navíc toto ani není bublání, je to obyčejná návaznost akcí na sebe: enter vyvolá klávesové události, ty (nejsou-li stornovány) vyvolají klik na tlačítku, ten (není-li stornován) vyvolá odeslání formuláře, to (není-li stornováno) vyvolá odchod ze stránky. Takhle mi to zní nejrozumněji a věřím, že to tak opravdu funguje. Přišlo by mi nepraktické a hloupé, kdyby enter vyvolal třeba rovnou onunload, i když by se v onkeydown jeho výchozí činnost stornovala.


Reaguji na 1Pupika1989:
Zhruba jako je to v ukázce.
Ano. Stejně tak si lze při kliku na konkrétní tlačítko nastavit nějakou proměnnou a tu pak v onsubmitu kontrolovat.

Mimochodem, přijde mi docela hloupé, že prohlížeče kolekci dat, kterou si připravují k odeslání, nezpřístupňují skriptům v nějakém pohodlném balíčku. Kdyby čistě hypoteticky existovalo třeba něco jako event.formData a v tom prostý objekt { jméno: "Hodnota", jménoTlačítka: "Value z prokliknutého tlačítka" }, to by bylo moc fajn…
_es
Profil
Chamurappi:
Knihu jsem nečetl, ale předpokládám, že tam autor naráží na nejisté pořadí při probublávání při zpracování událostí přes attachEvent/addEventListener.
Nie, on len používa skoro od začiatku knihy tie svoje "vylepšené" metódy, možno ani nevie, z čoho tá nekompatibilita poradia udalostí vznikla a že má jednoduché riešenie v použití „zastaralého“ „nevylepšeného“ spôsobu.

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0