How Forms Submit When Pressing Enter

Lately, I have been trying to perfect the x-browser behavior of pressing the enter key inside of an input field while using one of the in-page popups on Mint.com. The desired behavior is to capture the form submission and execute the same JavaScript action as is triggered by the call-to-action button. So, first I did some research trying to find out how the HTML specifications dictate that forms should behave. Unfortunately, I did not find what I was looking for, so instead I opted for writing a Test Page to run against each browser and help track my findings.

The Test Page evaluates 5 forms, each using a different submittal `button` to trigger a form submission. The first test is an input with type submit, which should always submit the form. The second test is an input with type image, which is evaluated as a control against type submit, because it should behave the same. The button element is the third submitter evaluated. While the fourth submitter is an input of type button, which should never fire the submit event. And the fifth is another control, using an anchor as a button, to ensure that using it does not trigger any form events.

Initially, each form has one text input and one submitter (when we add a second text input, the event behavior changes). The form submit event and the submitter click event is subscribed to in JavaScript. Now going through each form, type something into the text field and hit enter. Then go back through each form and click the submitter. Executing this test plan in various browsers shows that there are 3 classes of browser behavior: FireFox & Opera, Safari and Chrome, and IE.

All browsers, when there is only one text input per form, fire the form submit event properly when typing enter, regardless of whether there is a `button` present that would normally submit the form. However, some browsers will also fire the click event of the submitter button (the exact behavior varies between browsers). And IE can require two enters before submitting, if the text input is empty. When clicking the submitter all browsers behave correctly with the input type button and the anchor tag, only firing the click event. All browsers behave uniformly when clicking input types submit and image, firing both the click and the form submit events. All non-IE browsers do the same when clicking element type button, but IE treats button elements like inputs of type button.

If that wasnt complicated enough already, the behavior changes when two or more editable inputs are added to a form. In Chrome and Safari, the behavior with multiple inputs of all 5 tests is exactly the same as with a single input field. However, in IE, FireFox, and Opera forms will no longer submit on enter unless there is a submitter present that would trigger a form submission when clicked (inputs of type submit and image work in all 3 browsers, and element button works in non-IE browsers).

My Mint.com project was further complicated, because I had click listeners on the buttons and a submit listener on the form. So in some browsers actions were being duplicated or not fired at all. Sometimes, only one editable input field exists per form and sometimes there are many. Lastly, in some cases we used "display:none" on inputs of type submit to trick the browsers into behaving correctly. But to work uniformly across all browsers, I needed a standard to use everywhere.

So looking again at the Test Page, where do all browsers intersect and behavior uniformly? This happens when there is more than one editable input field and an input of type submit (or image). All browsers will fire both the form submit event and the submitter click event when typing enter in the input or clicking on the submitter. They will also fire the click event first, so if you prevent the default event, then the form submit will never fire, so you wont need to also listen on the form submit event.

The solution is then to always have two or more editable fields in a form. If you do not need 2 or more fields, then you can add an input of type text styled "display:none" and this will still make IE behave correctly. Then all forms need to have one input of type submit, whose click event should be subscribed to. If you do not want the form to submit, then prevent the default behavior of that click event. The input of type submit needs to be displayed and visible for IE to recognize it; depending on the situation you can set its opacity to ZERO or apply these styles "width:0;border:0;height:0;padding:0" to make it invisible in the UI.

Following these guidelines will help preserve your sanity and make form submission behave uniformly across all the major browsers. Although, I did not run these tests against IE 8 yet, because my local installation is screwy. If someone has time and the inclination, please post a comment of your IE 8 results.

------
Another test was added: A button element with type submit. This introduces a new variant. In non-WebKit browsers (IE, FireFox, and Opera), the button element now works the same as a submit. However, in WebKit browsers, enter works the same as normal buttons and click works like an input with type submit.