76

I want a jquery solution, I must be close, what needs to be done?

$('html').bind('keypress', function(e)
{
     if(e.keyCode == 13)
     {
         return e.keyCode = 9; //set event key to tab
     }
});

I can return false and it prevents the enter key from being pressed, I thought I could just change the keyCode to 9 to make it tab but it doesn't appear to work. I've got to be close, what's going on?

payling
  • 2,466
  • 5
  • 33
  • 44
  • What about preventing the event to continue being handled by superior layers, and instead of trying to change the current event, emitting a new one? – Spidey Aug 28 '13 at 18:15
  • Because of security reason modifying keyCode is very bad idea and I am happy that the newest browsers (IE11+ also) does not support this (but IE 10 and earlier did support for this). Anyhow I was looking for the best solution during the last two days for your question (it was mine as well) and here I have found very interesting approaches and solution experiments. Still I am thinking on the best approach. – Miklos Krivan May 21 '17 at 06:35

20 Answers20

78

Here is a solution :

$('input').on("keypress", function(e) {
            /* ENTER PRESSED*/
            if (e.keyCode == 13) {
                /* FOCUS ELEMENT */
                var inputs = $(this).parents("form").eq(0).find(":input");
                var idx = inputs.index(this);

                if (idx == inputs.length - 1) {
                    inputs[0].select()
                } else {
                    inputs[idx + 1].focus(); //  handles submit buttons
                    inputs[idx + 1].select();
                }
                return false;
            }
        });
Lorenzo
  • 797
  • 6
  • 27
Sarfraz
  • 377,238
  • 77
  • 533
  • 578
  • 7
    That solution doesn't look so great to me. It pays no attention to "tabindex" properties, for one thing. Also, it's specific to forms and input elements, while (for reasons unknown) the original asker apparently wants the effect to be global across the entire page. – Pointy Feb 25 '10 at 16:26
  • 1
    @Pointy: this is not the eternal solution, would love to see other possibilities from you or any one else :) – Sarfraz Feb 25 '10 at 16:27
  • It does the trick, but I'd like to see if any other people have different solutions. – payling Feb 25 '10 at 17:00
  • @payling: sure, that's better decision :) – Sarfraz Feb 25 '10 at 17:18
  • @Pointy I know it's been too long since the question was asked but you may want to checkout my answer ;) – Kamran Ahmed Oct 19 '13 at 08:04
  • `live` has been officially "obsoleted" by jquery, now you have to use `on`. Checkout my answer, for how to achieve it using `on` ;) – Kamran Ahmed Oct 19 '13 at 08:07
  • @Sarfraz I could not solve how to make use of the tab index where enter key is changed as tab scenarios. I posted a Q link below , any help is appreciated http://stackoverflow.com/questions/38489379/enter-key-as-tab-to-follow-the-tabindex . – user5249203 Jul 20 '16 at 19:51
  • @Pointy, you pointed out tabindex, can you help me out in that Q link i gave above comment? – user5249203 Jul 20 '16 at 19:51
  • Why does every answer in every question about this assume there is a form present?! – Justin Feb 05 '20 at 16:40
34

This works perfect!

 $('input').keydown( function(e) {
        var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
        if(key == 13) {
            e.preventDefault();
            var inputs = $(this).closest('form').find(':input:visible');
            inputs.eq( inputs.index(this)+ 1 ).focus();
        }
    });
