Autor Zpráva
midlan
Profil
Ahoj. Napsal jsem si jednoduchý skriptík, který mi zakáže tlačítka při form.onsubmit. Funguje super, ale zjistil jsem, že dělá zvláštní věc. U podobného formuláře:

<input type="text" name="policko" />
<input type="submit" name="pojmenovane" value="Pojmenované odeslání" />
<input type="submit" value="Normální odeslání" />

Když odešlu pojmenovaným tlačítkem, tak to jméno toho tlačítka na server nepřijde. Po odstranění skriptu ze stránky vše funguje jak má. Testováno v IE9 a Chrome, oba se chovají stejně.

Javascript:
/*přidání vlastnosti ready do document*/
document.readyCallbacksCalled = false;
document.readyCallbacks = new Array();
document.ready = function(callback) {
  document.readyCallbacks.push(callback);
};
document.callReadyCallbacks = function() {
  if(document.readyCallbacksCalled)
    return;
  document.readyCallbacksCalled = true;
  for(var i = 0; i < document.readyCallbacks.length; i++)
    document.readyCallbacks[i]();
}
window[addEventListener? 'addEventListener':'attachEvent'](addEventListener? 'load':'onload', document.callReadyCallbacks, false);

/*následující kód způsobuje popsanou věc*/
document.ready(function() {
  for(var i = 0; i < document.forms.length; i++) {
    document.forms[i].onsubmit = function() {
      var inputy = this.getElementsByTagName('input');
      for(var i = 0; i < inputy.length; i++) {
        if(inputy[i].type == 'submit' || inputy[i].type == 'reset') {
          inputy[i].disabled = true;
        }
      }
    };
  }
});
ShiraNai7
Profil
midlan:
Když odešlu pojmenovaným tlačítkem, tak to jméno toho tlačítka na server nepřijde.

Protože ho zakazuješ a disabled prvky formuláře se neposílají. Můžeš použít hidden input namísto pojmenovaného tlačítka nebo to ošetřit skriptem (deaktivovat tlačítka ale vytvořit hidden input s jeho jménem).
midlan
Profil
ShiraNai7:
disabled prvky formuláře se neposílají
Aha, děkuju. Stydím se, že to po takové době nevím.
midlan
Profil
Tak jsem si myslel že jsem problém vyřešil, ale otestoval jsem jen v chrome a myslel že to půjde všude. Po pár dnech jsem přišel na to, že to nefunguje v IE9. Nově jsem to udělal tak, že při onclick na nějaký submit, se do vlastnosti clickedSubmitName rodičovského formuláře uloží name tlačítka na které se kliklo, potom v onsubmit formulář zkopíruju do proměnné a původní zamknu a odesílám formulář z proměnné. V chrome to jde super, ale v IE se formulář zamkne, ale virtuální neodešle. Problém bude podle možná v tvrdém kopírování prvku, nevím jak se to přesně v JS dělá, ale našel jsem prvek.cloneNode(true) tak nevím.

document.ready(function() {
  var inputs = document.getElementsByTagName('input');
  for(var i = 0; i < inputs.length; i++) {
    if(inputs[i].type == 'submit')
      inputs[i].onclick = function() {
        this.form.clickedSubmitName = this.name;
        return true;
      };
  }
  for(var i = 0; i < document.forms.length; i++) {
    document.forms[i].onsubmit = function() {
      var form_copy = this.cloneNode(true);
      var inputs_to_disable = this.getElementsByTagName('input');
      for(var j = 0; j < inputs_to_disable.length; j++)
        inputs_to_disable[j].disabled = true;
      if(this.clickedSubmitName !== '') {
        form_copy[this.clickedSubmitName].click();
      }
      else
        form_copy.submit();
      return false;
    };
  }
});
_es
Profil
midlan:
Prerob to nejako tak, aby ti stačila len udalosť onsubmit formulára, nie zachytávanie klikania na prvky formulára. Nie je isté, v akom poradí v akom prehliadači nastanú udalosti onclick a onsubmit.
midlan
Profil
_es:
Prerob to nejako tak, aby ti stačila len udalosť onsubmit formulára
Kdybych věděl jak, tak bych to tak udělal, ale nepřišel jsem na zbůsob jak v onsubmit zjistit name tlačítka, kterým to bylo odesláno. Google taky nic nenašel.

