Input type = "submit", the onclick handler calls this.form.submit () and does not return a value

UPDATE: Please read the entire question carefully before you decide to answer it. I do not ask about the appropriateness of using the built-in event handler in the working code and I do not ask about the best way to achieve the result promised in the article to which I refer. This is a matter of Javascript semantics and browser implementation details, not coding best practices.

Sounds like a nightmare, right?

However, I found a few online tips that recommend doing just such a thing to prevent duplicate form submission:

<input type="submit" onclick="this.disabled=true; this.value='Sending, please wait...'; this.form.submit();" /> 

Leaving aside any discussion of the evil of the built-in event handlers, I see the following problems:

  1. The tag type is "submit" so submitting a form containing it is its default behavior;
  2. The onclick handler explicitly submits the containing form;
  3. The onclick handler does not return false to prevent the default behavior (see 1).

Intuitively, I think that clicking on this element would do exactly the opposite of what the article claims - that is, submit the form twice, once as a result of an explicit call to submit() , and then again as an unsuppressed default value. "submit" -typed control behavior.

On the other hand, I wrote a tiny PHP script (below) and tested it both in Firefox and Safari (at the moment I have only available browsers), and it writes only one log entry per click on the button:

 <html> <head></head> <body> <?php if (isset($_GET['action']) && $_GET['action'] == 'submit') { $s = 'Got form submission at ' . time(); error_log($s); echo $s; } else { ?> <form action="http://localhost/~hephaestus/phptests/submittest.php?action=submit" method="post"> <input type="submit" onclick="this.disabled=true; this.value='Sending, please wait...'; this.form.submit();" /> </form> <?php } ?> </body> </html> 

So these two browsers really do the “right” things (where the “right” ones are defined in some document that I either did not see or did not read carefully enough), which means that my problem analysis is incomplete or incorrect?

Or is my analysis correct - does this mean that the observed individual views are the result of browser developers using special case logic to save naive coders from themselves?

UPDATE:

In an attempt to empirically verify @sourcecode's assertion that the form.submit() method is a kind of “second submit button” on the form and thus obeys the rule specified in HTML4 section 17.13.2. To use only one “successful” submit button, I made several additions to my PHP test script:

 <?php if (isset($_GET['action']) && $_GET['action'] == 'submit') { $s = 'Got form submission at ' . time() . ', tellme = ' . $_POST['tellme']; error_log($s); echo $s; } else { ?> <form action="http://localhost/~hephaestus/phptests/submittest.php?action=submit" method="post"> <input type="hidden" id="tellme" name="tellme" value="0" /> <input type="submit" onclick="this.disabled=true; this.value='Sending, please wait...'; this.form.submit(); document.getElementById('tellme')=1;" /> </form> <?php } ?> 

In Firefox, this code creates a single entry in the error log:

Got a timestamp form, tellme = 1

which really assumes that the method call is somehow replaced by the internal event-driven behavior of the control.

Also, if I add an extra return false; after setting the tellme value to 1 (thereby preventing the propagation of the click event and thus preventing the control from behaving internally), the only error log entry will be:

Got the form at the timestamp, tellme = 0

This means that in this case, the view was the result of calling this.form.submit() .

On the other hand, when I try the same two options in Safari, each of them gives me the same error log entry:

Got the form at the timestamp, tellme = 0

So in the case of Safari, a method call always takes precedence over event-driven dispatch - perhaps because this happens earlier.

It. Just. Amazing .: - /

Further update: I got the opportunity to test this on IE 8.0 on Windows NT 5.1.

IE 8 reflects Safari behavior, i.e. The form.submit() method always takes precedence over even form.submit() .

Although this is hardly relevant today, I also realized that I have an ancient IE 5.22 on an even older PowerPC iMac running OS X 10.4.11. An interesting historical little thing here is that IE5 works in exactly the opposite of how IE8 works: event-driven dispatch always replaces the form.submit() method - even when the click event was forbidden to propagate with a return false; at the end of the onclick handler! (However, I did not delve into whether this was a mistake or a function. I have not yet carried out and, possibly, never!) I did not run a test to determine if this is an obstacle to blocking events or trying to do something “smart”. ".)

However, regardless of inconsistencies, both IEs only send one send.

My preliminary (well, at the moment, actually, pretty solid) conclusion is that the exact relationship between the submit -typed control and the DOM form.submit() method is not well-defined, and that browser implementations in lack of any clear directions, usually do what they consider best (see, for example, @Boris Zbarsky answer ).

At least in the cases of Firefox, Safari, and IE, their developers foresaw the possibility that both the event and the method call could compete for sending the same form, and took steps (albeit different - to a large extent using the gamma) to ensure that only one of them will succeed.

(I would still like to receive additional answers from people who know the various internal components of the browser well enough to comment, or who have downloaded my simple PHP script using browsers other than those I tested.)

+6
source share
4 answers

Gecko (Firefox) certainly detects multiple views and undoes old ones when new ones appear. See The mPendingSubmisson Member at http://hg.mozilla.org/mozilla-central/file/c4abfca219e5/content/html/content/src/nsHTMLFormElement.h and its processing at http://hg.mozilla.org/mozilla- central / file / c4abfca219e5 / content / html / content / src / nsHTMLFormElement.cpp (for example, in nsHTMLFormElement::Submit and nsHTMLFormElement::PostHandleEvent (the latter is what is called from the default action material for send controls).

From the point of view of the specification, it is not clear to me that the specification is necessarily normal, but it lives at http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms. html # concept-form-submit and assumes that both submissions will occur, but later can effectively cancel the previous ones due to the internal details of the "navigation" algorithm. I sent https://www.w3.org/Bugs/Public/show_bug.cgi?id=20580 to sort the spec.

+3
source

This is the w3 org recommendation:

  • If the form contains more than one submit button , only a successful confirmation button is successful .

    The same thing happens with the Submit Click function and local JS form.Submit, the submit function is activated, not form.submit. Because submit is primary, and JS function is secondary.
    you can find out more here link
+1
source

NEVER run a script in onclick submit and, of course, DO NOT submit a form !!! Also, if you turn off the button, the feed can be stopped!

If the code in the article works, it’s just luck, and I assume that many browsers enter a racing state with the send button disabled and the send event by clicking this disabled button.

Here is a built-in suggestion on what should work in any browser

 <form action="..." method="post" onsubmit="document.getElementById('subbut').innerHTML='Sending, please wait...'"> <span id="subbut"><input type="submit" /></span> </form> 

and just as unobtrusively:

 <html> <head> <script> window.onload=function() { document.getElementById("form1").onsubmit=function() { document.getElementById('subbut').innerHTML='Sending, please wait...'; } } </script> </head> <body> <form action="..." method="post" id="form1"> <span id="subbut"><input type="submit" /></span> </form> </body> <html> 
+1
source

I would suggest that you would need to use the stopPropogation() method. Ideally, you could call a function from your onclick handler instead of making it inline .. fooobar.com/questions/28532 / ...

0
source

All Articles