Bharat
  • 3,491
  • 1
  • 22
  • 22
  • 2
    It is not working for Select and a text field outside the form. can you please modify it to work for both select and any field outside the form. – bjan Mar 13 '12 at 12:05
  • 2
    @bjan just change the jquery selector – Leandro Bardelli Sep 02 '13 at 18:23
  • Good but not perfet. Better is to use event on because it create less events handlers(performance) and work for ajax updated dom objects $('input').on("keypress", function(e) { ... – Andzej Maciusovic Nov 19 '14 at 12:39
  • 2
    @AndzejMaciusovic, that's totally misleading `$('input').keydown(...` is the shorthand for `$('input').on("keypress"...`. They are both the same thing. Do you have a proof? – azerafati Jan 05 '18 at 13:34
10

Why not something simple like this?

$(document).on('keypress', 'input', function(e) {

  if(e.keyCode == 13 && e.target.type !== 'submit') {
    e.preventDefault();
    return $(e.target).blur().focus();
  }

});

This way, you don't trigger the submit unless you're focused on the input type of "submit" already, and it puts you right where you left off. This also makes it work for inputs which are dynamically added to the page.

Note: The blur() is in front of the focus() for anyone who might have any "on blur" event listeners. It is not necessary for the process to work.

rpearce
  • 1,720
  • 1
  • 21
  • 29
  • @versedi I do not believe that is accurate. Could you explain what you mean? This should work perfectly fine on all operating systems and browsers where jQuery is being used – rpearce Oct 13 '15 at 00:29
  • This is based on keyboard key code which's in your case stated only as 13. We should remember about numpad Enter key which has separate code - 3 in Macs (it doesn't affect Windows which uses 13 for both of them). – versedi Oct 13 '15 at 07:10
  • So whats the problem? Just do this `(e.keyCode == 13) || (e.keyCode == 3 )` – Risinek Nov 30 '16 at 14:55
  • The original question was to change the enter key behavior to tab key behavior not just catching the enter key pressed. – Miklos Krivan May 21 '17 at 09:32
7

PlusAsTab: A jQuery plugin to use the numpad plus key as a tab key equivalent.

PlusAsTab is also configurable to use the enter key as in this demo. See some of my older answers to this question.

In your case, replacing the enter key with tab functionality for the entire page (after setting the enter key as tab in the options).

<body data-plus-as-tab="true">
    ...
</body>
Joel Purra
  • 24,294
  • 8
  • 60
  • 60
  • Very good, Joel! Dealing with the github module dependency threw me for a loop at first, though. –  Jul 10 '12 at 18:25
  • @RiverC: yes, submodules can be tricky if you forget them, especially with javascript libraries. Updated the documentation to include the submodules, as a clone recommendation. `git clone --recursive git://github.com/joelpurra/plusastab.git` – Joel Purra Jul 10 '12 at 18:30
  • I like the plug in Joel, but it appears that when using the sample provided in the "Enter As Tab" demo, it fails to recognize tabindex. – Ed DeGagne Mar 26 '13 at 20:41
  • @EdDeGagne: `tabindex` is ignored by design - see [SkipOnTab versus tabindex](https://github.com/joelpurra/skipontab/wiki/SkipOnTab-versus-tabindex). Should probably write something similar or link to that page from PlusAsTab and EmulateTab. – Joel Purra Mar 27 '13 at 15:58
5

Building from Ben's plugin this version handles select and you can pass an option to allowSubmit. ie. $("#form").enterAsTab({ 'allowSubmit': true}); This will allow enter to submit the form if the submit button is handling the event.

(function( $ ){
    $.fn.enterAsTab = function( options ) {  
    var settings = $.extend( {
       'allowSubmit': false
    }, options);
    this.find('input, select').live("keypress", {localSettings: settings}, function(event) {
        if (settings.allowSubmit) {
        var type = $(this).attr("type");
        if (type == "submit") {
            return true;
        } 
    }
    if (event.keyCode == 13 ) {
        var inputs =   $(this).parents("form").eq(0).find(":input:visible:not(disabled):not([readonly])");
        var idx = inputs.index(this);
        if (idx == inputs.length - 1) {
           idx = -1;
       } else {
           inputs[idx + 1].focus(); // handles submit buttons
      }
        try {
            inputs[idx + 1].select();
            }
        catch(err) {
            // handle objects not offering select
            }
        return false;
    }
});
  return this;
};
})( jQuery );
Jenz
  • 8,280
  • 7
  • 44
  • 77
Manuel Guzman
  • 153
  • 2
  • 6
5

Here is what I've been using:

$("[tabindex]").addClass("TabOnEnter");
$(document).on("keypress", ".TabOnEnter", function (e) {
 //Only do something when the user presses enter
     if (e.keyCode == 13) {
          var nextElement = $('[tabindex="' + (this.tabIndex + 1) + '"]');
          console.log(this, nextElement);
           if (nextElement.length)
                nextElement.focus()
           else
                $('[tabindex="1"]').focus();
      }
});

Pays attention to the tabindex and is not specific to the form but to the whole page.

Note live has been obsoleted by jQuery, now you should be using on

Paresh3489227
  • 845
  • 11
  • 22
Kamran Ahmed
  • 11,809
  • 23
  • 69
  • 101
4

I wrote the code from the accepted answer as a jQuery plugin, which I find more useful. (also, it now ignores hidden, disabled, and readonly form elements).

$.fn.enterAsTab = function () {
  $(this).find('input').live("keypress", function(e) {
    /* ENTER PRESSED*/
    if (e.keyCode == 13) {
        /* FOCUS ELEMENT */
        var inputs =   $(this).parents("form").eq(0).find(":input:visible:not(disabled):not([readonly])"),
            idx = inputs.index(this);

        if (idx == inputs.length - 1) {
            inputs[0].select()
        } else {
            inputs[idx + 1].focus(); // handles submit buttons
            inputs[idx + 1].select();
        }
        return false;
    }
  });
  return this;
};

This way I can do $('#form-id').enterAsTab(); ... Figured I'd post since no one has posted it as a $ plugin yet and they aren't entirely intuitive to write.

B Robster
  • 40,605
  • 21
  • 89
  • 122
4

This is at last what is working for me perfectly. I am using jqeasyui and it is working fine

$(document).on('keyup', 'input', function(e) {
 if(e.keyCode == 13 && e.target.type        !== 'submit') {
   var inputs =   $(e.target).parents("form").eq(0).find(":input:visible"),
   idx = inputs.index(e.target);
       if (idx == inputs.length - 1) {
          inputs[0].select()
       } else {
          inputs[idx + 1].focus();
          inputs[idx + 1].select();
       }
 }

});
Metin
  • 41
  • 1
  • Thanks Metin you solved my problem, I added a litle bit check for select: $(document).on('keyup', 'input,select', function(e) { – user3086295 Dec 10 '13 at 09:57
3

Includes all types of inputs

$(':input').keydown(function (e) {
    var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
    if (key == 13) {
        e.preventDefault();
        var inputs = $(this).closest('form').find(':input:visible:enabled');
        if ((inputs.length-1) == inputs.index(this))
            $(':input:enabled:visible:first').focus();
        else
            inputs.eq(inputs.index(this) + 1).focus();
    }
});
pmereles
  • 401
  • 7
  • 10
  • This isn't working for me. I set everything as `enabled="false"`, set the tabindex order, and hitting enter while the cursor is in a textbox still triggers the default action (submit the first button). Has anything changed that would make this need to be different for me? I have no idea what I'm doing in Jquery, just asp.NET and VB.NET. – pixelmeow Mar 03 '15 at 15:11
  • see if the control is in a "form" tag >>$(this).closest('form').length – pmereles Mar 20 '15 at 14:16
  • 1
    This one I liked most! I just added small improvements: 1) `.find(':input:visible:enabled[tabindex!="-1"]').not(':input[readonly]');` - to skip readonly and tabindex=-1 fields ...2) `if (key == 13 && $(this).attr('type') != 'submit')` to exclude submit button – Rustam Guliev Dec 13 '17 at 16:46
2

I took the best of the above and added the ability to work with any input, outside of forms, etc. Also it properly loops back to start now if you reach the last input. And in the event of only one input it blurs then refocuses the single input to trigger any external blur/focus handlers.

$('input,select').keydown( function(e) {
  var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
  if(key == 13) {
    e.preventDefault();
    var inputs = $('#content').find(':input:visible');
    var nextinput = 0;
    if (inputs.index(this) < (inputs.length-1)) {
      nextinput = inputs.index(this)+1;
    }
    if (inputs.length==1) {
      $(this).blur().focus();
    } else {
      inputs.eq(nextinput).focus();
    }
  }
});
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
TSG
  • 4,242
  • 9
  • 61
  • 121
  • This works fine, except for textareas, where it just adds a newline (which might be intentional). I did not test radio/checkbox/select. I wouldn't want to maintain your code, though: readability is a requirement :). Proper spacing and bracing goes a long way. – modle13 Aug 09 '17 at 14:21
2

This is my solution, feedback is welcome.. :)

$('input').keydown( function (event) { //event==Keyevent
    if(event.which == 13) {
        var inputs = $(this).closest('form').find(':input:visible');
        inputs.eq( inputs.index(this)+ 1 ).focus();
        event.preventDefault(); //Disable standard Enterkey action
    }
    // event.preventDefault(); <- Disable all keys  action
});
cwallenpoole
  • 79,954
  • 26
  • 128
  • 166
Nick Ma.
  • 21
  • 1
  • 6
  • But still got an ugly "Warning: The 'charCode' property of a keydown event should not be used. ....". If someone know how to get rid of it... ;) Greez – Nick Ma. Apr 03 '11 at 21:31
1

These solutions didn't work with my datagrid. I was hoping they would. I don't really need Tab or Enter to move to the next input, column, row or whatever. I just need Enter to trigger .focusout or .change and my datagrid updates the database. So I added the "enter" class to the relevant text inputs and this did the trick for me:

$(function() {
   if ($.browser.mozilla) {
        $(".enter").keypress(checkForEnter);
    } else {
        $(".enter").keydown(checkForEnter);
    }
});

function checkForEnter(event) {
    if (event.keyCode == 13) {
        $(".enter").blur();
    }
}
PJ Brunet
  • 3,615
  • 40
  • 37
0

I know this question is older than god, but I never saw an answer that was all that elegant.

doc.on('keydown', 'input', function(e, ui) {
    if(e.keyCode === 13){
        e.preventDefault();
        $(this).nextAll('input:visible').eq(0).focus();
    }
});

that seems to get the job done in as few lines as humanly possible.

user1119648
  • 531
  • 1
  • 5
  • 16
  • Really looks simple but do not take care of textarea and disabled if I am right. And maybe you want to stay in the current form as in Sarfraz suggestion. – Miklos Krivan May 21 '17 at 09:44
0
$('input').live("keypress", function(e) {
            /* ENTER PRESSED*/
            if (e.keyCode == 13) {
                /* FOCUS ELEMENT */
                var inputs = $(this).parents("form").eq(0).find(":input:visible");
                var idx = inputs.index(this);

                if (idx == inputs.length - 1) {
                    inputs[0].select()
                } else {
                    inputs[idx + 1].focus(); //  handles submit buttons
                    inputs[idx + 1].select();
                }
                return false;
            }
        });

