0

I have an html form.

  1. It uses keyboard navigation (with arrow keys) to move between fields including the enter key.
  2. It periodically needs to prompt the user for acceptance of information.
  3. The enter key is picked up on both the button and in the form field.

Problem: When the user hits ENTER on the accept button it is triggering double events in my form. Shifting the focus 2 fields instead of 1.

I have code that demonstrates exactly what I'm talking about here:

Original Post http://jsfiddle.net/mcraig_brs/UgUUr/1/

Modified Post http://jsfiddle.net/mcraig_brs/UgUUr/2/

Here is the sample HTML:

<button id="myButton">Press Enter On Me</button><br>
<input type="text" id="text1" class="tInput" data-index="0"><br>
<input type="text" id="text2" class="tInput" data-index="1"><br>
<input type="text" id="text3" class="tInput" data-index="2"><br>
<div id="log"></div>

Here is the sample JS:

function log ( data ) {
    $('#log').append(data + "<br>");   
}
function focusOn(index) {
    log("focusOn(index): " + index);
    $('input.tInput').eq(index).focus();   
}
function focusNext( currentIndex ) {
    log("focusNext(currentIndex):" + currentIndex);
    focusOn(currentIndex + 1);
}
function focusPrevious (currentIndex) {
    log('focusPrevious(currentIndex):' + currentIndex);
    focusOn(currentIndex - 1);
}
$('#myButton').on('click', function(e) {
    log("event:click #myButton");
    focusOn(0);
});
$('input.tInput').on('keyup', function(e) {
    switch (e.which) {
        case 13:
            log("event:ENTER key in input.tInput");
            focusNext($(this).data('index'));
            break;
        case 38:
            log("event:UP ARROW key in input.tInput");
            focusPrevious($(this).data('index'));
            break;
        case 40:
            log('event:DOWN ARROW key in input.tInput');
            focusNext($(this).data('index'));
            break;
    }   
});

When I press "ENTER" while the focus is on the button in the current code I get the following output in the log div:

event:click #myButton
focusOn(index): 0
event:ENTER key in input.tInput
focusNext(currentIndex):0
focusOn(index): 1

(At the moment in jsFiddle the only way I can get to the button is to focus on the first text field and shift+tab back to it so it has focus, so that I can press ENTER on it. But in the live code it is automatically focused for the user.)

Question: How can I prevent this type of double event from triggering? I have tried e.stopPropagation() but that did not yield the results I was looking for. When the user pressed ENTER I want the focus to advance only one field.

I have been wrestling with this for a few days so any help would be greatly appreciated. Please note that if a user clicks on the button with the mouse it works properly, it is only the ENTER key that triggers the double event.

Note: I had to modify my question slightly to better convey the constraints.

5
  • 3
    Just a note, I have never pressed enter on a form for the purpose of going to the next field. It has always been tab for me. Commented Sep 19, 2013 at 13:46
  • Me either, but unfortunately part of the program requirements is acceptance of the enter key in the fields. The users have been "trained" that they must user "enter" at this particular local. Commented Sep 19, 2013 at 13:47
  • 1
    I changed keyup to keypress and it fixed your issue. Is there a reason for using keyup? Commented Sep 19, 2013 at 13:50
  • I originally had it as keypress when I first started the project a couple months ago, there was a reason I changed it and for the life of me I can't remember why. Well I'll change it back and see what happens. Thanks. Commented Sep 19, 2013 at 16:43
  • I figured out why I used keyup/keydown instead of keypress. I am also using the arrow keys to navigate up/down. keypress does not properly work for arrows in some browsers. Commented Sep 19, 2013 at 17:34

2 Answers 2

4

keyup is triggering the issue, change it to keypress

$('input.tInput').on('keypress', function(e) {
    switch (e.which) {
        case 13:
            log("event:ENTER key in input.tInput");
            focusNext($(this).data('index'));
            break;
    }   
});

from http://www.quirksmode.org/dom/events/keys.html

keypress

Fires when an actual character is being inserted in, for instance, a text input. It repeats while the user keeps the key depressed.

keyup

Fires when the user releases a key, after the default action of that key has been performed.

---- edit ---

To catch key press and keyup both, I would suggest to define it separately, http://jsfiddle.net/UgUUr/3/

$('input.tInput').on('keypress', function(e) {
    switch (e.which) {
        case 13:
            log("event:ENTER key in input.tInput");
            focusNext($(this).data('index'));
            break;
    }   
});

$('input.tInput').on('keyup', function(e) {
    switch (e.which) {
        case 38:
            log("event:UP ARROW key in input.tInput");
            focusPrevious($(this).data('index'));
            break;
        case 40:
            log('event:DOWN ARROW key in input.tInput');
            focusNext($(this).data('index'));
            break;
    }   
});
Sign up to request clarification or add additional context in comments.

1 Comment

Hello, I had to modify the question slightly, I have used "keypress" but had to switch to "keyup/keydown" to capture the arrow keys. I had forgotten that when I originally posted the question.
1

Use keypress event instead:

$('input.tInput').on('keypress', function(e) {    
    switch (e.which) {
        case 13:
            log("event:ENTER key in input.tInput");
            focusNext($(this).data('index'));
            break;
    }   
});

DEMO

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.