12

Users don't like the fact that the Enter key submits the page. So I am tasked with preventing the submission and changing the Enter key to a Tab to the next field.

I have tried many javascript snippets found on the net but none have worked so far. The only one that has even come close to having an effect was e.preventDefault() of the jQuery API, which stops the submit, but nothing I have tried emulates the tab behavior.

e.returnValue = false;
e.cancel = true;

Page still submits with the above in the keydown event handler. Same effect with return false in the keydown event handler. The handler is firing, tested by putting a breakpoint in it with firebug.

This needs to work with both IE and Firefox.

Don't say "don't do this".
1) I'm already convinced that I shouldn't do it, but it's not a choice that is mine, so the discussion is mute.
2) It would be an answer to the question "Should I do this?", which is not the question that I am asking.

AaronLS
  • 37,329
  • 20
  • 143
  • 202
  • Why not use `e.preventDefault()` to stop the submission, and then use something else to shift focus? You're allowed to put more than one action into an event handler, after all. – Anon. Dec 20 '10 at 22:23
  • Have tried various combinations of suggestions for emulating the tab key, in combination with e.preventDefault(), but haven't found anything that works yet. – AaronLS Dec 20 '10 at 22:25
  • I heard of such requirements before, but I don't think it's possible. I think you should convince your customers, that this is the wrong way. – Christian Dec 20 '10 at 22:25
  • 1
    It should be relatively easy to determine what element currently has focus. And hence what element should have focus next. Then you can manually set the focus to that element. – Anon. Dec 20 '10 at 22:29
  • 1
    Every so often I have a customer that requests this. I always point out that very few sites do this for one simple reason: it is unexpected behavior. Even google accepts the enter key as being a form submit. I've never had someone ask again. – NotMe Dec 20 '10 at 23:04
  • @Chris I agree with everything you said. Long story short, the problem is a combination of a non-inuitive default action for submit, and users familiar with Excel. The alternative in my opinion is a better design of the interface that has a more intuitive default action for the submit, but that is not my authority. I also think this approach will create an interface that is not accessibility compliant, since it is changing the standard behavior, I can imagine that would make it difficult to interact with the page for someone assisted with an accessibility tool. – AaronLS Dec 21 '10 at 00:11
  • 1
    @Waxolunist & @Chris, if you can't answer his question, please don't say anything. I've been in Aaron's shoes, and it's REALLY discouraging to get those kinds of replies. Also, some customers have staff who are coming from "green-screen" environments, where they are used to hitting Enter between fields, not Tab. The requirement for the web app is to retain the same behavior. – David Mar 18 '11 at 00:38
  • I think http://stackoverflow.com/questions/4251625/ie9-weird-javascript-error has some code to do what you want - sorry I don't know how to link it. – robocat Jun 03 '11 at 00:49
  • 1
    Have a look at [this answer](http://stackoverflow.com/questions/8664375/how-to-convert-an-enter-key-press-into-a-tab-key-press-for-web-pages/9333124#9333124) linking to this [example showing how to emulate enter as tab](http://joelpurra.github.com/plusastab/example/enter-as-tab.html). It's a reusable plugin called [PlusAsTab](http://joelpurra.github.com/plusastab/), using CSS classes or HTML5 `data-*` attributes to mark fields/forms/containers you want the functionality in. – Joel Purra Feb 27 '12 at 12:24

3 Answers3

11

This just feels icky, but you could use event.preventDefault as you mentioned and then call focus() on the next closest input:

Here's a simple example:

$("input").bind("keydown", function(event) {
    if (event.which === 13) {
        event.stopPropagation();
        event.preventDefault();
        $(this).next("input").focus();
    }
});

Example: http://jsfiddle.net/andrewwhitaker/Txg65/

Update: If you have elements in between your inputs, using plain next() will not work. Instead, use nextAll():

$("input").bind("keydown", function(event) {
    if (event.which === 13) {
        event.stopPropagation();
        event.preventDefault();
        $(this).nextAll("input").eq(0).focus();
    }
});

http://jsfiddle.net/andrewwhitaker/GRtQY/

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • 1
    Additionally, for IE, you need to use `event.cancelBubble = true` so that it doesn't bubble up (and submits the form or tabs to the next input). See http://www.quirksmode.org/js/events_order.html#link9. – Andre Dec 20 '10 at 22:47
  • 1
    Thanks for the tip, added `event.stopPropagation()` which I believe will work in IE/FF since it's a function on jquery's event object. – Andrew Whitaker Dec 20 '10 at 22:53
  • +1 for getting me on the right track, but doesn't work I think because I have things between input boxes. Never used fiddle before but I think this should show what I mean: http://jsfiddle.net/xpxB6/ Was able to get a solution though, posting it now. – AaronLS Dec 21 '10 at 00:18
  • @AaronLS: Good point, I've expanded the example to include that case, please refer to the answer. – Andrew Whitaker Dec 21 '10 at 00:29
  • I've put similar functionality into a jQuery plugin, in case you'd like a reusable solution. – Joel Purra Feb 27 '12 at 12:26
  • Doesn't work for me, jumping to next input. Maybe because there is not only something inbetween the inputs, but also around each input? They are within divs, in my case. – Ralf Oct 28 '20 at 21:26
2
$("input").bind("keydown", function(event) {

    if (event.which === 13 && this.type !== 'submit') {
        event.preventDefault();
        $(this).next("input").focus();
    }
});
qwertymk
  • 34,200
  • 28
  • 121
  • 184
1

Based on this post: http://forum.jquery.com/topic/how-to-find-next-node-in-focus-order

I came up with this. I eventually chose not to use focasables though, and instead use input to get the effect I wanted. The .not is to prevent image buttons and submit buttons from being effected, so that they still have the default action of submit on enter whenever they have focus.

$(document).ready(function() {
var focusables = $(":input").not('[type="image"]').not('[type="submit"]');

  focusables.keydown(function(e) {
    if (e.keyCode == 13) {
      e.preventDefault();
      var current = focusables.index(this),
              next = focusables.eq(current + 1).length ? focusables.eq(current + 1) : focusables.eq(0);
      next.focus();
    }
  });
});
AaronLS
  • 37,329
  • 20
  • 143
  • 202