visible input cann't be focused.

ldp615
  • 932
  • 1
  • 9
  • 13
0

you should filter all disabled and readonly elements. i think this code should not cover buttons

$('body').on('keydown', 'input, select, textarea', function(e) {
    var self = $(this),
        form = self.parents('form:eq(0)'),
        submit = (self.attr('type') == 'submit' || self.attr('type') == 'button'),
        focusable,
        next;

    if (e.keyCode == 13 && !submit) {
        focusable = form.find('input,a,select,button,textarea').filter(':visible:not([readonly]):not([disabled])');
        next = focusable.eq(focusable.index(this)+1);

        if (next.length) {
            next.focus();
        } else {
            form.submit();
        }

        return false;
    }
});
Kwido
  • 1,382
  • 8
  • 21
vatandoost
  • 2,799
  • 2
  • 12
  • 13
0

I had the same requirement in my development so I did research on this. I have read many articles and tried many solutions during last two days like jQuery.tabNext() plugin.

I had some trouble with IE11 (all IE version has this bug). When an input text followed by non text input the selection was not cleared. So I have created my own tabNext() method based on @Sarfraz solution suggestion. I was also thinking on how it should behave (only circle in the current form or maybe through the full document). I still did not take care of the tabindex property mostly because I am using it occasionally. But I will not forget it.

In order to my contribution can be useful for everybody easily I have created jsfiddle example here https://jsfiddle.net/mkrivan/hohx4nes/

I include also the JavaScript part of the example here:

            function clearSelection() {
            if (document.getSelection) { // for all new browsers (IE9+, Chrome, Firefox)
                document.getSelection().removeAllRanges();
                document.getSelection().addRange(document.createRange());
                console.log("document.getSelection");
            } else if (window.getSelection) { // equals with the document.getSelection (MSDN info)
                if (window.getSelection().removeAllRanges) {  // for all new browsers (IE9+, Chrome, Firefox)
                    window.getSelection().removeAllRanges();
                    window.getSelection().addRange(document.createRange());
                    console.log("window.getSelection.removeAllRanges");
                } else if (window.getSelection().empty) {  // maybe for old Chrome
                    window.getSelection().empty();
                    console.log("window.getSelection.empty");
                }
            } else if (document.selection) {  // IE8- deprecated
                document.selection.empty();
                console.log("document.selection.empty");
            }
        }
        function focusNextInputElement(node) { // instead of jQuery.tabNext();
            // TODO: take the tabindex into account if defined
            if (node !== null) {
                // stay in the current form
                var inputs = $(node).parents("form").eq(0).find(":input:visible:not([disabled]):not([readonly])");
                // if you want through the full document (as TAB key is working)
                // var inputs = $(document).find(":input:visible:not([disabled]):not([readonly])");
                var idx = inputs.index(node) + 1; // next input element index
                if (idx === inputs.length) { // at the end start with the first one
                    idx = 0;
                }
                var nextInputElement = inputs[idx];
                nextInputElement.focus(); //  handles submit buttons
                try { // if next input element does not support select()
                    nextInputElement.select();
                } catch (e) {
                }
            }
        }
        function tabNext() {
            var currentActiveNode = document.activeElement;
            clearSelection();
            focusNextInputElement(currentActiveNode);
        }
        function stopReturnKey(e) {
            var e = (e) ? e : ((event) ? event : null);
            if (e !== null) {
                var node = (e.target) ? e.target : ((e.srcElement) ? e.srcElement : null);
                if (node !== null) {
                    var requiredNode = $(node).is(':input')
                            // && !$(node).is(':input[button]')
                            // && !$(node).is(':input[type="submit"]')
                            && !$(node).is('textarea');
                    // console.log('event key code ' + e.keyCode + '; required node ' + requiredNode);
                    if ((e.keyCode === 13) && requiredNode) {
                        try {
                            tabNext();
                            // clearSelection();
                            // focusNextInputElement(node);
                            // jQuery.tabNext();
                            console.log("success");
                        } catch (e) {
                            console.log("error");
                        }
                        return false;
                    }
                }
            }
        }
        document.onkeydown = stopReturnKey;

I left commented rows as well so my thinking can be followed.

Miklos Krivan
  • 1,732
  • 20
  • 14
  • I need to say many thanks to all of this topic's contributors. Without you I would not able to create the best result for my development problem. My solution is an integration of all of yours with many testing and some addons of course. – Miklos Krivan May 21 '17 at 09:15
0

