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>
Andrezj's pretty much got it nailed... but here's an easy cross-browser solution.
Take a form like this:
and refactor to this:
Since the W3C spec indicates multiple submit buttons are valid, but omits guidance as to how the user-agent should handle them, the browser manufacturers are left to implement as they see fit. I've found they'll either submit the first submit button in the form, or submit the next submit button after the form field that currently has focus.
Unfortunately, simply adding a style of display: none; won't work because the W3C spec indicates any hidden element should be excluded from user interactions. So hide it in plain sight instead!
Above is an example of the solution I ended up putting into production. Hitting the enter key triggers the default form submission is behavior as expected, even when other non-default values are present and precede the default submit button in the DOM. Bonus for mouse/keyboard interaction with explicit user inputs while avoiding javascript handlers.
Note: tabbing through the form will not display focus for any visual element yet will still cause the invisible button to be selected. To avoid this issue, simply set tabindex attributes accordingly and omit a tabindex attribute on the invisible submit button. While it may seem out of place to promote these styles to !important, they should prevent any framework or existing button styles from interfering with this fix. Also, those inline styles are definitely poor form, but we're proving concepts here... not writing production code.
HTML 4 does not make it explicit. The current HTML5 working draft specifies that the first submit button must be the default: