59

I just wrote this nifty little function which works on the form itself...

$("#form").keypress(function(e) {
    if (e.which == 13) {
        var tagName = e.target.tagName.toLowerCase(); 
        if (tagName !== "textarea") {
            return false;
        }
    }
});

In my logic I want to accept carriage returns during the input of a textarea. Also, it would be an added bonus to replace the enter key behavior of input fields with behavior to tab to the next input field (as if the tab key was pressed). Does anyone know of a way to use the event propagation model to correctly fire the enter key on the appropriate element, but prevent form submitting on its press?

Austin Hummel
  • 332
  • 2
  • 7
Dmitriy Likhten
  • 5,076
  • 7
  • 36
  • 47

10 Answers10

54

You can mimic the tab key press instead of enter on the inputs like this:

//Press Enter in INPUT moves cursor to next INPUT
$('#form').find('.input').keypress(function(e){
    if ( e.which == 13 ) // Enter key = keycode 13
    {
        $(this).next().focus();  //Use whatever selector necessary to focus the 'next' input
        return false;
    }
});

You will obviously need to figure out what selector(s) are necessary to focus on the next input when Enter is pressed.

Jake Wilson
  • 88,616
  • 93
  • 252
  • 370
  • need to add-- return false; – Craig Feb 06 '13 at 17:11
  • I like how you block the whole input with this return false; return false must be moved into condition block. Otherwise return true must be used. – pronebird Dec 16 '13 at 14:31
  • how can i avoid cursor from focus in readonly inputfields like skipping the readonly fields – Aitazaz Khan Jun 07 '15 at 10:50
  • 1
    @AitazazKhan you can use `tabindex` attributes but I think your cursor will eventually hit it anyways. You could also maybe setup a jQuery event when the readonly input is focused and force focus to another element... Never tried that. – Jake Wilson Jun 08 '15 at 02:28
  • 1
    You may find that `$(this).nextAll('INPUT').first().focus();` is more suitable than `$(this).next().focus();`. Try it and see the differences. – Volomike Aug 10 '16 at 05:41
40

Note that single input forms always get submitted when the enter key is pressed. The only way to prevent this from happening is this:

<form action="/search.php" method="get">
<input type="text" name="keyword" />
<input type="text" style="display: none;" />
</form>
philipphoffmann
  • 785
  • 6
  • 9
27

Here is a modified version of my function. It does the following:

  1. Prevents the enter key from working on any element of the form other than the textarea, button, submit.
  2. The enter key now acts like a tab.
  3. preventDefault(), stopPropagation() being invoked on the element is fine, but invoked on the form seems to stop the event from ever getting to the element.

So my workaround is to check the element type, if the type is not a textarea (enters permitted), or button/submit (enter = click) then we just tab to the next thing.

Invoking .next() on the element is not useful because the other elements might not be simple siblings, however since DOM pretty much garantees order when selecting so all is well.

function preventEnterSubmit(e) {
    if (e.which == 13) {
        var $targ = $(e.target);

        if (!$targ.is("textarea") && !$targ.is(":button,:submit")) {
            var focusNext = false;
            $(this).find(":input:visible:not([disabled],[readonly]), a").each(function(){
                if (this === e.target) {
                    focusNext = true;
                }
                else if (focusNext){
                    $(this).focus();
                    return false;
                }
            });

            return false;
        }
    }
}
Dmitriy Likhten
  • 5,076
  • 7
  • 36
  • 47
  • In case it isn't clear, `preventEnterSubmit` is a handler for the form's `keypress` event. – Álvaro González Jan 28 '13 at 11:33
  • if you please add support of select as well will be better – Aitazaz Khan Jun 07 '15 at 13:19
  • For some reason, I just *can* *not* get this to work. `jQuery('#form_id').onkeypress(preventEnterSubmit(e);` returns a reference error saying that `e` can't be found; same with more roundabout methods such as `jQuery('#form_id').addEventListener('keypress', preventEnterSubmit(e));` What's missing here? – Kaji Feb 23 '18 at 05:44
5

From a usability point of view, changing the enter behaviour to mimic a tab is a very bad idea. Users are used to using the enter key to submit a form. That's how the internet works. You should not break this.

Jarón Barends
  • 127
  • 1
  • 4
  • 10
    Not necessarily all the time. If it is clear enough that another field needs to be filled out, then forcing tab is OK. As long as the next field does indeed need to be filled out. – 700 Software Apr 08 '11 at 19:18
  • 10
    Or if you're using barcode scanners, which automatically send an enter key when they're done sending the barcode number. – bestattendance Jun 17 '11 at 00:04
  • 2
    And ... Safari uses enter to select when you're trying to select from a list by hand - which is crap, but that's what it does – Ghoti Aug 23 '11 at 17:22
  • I agree with point in general, but, this is why i am here ... I have a form that includes addition of a map point and I don't want users who use the postcode search to accidentally submit the form (the map search field is saved as part of the form too, so i can't pull it out entirely), sometimes there are cases where rules need to be broken – Toni Leigh Jan 18 '14 at 09:07
  • I find users are surprised by this behavior. Also jquery validate doesn't work right with entry key submits. – nuander Feb 27 '14 at 23:26
  • How about when you have a multi-step form where you're only showing one input in the form at a time in a series of "screens". The user probably expects the enter key to go to the next screen in that case. – V. Rubinetti Aug 06 '20 at 22:18
3

The post Enter Key as the Default Button describes how to set the default behaviour for enter key press. However, sometimes, you need to disable form submission on Enter Key press. If you want to prevent it completely, you need to use OnKeyPress handler on tag of your page.

<body OnKeyPress="return disableKeyPress(event)">

The javascript code should be:

<script language="JavaScript">

function disableEnterKey(e)
{
     var key;      
     if(window.event)
          key = window.event.keyCode; //IE
     else
          key = e.which; //firefox      

     return (key != 13);
}

</script>

If you want to disable form submission when enter key is pressed in an input field, you must use the function above on the OnKeyPress handler of the input field as follows:

<input type="text" name="txtInput" onKeyPress="return disableEnterKey(event)">

Source: http://www.bloggingdeveloper.com/post/Disable-Form-Submit-on-Enter-Key-Press.aspx

MA9H
  • 1,849
  • 2
  • 16
  • 19
  • this is only working solution for me. My case was an edit with auto-fill options and when you chose option you press enter, right? In my case chosen option was not passing to the js function but rather form was submitted. Now I can use google maps api with this little blocking trick. It works for Google Chrome all right too. Thank you. – Yevgeniy Afanasyev Jul 06 '18 at 02:35
  • @YevgeniyAfanasyev I'm glad you find my solution helpful :) – MA9H Aug 08 '18 at 23:11
1

I modified Dmitriy Likhten's answer a bit, works good. Included how to reference the function to the event. note that you don't include () or it will execute. We're just passing a reference.

$(document).ready(function () {
    $("#item-form").keypress(preventEnterSubmit);
});

function preventEnterSubmit(e) {
    if (e.which == 13) {
        var $targ = $(e.target);

        if (!$targ.is("textarea") && !$targ.is(":button,:submit")) {
            var focusNext = false;
            $(this).find(":input:visible:not([disabled],[readonly]), a").each(function () {
                if (this === e.target) {
                    focusNext = true;
                } else {
                    if (focusNext) {
                        $(this).focus();
                        return false;
                    }
                }
            });

            return false;
        }
    }
}
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Dave ت Maher
  • 1,561
  • 14
  • 8
0

In my case i wanted to prevent it only in a dinamically created field, and activate some other button, so it was a little bit diferent.

$(document).on( 'keypress', '.input_class', function (e) {
    if (e.charCode==13) {
        $(this).parent('.container').children('.button_class').trigger('click');
        return false;
    }
});

In this case it will catch the enter key on all input's with that class, and will trigger the button next to them, and also prevent the primary form to be submited.

Note that the input and the button have to be in the same container.

Julio Popócatl
  • 712
  • 8
  • 16
0

The previous solutions weren't working for me, but I did find a solution.

This waits for any keypress, test which match 13, and returns false if so.

in the <HEAD>

function stopRKey(evt) {
  var evt = (evt) ? evt : ((event) ? event : null);
  var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
  if ((evt.which == 13) && (node.type == "text")) {
    return false;
  }
}

document.onkeypress = stopRKey;
LWSChad
  • 331
  • 3
  • 14
0

I prefer the solution of @Dmitriy Likhten, yet: it only worked when I changed the code a bit:

[...] else 
            { 
             if (focusNext){
                $(this).focus();
                return false; } //  
            }     

Otherwise the script didn't work. Using Firefox 48.0.2

davidman77
  • 331
  • 3
  • 12
-1

Set trigger for both the form and the inputs, but when the input events are triggered, stop the propagation to the form by calling the stopPropagation method.

By the way, IMHO, it's not a great thing to change default behaviors to anything any average user is used to - that's what make them angry when using your system. But if you insist, then the stopPropagation method is the way to go.

Seb
  • 24,920
  • 5
  • 67
  • 85