lindsaymacvean lindsaymacvean - 6 months ago 23
jQuery Question

keyup 13 event repeats implied submission - submit form on enter issue

UPDATE 10/9/15

My original question is below and is unclear and does not fully describe my problem because it focuses on the

keyup
event listener when its actually the double submission of the form (once from the
change
event and once from the implicit submission both triggered by
keypress
of the enter key) as the root problem... I have reviewed the code some more and here is an example demonstrating my true problem:

<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
</head>
<body>

<form method="GET" action="#">

<input type="text" />
<input type="submit" />
</form>

<script>
$('form>input[type="text"]')
// Change event triggered by both enter key and tab key
.on('change', function (e) {
e.preventDefault();
console.log('change event');
$('form').submit(); //This emulates a more complex ajax request
});
$('form').submit(function (e) {
// You will notice the console logs this twice if you hit enter instead of tab.
console.log("form submitted");
});
</script>
</body>
</html>


If you enter something into the input box and hit the enter key then you will see in the console that the form submits twice, once from the change event and once from the implicit submission of the browser.

I want to stop the form submitting twice (you will notice I have already tried preventDefault in my code above). The answer appears to be to preventDefault specifically on the
keypress
(not
keyup
) of the enter key (many thanks to @JotaBe)

ORIGINAL QUESTION

So I have an event listener for the enter key on an input something like so

$(element)
.on('keyup', function (e) {
if (e.which === 13) {
event.trigger();
}
}); `


Specifically the code is from this plugin

This is interfering with the implied submission which is standard on most browsers, as per the W3 standard, and causing the form to submit twice.

What I would like to know, does the implicit submission happen before or after the explicit submission of my form with the event listener?

And for bonus points which version (or where can I find out which version) did 'implicit submission' get added to various browsers? (so I know how far back my code will be compatible)

Answer

Second question first

The implicit submission, although not with that name, exists at least from something as old as HTML 2 specs of novemeber 1995. Last lines of section 8.2:

When there is only one single-line text input field in a form, the user agent should accept Enter in that field as a request to submit the form.

So, as we say in Spain, is as old as coughing.

And then, the main stuff

When you handle an event, unless you cancel the default action, when the code in your handler finishes running, the default action is executed.

Your code is triggering the event, and not cancelling the defautl action. That's why the submission happens twice, once for the handled event, and once for the additional triggered event.

In the case of jquery you've got to call event.preventDefault() to avoid the default action to execute.

Please look at this fiddle to check 2 things:

1) By default, when you press enter on a form, the form is submitted To be more precise, it must simulate a click on the first submit button of the form. Thus, if this button is disabled, or doesn't exist, nothing happens.

2) If you want to prevent the default behavior, you must handle the keypress (not keydown or keyup) event on the textbox, and invoke the event's preventDefault method.

3) According to the specs, this should only happen when there is a single textbox (of type text, number, date, url,email, etc.). But it doesn't work like this in most browsers, for example in desktop versions of Chrome 45, IE 10 and FF27 & FF33. I didn't test other versions.

Fiddle code:

// This suppres the default behavior of submitting the
// form when the enter key is pressed in the textbox
$('#form2').on('keypress', function (e) {
    if (e.which === 13) {
        e.preventDefault(); 
        console.log('key press 13');
    }
});

// This event is triggered when any form is submitted
// (in fact, the submission is prevented).
$('form').on('submit', function(e) {
    console.log('Sending form', e.target.name);
    e.preventDefault();
});

with this HTML:

<div>
    <p>Form 1, default enter behavior, when there is only a textbox, and there is a submit button</p>
    <p>If you press enter, it's submitted</p>
    <form method="GET" id="form1">
        <input type="text" />
        <input type="submit" />
    </form>
</div>

<div>
    <p>Form 2: prevents default behavior on textbox</p>
    <p>If you press enter the form is not submitted</p>
    <form method="GET" id="form2">
        <input type="text" />
        <input type="submit" />
    </form>
</div>

<div>
    <p>Form 3: submit shuld only happen if there is only one textbox, but it depends on the browser</p>
    <p>If you press enter the form should not be submitted, because there are several textboxes, but I bet it will be submitted</p>
    <form method="GET" id="form3">
        <input type="text" />
        <input type="text" />
        <input type="submit" />
    </form>
</div>    
Comments