Capture TAB keydown and trigger other keypress - javascript

I am trying to change the behaviour of selects in an html form.
I would like that when a user navigates the form using the keyboard, if they are selecting an element and presses tab, the element is selected and the focus switches to the next form input. Normally, you need to press enter to select the element and then you can use tab to switch to the next one. If enter isn't pressed, no option is selected.
To do this, I want to capture the TAB keypress and trigger an ENTER keypress followed by a TAB.
This is what I have for now:
$('form[class="ui form"]').on('keydown', 'div[class="ui fluid selection dropdown active visible"]', function (e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
var y = jQuery.Event('keydown', {which: 13});
$(this).trigger(y);
var x = jQuery.Event('keydown', {which: 9});
$(this).trigger(x);
}
});
Here is a demo: JSFiddle
The code 'works' up to e.preventDefault(), the tab keypress doesn't switch the focus to the next input. However, the enter and tab actions aren't triggered, so nothing happens. What should I do ?
Thank you in advance !
UPDATE 10/10: Found the problem! Triggering event x (tab keypress) makes the code enter an infinite loop. Therefore the whole approach is wrong. I'll soon post an answer.

When I try it passing whichas the event object, it does work jsfiddle.net/mendesjuan/sL7tnfm6/5
$('form[class="ui form"]').on('keydown', 'div[class="ui fluid selection dropdown active visible"]', function (e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
var y = jQuery.Event('keydown', {which: 13});
$(this).trigger(y);
}
});

The draft code in the question triggers an infinite loop. The key point in the problem is capturing the selected (active) element when the user presses TAB and switches the focus to the next element.
So, it is better to use a function called onblur:
$('form[class="ui form"]').on('blur', '.dropdown', function () {
var y = jQuery.Event('keydown', {which: 13});
$(this).trigger(y);
});

Related

Manually triggering jquery keyup event passing wrong keycode

I have an input that I want to allow the user to save the text either by pressing enter or by clicking anywhere else on the screen. Getting the code to process when the user presses enter is no problem. But I want to process the same code by triggering the jquery keyup event when the user clicks away just as if they pressed Enter on the input box instead. The theory isn't giving me an issue, but the keycode is either not being passed correctly or interpreted correctly when clicking away. When I alert the interpreted keycode, I get a "1" which doesn't equate to any keypress. What am I doing wrong?
$(document).on("click","body",function(e){
if(e.target.id!="openInput"){ //Indicates user has clicked out away from the input
if($(".attributeEdit")[0]){ //This is a unique class added
var i = $.Event('keyup');
i.which = 13;
$(".attributeEdit").trigger(i); //Have also tried triggering off #openInput, too with no success
}
}
});
$(document).on("keyup",".attributeEdit",function(){
var keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '13'){
do stuff;
}
else{
alert("keycode: " + keycode); //This results in a "1" every time user clicks away
}
});
I found a solution to the end objective using Hiren Raiyani's suggestion of a function call. It doesn't actually answer the original question, but since it solved my problem, I'm hoping this will be useful to others that search. I created a function to "do stuff" and that way, I can call that function both after the Enter key is pressed and after the mouse is clicked.
function doStuff(x,y){
do stuff
}
$(document).on("click","body",function(e){
if(e.target.id!="openInput"){ //Indicates user has clicked out away from the input
if($(".attributeEdit")[0]){ //This is a unique class added
doStuff(x,y);
}
}
});
$(document).on("keyup",".attributeEdit",function(){
var keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '13'){
doStuff(x,y);
}
});

preventDefault enter key event without preventing scrolling

I want to prevent default actions except scrolling. When I have added e.preventDefault in keyDown event (Enter key) it also prevents browser from scrolling. I want to prevent actions on enter key press except scrolling. Is there any way to distinguish between enter key event and scroll? Or can we partially prevent default actions where scroll should work and other actions are prevented. Any help would be highly appreciated.
document.getElementById('textBox').addEventListener("keydown", function(event) {
// Number 13 is the "Enter" key on the keyboard
if (event.keyCode === 13) {
// Cancel the default action, if needed
event.preventDefault();
}
});
I have added preventDefault in enter action. For some reason I must add this line to code but this is also preventing my page from scrolling.
I want to keep preventDefault but my page should scroll. Is there any way to do so?
Just add a new line to textarea whenever event is triggered.
document.getElementById('textBox').addEventListener("keydown", function(event) {
// Number 13 is the "Enter" key on the keyboard
if (event.keyCode === 13) {
var cursor= this.selectionEnd;
this.value = this.value.substring(0, cursor) + '\n' +
this.value.substring(cursor);
this.selectionEnd = cursor+1;
event.preventDefault();
}
});
<textarea style="height:200px;width:300px" id="textBox"></textarea>
Note: I noticed OP is using contenteditable in this case. Here is a fork of OP's JSFiddle. I have made few changes with making different element editable because that seemed more appropriate.

