If a form is submitted but not by any specific button, such as
- by pressing Enter
- using
HTMLFormElement.submit()
in JS
how is a browser supposed to determine which of multiple submit buttons, if any, to use as the one pressed?
This is significant on two levels:
- calling an
onclick
event handler attached to a submit button - the data sent back to the web server
My experiments so far have shown that:
- when pressing Enter, Firefox, Opera and Safari use the first submit button in the form
- when pressing Enter, IE uses either the first submit button or none at all depending on conditions I haven't been able to figure out
- all these browsers use none at all for a JS submit
What does the standard say?
If it would help, here's my test code (the PHP is relevant only to my method of testing, not to my question itself)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
</head>
<body>
<h1>Get</h1>
<dl>
<?php foreach ($_GET as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<h1>Post</h1>
<dl>
<?php foreach ($_POST as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<form name="theForm" method="<?php echo isset($_GET['method']) ? $_GET['method'] : 'get'; ?>" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
<input type="text" name="method" />
<input type="submit" name="action" value="Button 1" onclick="alert('Button 1'); return true" />
<input type="text" name="stuff" />
<input type="submit" name="action" value="Button 2" onclick="alert('Button 2'); return true" />
<input type="button" value="submit" onclick="document.theForm.submit();" />
</form>
</body></html>
If you submit the form via Javascript (i.e.
formElement.submit()
or anything equivalent), then none of the submit buttons are considered successful and none of their values are included in the submitted data. (Note that if you submit the form by usingsubmitElement.click()
then the submit that you had a reference to is considered active; this doesn't really fall under the remit of your question since here the submit button is unambiguous but I thought I'd include it for people who read the first part and wonder how to make a submit button successful via JS form submission. Of course, the form's onsubmit handlers will still fire this way whereas they wouldn't viaform.submit()
so that's another kettle of fish...)If the form is submitted by hitting Enter while in a non-textarea field, then it's actually down to the user agent to decide what it wants here. The specs don't say anything about submitting a form using the enter key while in a text entry field (if you tab to a button and activate it using space or whatever, then there's no problem as that specific submit button is unambiguously used). All it says is that a form must be submitted when a submit button is activated, it's not even a requirement that hitting enter in e.g. a text input will submit the form.
I believe that Internet Explorer chooses the submit button that appears first in the source; I have a feeling that Firefox and Opera choose the button with the lowest tabindex, falling back to the first defined if nothing else is defined. There's also some complications regarding whether the submits have a non-default value attribute IIRC.
The point to take away is that there is no defined standard for what happens here and it's entirely at the whim of the browser - so as far as possible in whatever you're doing, try to avoid relying on any particular behaviour. If you really must know, you can probably find out the behaviour of the various browser versions but when I investigated this a while back there were some quite convoluted conditions (which of course are subject to change with new browser versions) and I'd advise you to avoid it if possible!
From your comments:
I drop an
<input type="hidden" value="form_name" />
into each form.If submitting with javascript: add submit events to forms, not click events to their buttons. Saavy users don't touch their mouse very often.
This can now be solved using
flexbox
:HTML
CSS
Explaination
Using flex box, we can reverse the order of the elements in a container that uses
display: flex
by also using the CSS rule:flex-direction: row-reverse
. This requires no CSS or hidden elements. For older browsers that do not support flexbox, they still get a workable solution but the elements will not be reversed.Demo
http://codepen.io/Godwin/pen/rLVKjm
my recipe:
It will send the default hidden field if none of the buttons are 'clicked'.
if they are clicked, they have preference and it's value is passed.
Strange that the first button Enter goes always to the first button regardless is visible or not, e.g. using jquery
show/hide()
. Adding attribute.attr('disabled', 'disabled')
prevent receiving Enter submit button completely. It's problem for example when adjusting Insert/Edit+Delete button visibility in record dialogs. I found less hackish and simple placing Edit in front of Insertand use javascript code:
EDIT: Sorry, when writing this answer I was thinking about submit buttons in the general sense. The answer below is not about multiple
type="submit"
buttons, as it leaves only onetype="submit"
and change the other totype="button"
. I leave the answer here as reference in case helps someone that can change thetype
in their form:To determine what button is pressed when hitting enter, you can mark it up with
type="submit"
, and the other buttons mark them withtype="button"
. For example: