jquery how to catch enter key and change event to tab
Asked Answered
P

20

77

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?

Pecten answered 25/2, 2010 at 16:16 Comment(2)
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?Footed
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.Alberik
P
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;
            }
        });
Pyxie answered 25/2, 2010 at 16:21 Comment(9)
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.Madras
@Pointy: this is not the eternal solution, would love to see other possibilities from you or any one else :)Pyxie
It does the trick, but I'd like to see if any other people have different solutions.Pecten
@payling: sure, that's better decision :)Pyxie
@Madras I know it's been too long since the question was asked but you may want to checkout my answer ;)Gerlac
live has been officially "obsoleted" by jquery, now you have to use on. Checkout my answer, for how to achieve it using on ;)Gerlac
@Pyxie 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 #38489879 .Gasolier
@Pointy, you pointed out tabindex, can you help me out in that Q link i gave above comment?Gasolier
Why does every answer in every question about this assume there is a form present?!Caerleon
F
36

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();
        }
    });
Felon answered 25/5, 2011 at 17:48 Comment(4)
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.Calzada
@Calzada just change the jquery selectorVaulting
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) { ...Xuthus
@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?Riposte
G
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.

Grandma answered 27/5, 2013 at 21:24 Comment(4)
@Volitant 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 usedGrandma
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).Volitant
So whats the problem? Just do this (e.keyCode == 13) || (e.keyCode == 3 )Raymer
The original question was to change the enter key behavior to tab key behavior not just catching the enter key pressed.Alberik
T
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>
Thymic answered 30/4, 2012 at 19:27 Comment(4)
Very good, Joel! Dealing with the github module dependency threw me for a loop at first, though.Heuser
@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.gitThymic
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.Gittel
@EdDeGagne: tabindex is ignored by design - see SkipOnTab versus tabindex. Should probably write something similar or link to that page from PlusAsTab and EmulateTab.Thymic
N
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 );
Nightjar answered 5/4, 2012 at 22:24 Comment(1)
put disabled into bracket in selector [disabled]Alberik
G
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

Gerlac answered 19/10, 2013 at 8:1 Comment(2)
This is my favorite answer. It works well in my case, but it should be noted it won't if the elements' tabindexs are not sequential.Willey
It is good only if you have tabindex on elements otherwise it does not work.Alberik
C
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.

Clomp answered 5/4, 2012 at 3:25 Comment(1)
There is something similar; release a plugin a couple of months ago, see my answer.Thymic
B
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();
       }
 }

});
Brocket answered 3/11, 2013 at 7:55 Comment(1)
Thanks Metin you solved my problem, I added a litle bit check for select: $(document).on('keyup', 'input,select', function(e) {Cortese
S
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();
    }
});
String answered 12/6, 2014 at 14:5 Comment(3)
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.Asinine
see if the control is in a "form" tag >>$(this).closest('form').lengthString
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 buttonNeocolonialism
A
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
});
Abilene answered 3/4, 2011 at 21:29 Comment(1)
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... ;) GreezAbilene
C
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();
    }
  }
});
Christyna answered 14/3, 2013 at 21:12 Comment(1)
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.Catenary
R
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();
    }
}
Runge answered 16/3, 2012 at 23:31 Comment(0)
D
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.

Dollydolman answered 16/3, 2010 at 3:9 Comment(0)
B
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.

Burns answered 11/8, 2013 at 3:5 Comment(1)
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.Alberik
C
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;
    }
});
Catlaina answered 23/12, 2016 at 8:29 Comment(0)
A
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.

Alberik answered 21/5, 2017 at 9:9 Comment(1)
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.Alberik
M
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;
                }
    });
Martinemartineau answered 4/4, 2018 at 11:13 Comment(0)
V
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>
Vicinal answered 12/3, 2019 at 1:7 Comment(0)
D
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.

Dibrin answered 10/3, 2020 at 14:3 Comment(0)
A
-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>
Affusion answered 4/5, 2016 at 22:5 Comment(2)
Sorry, just saw the "jquery" partAffusion
It looks really simple but unfortunately do not work on IE11. The last version where it works is IE10 (I have tried with all of the IE emulation modes)Alberik

© 2022 - 2024 — McMap. All rights reserved.