Reputation: 155
I have a button and a series of text fields. I am trying to facilitate keyboard navigation. Here is what I have:
HTML
<button id="button1">Click me</button>
<input type="text" id="field1" name="field1">
<input type="text" id="field2" name="field2">
<input type="text" id="field3" name="field3">
JS/JQUERY v 1.9.1
/* If they click the button */
$('#button1').on('click', function() {
moveToNextInputField(); /* <-- Mystical function to "focus" the next input */
});
/* If they hit "enter" on the button */
$('#button1').on('keyup', function(e) {
if (e.which === 13) {
moveToNextInputField();
}
});
/* Capture keyboard input to limit to Numbers */
$('input').on('keydown', function (e) {
switch(e.which) {
case 48:
case 49:
case 50: /* All numbers, or wanted keys, etc.... */
$(this).data('changed', true);
break;
default:
e.preventDefault(); /* prevent other unwanted keys from doing anything */
break;
}
});
/* Capture keyboard input for keyboard navigation */
$('input').on('keyup', function (e) {
switch (e.which) {
/* other cases to do stuff excluded */
case 13:
moveToNextInputField();
break;
}
});
The problem I am having is that in Firefox and IE10 (possibly others), When I select the button and press "ENTER" it triggers 2 events. The first event moves the focus to the next field, and the second does the same thing. It appears that I cannot press the "ENTER" key fast enough. When I run this code and press "enter" on the button I end up in field2.
So to my question: Is it possible to "lock" an event so that it only triggers 1 event instead of several?
As a side note, if there is a better way to do this I'm all ears.
Solution:
I found my answer was a combination of things recommended.
Here is what the solution that worked looks like:
/* If they click the button or press ENTER while focused */
$('#button1').on('click', function(e) {
e.stopImmediatePropigation();
moveToNextInputField(); /* <-- Mystical function to "focus" the next input */
});
/* Capture keyboard input to limit to Numbers */
$('input').on('keydown', function (e) {
switch(e.which) {
case 48:
case 49:
case 50: /* All numbers, or wanted keys, etc.... */
$(this).data('changed', true);
break;
default:
e.preventDefault(); /* prevent other unwanted keys from doing anything */
break;
}
});
/* Capture keyboard input for keyboard navigation */
$('input').on('keyup', function (e) {
switch (e.which) {
/* other cases to do stuff excluded */
case 13:
moveToNextInputField();
break;
}
});
Thanks all for the help.. Hopefully this helps someone else too. Cheers.
Upvotes: 1
Views: 1270
Reputation: 1510
You must notice that click is kind of special event. It is generated when button function has to be triggered. So it happens usually after mousedown, ENTER or SPACE. You can apply few solutions
btw. i also recommend use keypress not keyup - look here.
Upvotes: 1
Reputation: 318212
This is easy, when focusing the button and clicking enter, both the click and keyup event handlers fire.
In other words, focusing a button and hitting enter will trigger a click event on the button, so change this :
$('#button1').on('click', function() {
moveToNextInputField(); /* <-- Mystical function to "focus" the next input */
});
$('#button1').on('keyup', function(e) {
if (e.which === 13) {
moveToNextInputField();
}
});
to just:
$('#button1').on('click', function() {
moveToNextInputField(); /* <-- Mystical function to "focus" the next input */
});
as the keyup event handler is not needed.
as a sidenote, you could shorten that to:
$('#button1').on('click', moveToNextInputField);
Upvotes: 1
Reputation: 621
You may try jQuery's deferred to do that. Whichever fires first, you can set the deferred object to resolved. You can check for the state of the object to see if its pending to fire first time and not when already resolved.
Upvotes: 0