Nie je isté, v akom poradí v akom prehliadači nastanú udalosti onclick a onsubmit.
Tohle tu nefunkčnost v IE nezpůsobuje, onlclick se vykoná jako první.
Chamurappi
Profil
Reaguji na midlana:
Tipnul bych si, že Exploreru vadí, že vyvoláváš click() na elementu, který není uvnitř dokumentu.

potom v onsubmit formulář zkopíruju do proměnné
Kopie nemusí být stoprocentně shodná s originálem. Tipnul bych si, že třeba uploadovaný soubor se ztratí.

Celá tvoje akce mi připadá podivná. Proč chceš formulářové prvky zakázat, když je chceš i odeslat? Znáš rozdíl mezi disabled a readonly?
midlan
Profil
Chamurappi:
Proč chceš formulářové prvky zakázat, když je chceš i odeslat?
původně jsem chtěl jen zakázat odesílací tlačítka, protože některé formuláře se posílají déle (typicky ty kde se na serveru posílá e-mail), aby nedočkaví uživatelé neodeslali formulář dvakrát. Ostatní inputy už jsem zakázal jen pro efekt.
ShiraNai7
Profil
Když už tak doporučuji spíš nějaký overlay, než haprovat s inputama.

Např. http://jquery.malsup.com/block/#element , pokud využíváš jQuery a nechce se ti to programovat.
Chamurappi
Profil
Reaguji na midlana:
aby nedočkaví uživatelé neodeslali formulář dvakrát
formulář.onsubmit = function()
{
  this.onsubmit = function()
  {
    return false;
  };
};
Proč v tom hledat vědu?
midlan
Profil
ShiraNai7:
Když už tak doporučuji spíš nějaký overlay, než haprovat s inputama.
>
Např. http://jquery.malsup.com/block/#element , pokud využíváš jQuery a nechce se ti to programovat.
jQuery už nepoužívám, ale overlay není špatné řešení

Chamurappi:
Proč v tom hledat vědu?
Tak tohle mě fakt nenapadlo. Sice to nemá ten optický efekt zamknutých submitů, ale účel to splní. Asi to nasadím :)
_es
Profil
midlan:
Sice to nemá ten optický efekt zamknutých submitů, ale účel to splní.
To „zamknutie“ si tam predsa môžeš doplniť.
Chamurappi
Profil
Reaguji na midlana:
Sice to nemá ten optický efekt zamknutých submitů, ale účel to splní.
Zakázat ovládací prvky klidně můžeš o chvíli později. Třeba za 1 milisekundu.

Nicméně všechna tahle opatření mají vedlejší efekt v tom, že zabrání člověku formulář znovu odeslat i z jiných důvodů, než je nedočkavost. Třeba mu vypadne připojení, nebo něco jiného selže, ocitne se na chybové stránce, zmáčkne zpět … a dnešní moudré prohlížeče nepřenačtou stránku znovu, drží si ji v paměti přesně tak, jak ji člověk opustil, v tomto případě se zablokovaným formulářem.
midlan
Profil
Chamurappi:
Zakázat ovládací prvky klidně můžeš o chvíli později. Třeba za 1 milisekundu.
Chtěl jsem aby to bylo vázané na eventy, protože nevím jak je to v JavaScriptu s prodlevami před vykonáním události. Ale vy s tím budete mít určitě větší zkušenost.

Chamurappi:
Nicméně všechna tahle opatření mají vedlejší efekt v tom, že zabrání člověku formulář znovu odeslat i z jiných důvodů, než je nedočkavost. Třeba mu vypadne připojení, nebo něco jiného selže, ocitne se na chybové stránce, zmáčkne zpět … a dnešní moudré prohlížeče nepřenačtou stránku znovu, drží si ji v paměti přesně tak, jak ji člověk opustil, v tomto případě se zablokovaným formulářem.
Tohle mě taky nenapadlo, další důvod proč nezamykat.

Tímto příspěvkem bych ukončil diskusi. Všem děkuji za rady.

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