'IE bug triggers click for 2 buttons?

I am trying to trigger the submit button when a user presses enter. Works great for all browsers except Internet Explorer 9. Strange thing is that IE insists on also triggering the click for another button I never told it to. Am I doing something wrong or how to fix this?

Below is my code. Pressing enter in IE triggers the submit click as expected, but for some reason also triggers the "some button" click (even without my keypress listener):

$('input[type=submit]').click(function () {
    alert('Submit click');
});

//SIMULATE CLICK IF ENTER PRESSED IN SEARCH
$('input[type=text]').keypress(function (event) {
    var keycode = event.keyCode || event.which;
    if (keycode == 13) $('input[type=submit]').click();
});

//ROUTE CLEAR HANDLER
$('button').click(function () {
    alert('Button click');
});

You can see the bug in action here: http://jsfiddle.net/h64xD/



Solution 1:[1]

Here are a couple of things to consider:

IE9 counts the <button/> element as type="submit" by default. So to make it non-submit, you have to be explicit:

<button type="button">Some button</button>

If you do that, you will notice that the emulated click event now doesn't trigger the <button/> but still fires 2 events. The reason is that, because you haven't explicitly defined a <form/> element, IE9 assumes the controls as being in a form, and thus pressing enter in the textbox triggers 2 events:

  • the one that you are emulating
  • the default form submit button behaviour

So again to get around this issue, you have to be explicit:

<button type="button">Some button</button>
<form><input type="text" /></form>
<input type="submit" value="Submit" />

Now, these are the reasons that you are seeing the behaviour in IE. @MrSlayer's answer caters to the second issue of stopping the keypress event after you have satisfactorily handled it, using preventDefault()

Solution 2:[2]

The Enter key has a default behavior to submit, so you need to prevent the default behavior from executing. Because the button tag is, by default, type="submit" it is executing that button when the Enter key is pressed.

//SIMULATE CLICK IF ENTER PRESSED IN SEARCH
$('input[type=text]').keypress(function (event) {
    var keycode = event.keyCode || event.which;
    if (keycode == 13)
    {
        event.preventDefault();
        $('input[type=submit]').click();
    }
});

Solution 3:[3]

How about triggering the form's submit instead of a button click?

$('input[type=text]').keypress(function(e) {
     var keycode = event.keyCode || event.which,
         frm = $(this).closest('form');

     if (keycode == 13) {
          e.stopPropagation();
          frm.submit();
          return false;
     }
     return true;
});

--EDIT--

Updated Slightly to stop the event propagation.

Solution 4:[4]

First off, you don't need to manually attach an event to submit a form when the user presses enter - the browser already handles that.

Oddly enough, this was to do with the order of the elements, implicit form-associations, as well as the fact that IE handles buttons as submit elements.

Try swapping the order of these buttons to see what I mean:

<input type="text" />
<input type="submit" value="Submit" />
<button>Some button</button>

Naturally, the browser is already instructed to listen to respond to the Enter on a text-input. This results in the browser clicking the associated submit button. Further, since you haven't explicitly provided a form, or associated elements with one another via their form attribute, the browser is attempting to make that relationship for you.

In your code, the <button> element was assumed to be the submit button of the text-input (because it was the first submit button in the implicit form). As such, anytime you press Enter on the text-input, the browser naturally raises the click event of the associated button.

If you re-order the elements, as I have above, we see the opposite take place. IE associates the other <input> element with the text-box. And pressing Enter on the text-box implicitly raises the click event on the submit input.

You can confirm this behavior by comparing the .form attributes of various elements. For instance, adding some id values will give us easier access to these:

<button id="fiz">Some Button</button>
<input  id="foo" type="text" />
<input  id="bar" type="submit" value="Submit" />

Then run some quick comparisons:

var button = document.getElementById("fiz"); 
var text = document.getElementById("foo"); 
var submit = document.getElementById("bar"); 

button.form === text.form;   // true 
submit.form === text.form;   // true 
button.form === submit.form; // true 

So in the end, it's up to you to remove the ambiguity between the two buttons, by declaring the <button> element to be type='button', or by placing it after the intended submit button.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Jeff Jenkins
Solution 3
Solution 4