Prevent keypress event trigger when input is in focus - javascript

I am currently using a switch to trigger some code when a key is pressed. This isn't the exact code, but its basically what I am using (this is just for the sake of keeping it short and simple on here.)
$(document).keydown(function(e) {
switch(e.keyCode) {
case 39:
e.preventDefault();
alert("Arrow Key");
break;
case 37:
e.preventDefault();
alert("Arrow Key");
}
});
How can I prevent the events from firing when an input box is in focus?

I think you mean that you want to do e.preventDefault() only if the target element was not an input tag. You can do this like this:
$(document).keydown(function(e) {
if (e.target.nodeName.toLowerCase() !== 'input') {
switch(e.keyCode) {
case 39:
e.preventDefault();
alert("Arrow Key");
break;
case 37:
e.preventDefault();
alert("Arrow Key");
}
}
});
e.target is the element where the event originated. Alternatively, you can use jQuery's event delegation API:
$(document).delegate(':not(input)', 'keydown', function(e) {
switch(e.keyCode) {
case 39:
e.preventDefault();
alert("Arrow Key");
break;
case 37:
e.preventDefault();
alert("Arrow Key");
}
});
Edit Updated my answer to do "not an input" rather than "is an input" checks.

You can use document.activeElement which returns the currently focused element.
Brief doc from the MDN:
Returns the currently focused element, that is, the element that will get keystroke events if the user types any. This attribute is read only.
That is, in order to prevent keystroke events from firing when input is in focus, you can just ignore keystroke events handling when the focused element is an input
if (!$(document.activeElement).is("input"){ /* handle keystroke events here */ }

There may be a more elegant way but I would do something like this:
var inputHasFocus = false;
$("#some_input_id").focusin(function () {
inputHasFocus = true;
}).focusout(function () {
inputHasFocus = false;
});
and then use that in your case statement.

Related

Bootstrap dropdown-menu prevented keys

I have an input field that shows suggestions with a dropdown menu while i type. My example is simpified, but the problem is the same.
If I have focus on the top menu item and press the arrow up key I would like to set focus on the input field (without closing the menu).
It seems like Bootstrap is preventing event bubbeling of some of the keys.
The escape key is just for testing. It's the arrow up key I want to use.
You can find a jsfiddle here.
EVENT KEY RESULT
keypress [any] not working
keydown arrowup not working
keydown escape working
keyup arrowup working, but will move focus when on second item too
HTML:
<div class="dropdown">
<input type="text" class="form-control">
<ul class="dropdown-menu" role="menu">
<li><a href="#" id='AAAA'>AAAA</a></li>
<li>BBBB</li>
<li>CCCC</li>
</ul>
</div>
JS:
$('.form-control').bind('keypress', function(event) {
if (event.key === 'ArrowDown') {
if ($('.dropdown').hasClass('open')) {
$('#AAAA').focus();
} else {
$('.dropdown').addClass('open');
}
}
});
$('#AAAA').bind('keyup', function(event) {
switch (event.key) {
case 'ArrowUp':
$('.form-control').focus();
break;
case 'Escape':
$('.form-control').focus();
break;
}
});
Well, I first closed the dropdown ( removed the open class ) and then focused on the input. It seems to be working now.
$('#AAAA').bind('keydown', function(event) {
switch (event.key) {
case 'ArrowUp':
$('.dropdown').removeClass('open');
$('input').focus();
break;
case 'Escape':
$('.form-control').focus();
break;
}
});
Edit ( After you updated your question ): keydown is being used by bootstrap. You can bind all events on keyup. keyup event fires after keydown so you don't need to use setTimeout()
$('#AAAA').bind('keyup', function(event) {
switch (event.key) {
case 'ArrowUp':
$('.form-control').focus();
break;
case 'Escape':
$('.form-control').focus();
break;
}
});
Edit 2 ( Solves the: If you press the up key when on the second item, you will release the key on the first item and it will set focus on the input ) I kept the use of setTimeout() to let bootstrap complete its own working. This will also let keypress work from bottom to input. jsFiddle Link
$('.dropdown').on('keydown.bs.dropdown.data-api', function(e) {
var index = $(this).find('li:not(.disabled):visible a').index(e.target);
if (!index && e.which == 38) {
setTimeout(function() {
$('.form-control').focus();
}, 1);
}
});
I solved it like this until anyone can find a better solution. I wrapped the focus() in a timer.
$('#AAAA').bind('keydown', function(event) {
switch (event.key) {
case 'ArrowUp':
setTimeout(function() {
$('.form-control').focus();
}, 1);
break;
case 'Escape':
$('.form-control').focus();
break;
}
});

how can give arrow key events in full page image silder

How can give arrow key events in full page image slider, for example the below sample link -> https://www.htmllion.com/examples/pure-css-based-fullscreen-slider-demo.html.
I need the same layout with arrow key events.
Kindly help.
Use Keyboard events in Jquery. Based on the user click navigate the page
Using jQuery you can do something like this.
$(window).on('keyup', function(e){
console.log(e.keyCode); // log the keycode of the key pressed
switch(e.keyCode){
case 37:
console.log('Prev');
break;
case 38:
console.log('Up');
break;
case 39:
console.log('Next');
break;
case 40:
console.log('Down');
break;
}
});
You can add a keydown event to any element and call a function.
In the below example i have used an input text field to add a keydown event and it gives alert on pressing left or right arrow key
function myFunction(event) {
var keyVal = event.keyCode;
switch(keyVal)
{
case 37:
alert('Pressed left');
break;
case 39:
alert('Pressed right');
break;
}
}
<input type="text" onkeydown="myFunction(event)">

Binding arrow keys in jQuery except in input and textarea

I found this excellent question about binding the arrow keys with jQuery: Binding arrow keys in JS/jQuery with a great solution from Sygmoral:
$(document).keydown(function(e) {
switch(e.which) {
case 37: // left
break;
case 38: // up
break;
case 39: // right
break;
case 40: // down
break;
default: return; // exit this handler for other keys
}
e.preventDefault(); // prevent the default action (scroll / move caret)
});
EXCEPT: This prevents the arrow keys from working the way they would usually work when the focus is in a text input field.
How would I modify this solution to allow the arrow keys to function normally when the current focus is in an input, text area, or another content editable area?
Put this in a condition:
$(document).keydown(function(e) {
if(!$(e.target).is(':input, [contenteditable]')){
switch(e.which){
// the cases as is
}
e.preventDefault(); // prevent the default action (scroll / move caret)
}
});
You can use event.target to get the target element of event, so you can check
var $target = $(e.target);
if($target.is("input") || $target.is("textarea")) {
//
}
Your editable element may have some common class
$('.input').keypress(function(event) {
var charCode = (evt.which) ? evt.which : event.keyCode
switch(charCode) {
case 37: // left
break;
case 38: // up
break;
case 39: // right
break;
case 40: // down
break;
default: return; // exit this handler for other keys
}
e.preventDefault();
});

Disable keydown event defined by javascript in textarea and restore default behavior

I am using reveal.js by Hakim El Hattab to make presentation slides. I have added textarea to a slide. Within the textarea I want to prevent javascript functions from being called when certain keys are pressed, and restore the default behavior of typing. For example, as you can see from the lines of code below from reveal.js, when p is pressed, a function navigatePrev() is called. I want to prevent this function from being called and simply want p to be typed in the textarea when p is pressed. How can I do this using jquery? I tried adding the following script but that does not help.
<script>
$(document).keydown(function (e) {
if ($(e.target).is('textarea')) {
e.stopPropagation();
}
})
</script>
The functions defined in the reveal.js are still called. Using return false in place of e.stopPropagation() does not help either. I am also including the above jQuery lines at the very end on my page (after reveal.js is called).
Thank you.
Relevant lines from reveal.js
function onDocumentKeyDown(event) {
// FFT: Use document.querySelector( ':focus' ) === null
// instead of checking contentEditable?
// Disregard the event if the target is editable or a
// modifier is present
if (event.target.contentEditable != 'inherit' || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
var triggered = false;
switch (event.keyCode) {
// p, page up
case 80: case 33: navigatePrev(); triggered = true; break;
// n, page down
case 78: case 34: navigateNext(); triggered = true; break;
// h, left
case 72: case 37: navigateLeft(); triggered = true; break;
// l, right
case 76: case 39: navigateRight(); triggered = true; break;
// k, up
case 75: case 38: navigateUp(); triggered = true; break;
// j, down
case 74: case 40: navigateDown(); triggered = true; break;
// home
case 36: navigateTo(0); triggered = true; break;
// end
case 35: navigateTo(Number.MAX_VALUE); triggered = true; break;
// space
case 32: overviewIsActive() ? deactivateOverview() : navigateNext(); triggered = true; break;
// return
case 13: if (overviewIsActive()) { deactivateOverview(); triggered = true; } break;
}
}
The problem with your keydown event binding is that it binds to the document, which receives the event LAST (once it's too late to prevent the event from bubbling further up the DOM tree).
Instead, try binding the event directly to the textarea every time it is created:
// create text area & append to slide container
createTextAreaOnSlideContainer();
// bind an event handler to the element
$('textarea.slideTextArea').keydown( function(e) {
e.stopPropagation();
});
This will stop the event before it bubbles (propagates) up to the document that is listening for a key to be pressed
You can do this:
$(document).keydown(function(e){
if(!$('#textarea').is(':focus')){
yourfunction();
}
});
You just simply add an if statement inside and if the textarea is not focused then you call the function.

Keypress not firing In Firefox

I am using a JavaScript keypress switch to fire events, and it works fine in webkit browsers, but it does not work in Firefox. Can anyone help? The code I am using is:
$(document).keydown(function(e) {
switch(e.keyCode) {
case 39:
event.preventDefault();
alert("Arrow Key");
}
break;
case 37:
event.preventDefault();
alert("Arrow Key");
}
});
The functions I am trying to fire are more complex than just an alert, but i thought i would keep it simple for the explanation.
IIRC Firefox use charCode and not keyCode.
Can you try that :
$(document).keydown(function(e) {
kCode = (e.keyCode)? e.keyCode: e.charCode;
switch(kCode) {
case 39:
event.preventDefault();
alert("Arrow Key");
}
break;
case 37:
event.preventDefault();
alert("Arrow Key");
}
});
You have an syntax-error(a wrong bracket } before break;), and an undefined object(event) inside your function.
$(document).keydown(function(e) {
switch(e.keyCode) {
case 39:
e.preventDefault();
alert("Arrow Key");
break;
case 37:
e.preventDefault();
alert("Arrow Key");
}
});
The wrong object(event) does'nt occur in MSIE, as there is always a global object called "event"

Categories