I know this is rather old, but I was looking for the same answer and found that the chosen solution did not obey the tabIndex. I have hence modified it to the following which works for me. Please note that maxTabNumber is a global variable that holds the maximum number of tabbable input fields

  $('input').on("keypress", function (e) {
                if (e.keyCode == 13) {
                    var inputs = $(this).parents("form").eq(0).find(":input");
                    var idx = inputs.index(this);

                    var tabIndex = parseInt($(this).attr("tabindex"));
                    tabIndex = (tabIndex + 1) % (maxTabNumber + 1);
                    if (tabIndex == 0) { tabIndex = 1; }
                    $('[tabindex=' + tabIndex + ']').focus();
                    $('[tabindex=' + tabIndex + ']').select();
          
                    return false;
                }
    });
Claus Behn
  • 11
  • 2
0

Here's a jQuery plugin I wrote that handles enter key as a callback or as a tab key (with an optional callback):

$(document).ready(function() {
  $('#one').onEnter('tab');
  $('#two').onEnter('tab');
  $('#three').onEnter('tab');
  $('#four').onEnter('tab');
  $('#five').onEnter('tab');
});

/**
 * jQuery.onEnter.js
 * Written by: Jay Simons
 * Cloudulus.Media (https://code.cloudulus.media)
 */

if (window.jQuery) {
    (function ($) {
        $.fn.onEnter = function (opt1, opt2, opt3) {
            return this.on('keyup', function (e) {
                var me = $(this);
                var code = e.keyCode ? e.keyCode : e.which;
                if (code == 13) {
                    if (typeof opt1 == 'function')
                    {
                        opt1(me, opt2);
                        return true;
                    }else if (opt1 == 'tab')
                    {
                        var eles = $(document).find('input,select,textarea,button').filter(':visible:not(:disabled):not([readonly])');
                        var foundMe = false;
                        var next = null;
                        eles.each(function(){
                            if (!next){
                                if (foundMe) next = $(this);
                                if (JSON.stringify($(this)) == JSON.stringify(me)) foundMe = true;
                            }
                        });
                        next.focus();
                        if (typeof opt2 === 'function')
                        {
                            opt2(me, opt3);
                        }
                        return true;
                    }
                }
            }).on('keydown', function(e){
                var code = e.keyCode ? e.keyCode : e.which;
                if (code == 13)
                {
                    e.preventDefault();
                    e.stopPropagation();
                    return false;
                }
            });
        }
    })(jQuery);
} else {
    console.log("onEnter.js: This class requies jQuery > v3!");
}
input,
select,
textarea,
button {
  display: block;
  margin-bottom: 1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <input id="one" type="text" placeholder="Input 1" />
  <input id="two" type="text" placeholder="Input 2" />

  <select id="four">
    <option selected>A Select Box</option>
    <option>Opt 1</option>
    <option>Opt 2</option>
  </select>
  <textarea id="five" placeholder="A textarea"></textarea>
  <input id="three" type="text" placeholder="Input 3" />
  <button>A Button</button>
</form>
Jay
  • 353
  • 4
  • 8
0

I need to go next only to input and select, and element have to be focusable. This script works better for me:

$('body').on('keydown', 'input, select', function(e) {
    if (e.key === "Enter") {
        var self = $(this), form = self.parents('form:eq(0)'), focusable, next;
        focusable = form.find('input,select,textarea').filter(':visible');
        next = focusable.eq(focusable.index(this)+1);
        if (next.length) {
            next.focus();
        } else {
            form.submit();
        }
        return false;
    }
});

Maybe it helps someone.

lynx_74
  • 1,633
  • 18
  • 12
-1

If you're using IE, this worked great for me:

    <body onkeydown="tabOnEnter()">
    <script type="text/javascript">
    //prevents the enter key from submitting the form, instead it tabs to the next field
    function tabOnEnter() {
        if (event.keyCode==13) 
        {
            event.keyCode=9; return event.keyCode 
        }
    }
    </script>