JQuery on keydown event to focus to a button seems to automatically press the button?

I have two text inputs and a button.
For both text inputs, I set a keydown event with JQuery to switch focus to the next element on pressing Enter.
So:
Pressing Enter while in the first input should focus to the second input.
Pressing Enter while in the second input should focus to the button.
var counter = 0;
function Foo()
{
$('#output').html(++counter);
}
function FocusToLastName(evt)
{
var keyCode = evt.keyCode || evt.which;
if (keyCode==13) $('#lastname').focus();
}
function FocusToButton(evt)
{
var keyCode = evt.keyCode || evt.which;
if (keyCode==13) $('#btn').focus();
}
$('#firstname').on('keydown',FocusToLastName);
$('#lastname').on('keydown',FocusToButton);
$('#firstname').focus();
#output { color:#0f0; background:#80f; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id='firstname' type='text'>
<input id='lastname' type='text'>
<button id='btn' onclick='Foo()'>OK</button>
<h1 id='output'></h1>
To see what happens:
Click on first input field to set focus there.
Press Enter. Focus will move to second input field (correct).
Press Enter again. Focus will move to the button (correct) however the button's onclick event is also triggered (NOT correct)
Note that this only happens when I use the Enter key. If I change the keyCode condition to 40 instead of 13 (for cursor key down ↓ instead of Enter) in both event handlers, it works as expected.
Additionally, another small problem: I automatically focus to the first input element which doesn't seem to work. But that may be related to JSFiddle.
You need to stop the default event. Use the event.preventDefault() method to do so in your focus to button function like so :
function FocusToButton(evt)
{
evt.preventDefault();
var keyCode = evt.keyCode || evt.which;
if (keyCode==13) $('#btn').focus();
}
It would be a good idea to add it to other functions as well. Read more on preventDefault() here

Preventing backspace to go back from the current form

I'm using the below JavaScript function to prevent backspace from going back.
function preventBackspace(e) {
var evt = e || window.event;
if (evt) {
var keyCode = evt.charCode || evt.keyCode;
if (keyCode === 8) {
if (evt.preventDefault) {
evt.preventDefault();
} else {
evt.returnValue = false;
}
}
}
}
I have added onkeydown="preventBackspace();" to all the text boxes.
I have two radio buttons and two textboxes which when checked make the other textbox readonly. When hitting the backspace key it is not going to back page, but I am not able to delete from the editable text box. Please suggest. Thanks!
When the user is currently focused on a textbox, the backspace key does not cause the browser to go back. The backspace in a textbox is used to delete a character - and since you've added preventDefault(), you're stopping that behavior from happening.
If your goal is to prevent the user from accidentally leaving the form before they are finished, you can use window.onbeforeunload to display a warning message that allows the user to cancel navigation:
window.onbeforeunload = function() {
return "Are you sure you want to leave this page? Your current entries" +
" will be lost.";
};

Prevent Enter key works as mouse click

I noticed that if you focus on an element that mouse clic can be triggered, the Enter keys acts like as you left click the mouse. I want to avoid this running since it comes into conflict in other pieces of my code.
In the following example if I focus on this imageButton and I clic once, the next clicks can be "done" with the Enter key, so I don't want this because this button fires a slideToggle() and shows a hidden div, so IMO it's pointless toggle this div with the keyboard.
Is there any way to make it global way?
Thank you.
Try this:
$(".myElements").keypress(function(e) {
if (e.which == 13) {
e.preventDefault();
}
});
It will stop the enter key behaviour only, allowing the other key functions to work as usual.
Listen for "keypress" and .preventDefault()
ex. with <myelm class="nokey"/>
function noKeyPressing(){
var elms = document.getElementsByClassName('nokey'),
stop = function stop(e){ return e.preventDefault(), false; },
i = elms.length;
while(--i >= 0){
elms[i].addEventListener('keypress', stop, true);
}
}
noKeyPressing()
If you just want to prevent Enter then the keyCode to look for is 13.
try
.unbind('keydown');
to disable all key events on your element
You can return false to prevent the default action.
<input type="submit" onkeypress="return false;" value="Submit" />
An other possible way i think:
$('.elems').on('click',function(){$(this).blur()});
try this code
$('body *').keypress(function (e) {
if (e.which == 13) {
e.preventDefault();
}
});
the above code will prevent pressing enter for every element in page
,You can change the selector $('body *') to something else depending to your case

Categories