Setting focus to next page element on keypress - javascript

I'm having trouble setting the focus to the next element on the page from a data grid. The idea is that the user will navigate a data grid with arrow keys, but when pressing the tab key, the focus on the page will be moved from the data grid to an entirely different element within the page.
I'm trying to have the tab keypress set the focus to the next page element(outside of the data grid), but this doesn't seem to work with the current switch case I have setup:
document.querySelector('.ag-body').tabIndex=0;
let lastHeaderCell = false;
document.addEventListener("keydown", function(e) {
if (e.keyCode == 9 && e.shiftKey == true) {
let currentFocusedElement = document.activeElement;
let compId = currentFocusedElement.getAttribute("comp-id");
currentFocusedElement.classList.add('focus-visible');
console.log("Shift + Tab currently focused on: ", currentFocusedElement)
let bodyFocused = document.querySelector('.ag-body').classList.contains('focus-visible');
if(bodyFocused == true){
document.querySelector('.ag-cell').classList.add('focus-visible');
}
}
else if(e.key === "ArrowRight"){
let headerId = document.activeElement.parentElement.parentElement.getAttribute("col-id");
const headerCell = document.querySelector('.ag-header-cell:last-child').children[1].children[1];
const hasFocusVisible = document.activeElement.classList.contains('focus-visible');
if(lastHeaderCell === true) {
document.querySelector('.ag-cell').focus();
lastHeaderCell = false;
}
else if(headerCell.classList.contains('focus-visible')) {
lastHeaderCell = true;
}
}
else if(e.key === "ArrowDown"){
//get column id on arrowdown
let cellHeaderId = document.activeElement.parentElement.parentElement.getAttribute("col-id");
document.querySelector('.ag-cell[col-id="' + cellHeaderId + '"]').focus();
}
else if(e.key === "ArrowUp") {
//store value of grid cell column id
let cellId = document.activeElement.getAttribute("col-id");
let rowId = document.activeElement.parentElement.getAttribute("row-id");
//set focus to column header if active cell is in first row and remove body cell focus
if(rowId === "0"){
document.querySelector('.ag-cell[col-id="' + cellId + '"]').classList.remove('ag-cell-focus');
document.querySelector('.ag-header-cell[col-id="' + cellId + '"] .ag-header-cell-label').focus();
}
}
else if(e.key === "Tab"){
let header = document.querySelector('.ag-header-cell-label').classList.contains('focus-visible');
console.log("Header has focus visible: ",header)
//store currently focused cell on tab
let currentFocusedElement = document.activeElement;
let compId = currentFocusedElement.getAttribute("comp-id");
console.log("Currently Focused Element: ",compId);
//removes focus from current cell
document.activeElement.blur();
console.log("Active Element was: ", document.activeElement)
if(header == true) {
document.querySelector('.ag-header-cell').tabIndex = -1;
document.querySelector('.ag-cell[col-id="' + compId + '"]').classList.add('ag-cell-focus');
}
}
});
Example of current grid state: Link

Related

Manipulating integers using a keyboard

Sorry for the vague post. I'm stuck on an online coding challenge, where the objective is that it must be possible to increase and or decrease a number using a keyboard, using the up and down keys. (all HTML-content must be created using JS)
It wants me to use addEventListener without an element object - use the event type keydown. Regardless if the buttons or the up and down keys are used, the decrease button must be 'disabled' if the values in the div-element is '1', and there can't be a number less than '1' in the div element.
Here is my code so far - I'm not sure how to incorporate the functions described above:
addEventListener('load', function() {
let button = document.createElement('input')
let secondButton = document.createElement('input')
button.setAttribute('type', 'button')
button.setAttribute('id', 'increase')
secondButton.setAttribute('type', 'button')
secondButton.setAttribute('id', 'decrease')
document.body.appendChild(button)
document.body.appendChild(secondButton)
let div = document.createElement('div')
div.setAttribute('id', 'bet-size')
div.textContent = '1'
document.body.appendChild(div)
if (Number(div.textContent) === 1) {
secondButton.setAttribute('disabled', '')
}
const increase = function() {
div.textContent = Number(div.textContent) + 1
if (Number(div.textContent) > 1) {
secondButton.disabled = false
}
}
const decrease = function() {
if (Number(div.textContent) === 2) {
secondButton.disabled = true
}
if (Number(div.textContent) > 1) {
div.textContent = Number(div.textContent) - 1
}
}
button.addEventListener('click', increase)
secondButton.addEventListener('click', decrease)
})
You want to use keyDown event's keyCode property to determine the pressed key and call increase() or decrease() accordingly. keyCode stores a number indicating the key that caused the event evocation. There are a number of sites on the internet to determine your desired key code, like this for example.
You also might want to use keyUp to determine key releases again because you might get these events multiple times and only want to react to one of them.
let isKeyDown = false;
const handleKeyDown = function(event) {
if(isKeyDown == false)
{
isKeyDown = true;
if(event.keyCode == 38) // Arrow Up
{
event.preventDefault(); // Prevent page scrolling
increase();
}
else if(event.keyCode == 40) // Arrow Down
{
event.preventDefault(); // Prevent page scrolling
decrease();
}
}
}
const handleKeyUp = function(event) {
if(isKeyDown == true)
{
isKeyDown = false;
}
}
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
Your expanded example might look like this, then:
addEventListener('load', function() {
let button = document.createElement('input')
let secondButton = document.createElement('input')
button.setAttribute('type', 'button')
button.setAttribute('id', 'increase')
secondButton.setAttribute('type', 'button')
secondButton.setAttribute('id', 'decrease')
document.body.appendChild(button)
document.body.appendChild(secondButton)
let div = document.createElement('div')
div.setAttribute('id', 'bet-size')
div.textContent = '1'
document.body.appendChild(div)
if (Number(div.textContent) === 1 ) {
secondButton.setAttribute('disabled', '')
}
const increase = function() {
div.textContent = Number(div.textContent) + 1
if (Number(div.textContent) > 1) {
secondButton.disabled = false
}
}
const decrease = function() {
if (Number(div.textContent) === 2) {
secondButton.disabled = true
}
if (Number(div.textContent) > 1) {
div.textContent = Number(div.textContent) - 1
}
}
// Required to remember if a key is already pressed or not
let isKeyDown = false;
//Event handlers for KeyUp And KeyDown
const handleKeyDown = function(event) {
if(isKeyDown == false)
{
isKeyDown = true;
if(event.keyCode == 38) // Up
{
event.preventDefault(); // Prevent page scrolling
increase();
}
else if(event.keyCode == 40) // Down
{
event.preventDefault(); // Prevent page scrolling
decrease();
}
}
}
const handleKeyUp = function(event) {
if(isKeyDown == true)
{
isKeyDown = false;
}
}
button.addEventListener('click', increase)
secondButton.addEventListener('click', decrease)
//Add the new event handlers to the document's keydown and keyup events
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
})

go to next image element when right arrow is pressed

So if i had an element like this on HTML
index.html
<div><img id="2" src="1.jpg"><img id="2" src="2.jpg"></div>
that created by js like this
index.js
let image = document.createElement("img")
image.src = img.image
image.style.width = "725"
image.style.height = "1024"
image.setAttribute("id",img.index)
how can I make if the right arrow pressed it go to the top of the next image index
I've try this
image.onkeydown = function(e) {
e = e || window.event;
if (e.keyCode == '37') {
document.location.href = `#${img.index--}`
} else if (e.keyCode == '39') {
document.location.href = `#${img.index++}`
}
}
but didn't work
You should not change the document.location, the script will have to rerun because the page is reloaded. Instead just scrollIntoview:
Also no need for index, you can calculate the index from the content
const imageArr = [
"https://via.placeholder.com/725x1024/000000/FFFFFF/?text=image1",
"https://via.placeholder.com/725x1024/FF0000/0000FF/?text=image2",
"https://via.placeholder.com/725x1024/FFAAFF/00AA00/?text=image3"
]
const container = document.getElementById("imageContainer");
container.innerHTML = imageArr.map(img => `<img src="${img}" />`)
const images = container.querySelectorAll("img");
let current = 0;
const max = imageArr.length
window.addEventListener("keydown", function(event) {
if (event.defaultPrevented) {
return; // Do nothing if event already handled
}
const key = event.code;
if (key === "ArrowLeft") current--;
else if (key === "ArrowRight") current++
// wrap
if (current < 0) current = max; // change to current=0 if no wrap
else if (current >= max) current = 0; // change to current = max if no wrap
images[current].scrollIntoView()
})
<div id="imageContainer"></div>

Use Enter Keydown Event to move to the next Input

I have a large form. As users are filling in values I would like for the enter key to take on the same behavior as the tab key (i.e. I want to move the user to the next input element when the enter key is pressed.
Due to the way my HTML form is structured into various sections I cannot assume the next input is a sibling of the current input. Additionally, the classes and IDs of the inputs are not sequential.
jQuery:
$("input").bind("keydown", function (event) {
document.getElementById('keys').innerHTML = document.getElementById('keys').innerHTML + event.which + " ";
if (event.which === 13) {
event.stopPropagation();
event.preventDefault();
var e = $.Event("keydown");
e.which = 9;
$(this).trigger(e);
}
});
JSFIDDLE
This will do your job
$("input").not($(":button")).keypress(function (evt) {
if (evt.keyCode == 13) {
iname = $(this).val();
if (iname !== 'Submit') {
var fields = $(this).parents('form:eq(0),body').find('button, input, textarea, select');
var index = fields.index(this);
if (index > -1 && (index + 1) < fields.length) {
fields.eq(index + 1).focus();
}
return false;
}
}
});
example

Focus button from javascript withour clicking it

I call
element.focus();
Where element is HTMLInputElement of type=button.
But then the browser clicks the button! That's in mozilla and chrome.
How do i highlight the button with selection, but not initiate the click event?
No .focus() doesn't click the button or submits the form: http://jsbin.com/onirac/1/edit
It does exactly what you want it to.
Well, i've identified the reason.
I was handling the onkeydown event for Enter key.
The solution is to use
e.preventDefault();
function ConvertEnterToTab(s, e, numSkipElements) {
var keyCode = e.keyCode || e.htmlEvent.keyCode;
if (keyCode === 13) {
var tabIndex = s.tabIndex || s.inputElement.tabIndex;
if (numSkipElements == undefined) {
numSkipElements = 0;
}
var nextElement = FindNextElementByTabIndex(tabIndex + numSkipElements);
if (nextElement != undefined) {
nextElement.focus();
return e.preventDefault ? e.preventDefault() : e.htmlEvent.preventDefault(); // this is the solution
}
}
}
function FindNextElementByTabIndex(currentTabIndex, maxTabIndex) {
if (maxTabIndex == undefined) {
maxTabIndex = 100;
}
var tempIndex = currentTabIndex + 1;
while (!$('[tabindex='+ tempIndex+ ']')[0] || tempIndex === maxTabIndex) {
tempIndex++;
}
return $('[tabindex=' + tempIndex + ']')[0];
}

Switch between two textareas only when pressing Tab button

Normally when a user is visiting a web page and pressing TAB button on a keyboard, the selection moves from one element to another starting from the begining of the page.
I am looking for a solution to switch between two particular text areas by pressing TAB button on a keyboard with an initial focus on the first one when web page is loaded? All other elements on the page have to be ignored for this TAB key press event.
How can I achive this?
Thanx for your help!
= Update =
I have managed to make it work under Firefox 12.0 . IE and Chrome do not work properly. Asuming the text area IDs are #ICCID and #MSISDN, the Jquery looks like this:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$(document).ready(function() {
$("#ICCID").focus();
});
var $inp = $('.cls');
$inp.bind('keydown', function(e) {
var key = e.which;
if (key == 9) {
e.preventDefault();
var nxtIdx = $inp.index(this) + 1;
$(".cls:eq(" + nxtIdx + ")").focus();
//Simulate Enter after TAB
var textInput = $("#MSISDN").val();
var lines = textInput .split(/\r|\r\n|\n/);
if (lines > 1) {
$("#MSISDN").on("keypress", function(e) {
if (e.keyCode == 9) {
var input = $(this);
var inputVal = input.val();
setTimeout(function() {
input.val(inputVal.substring(0,inputVal.length) + "\n");
}, 1);
}
});
}
}
if (key == 9) {
e.preventDefault();
var nxtIdx = $inp.index(this) - 1;
$(".cls:eq(" + nxtIdx + ")").focus();
//Simulate Enter after TAB
$("#ICCID").on("keypress", function(e) {
if (e.keyCode == 9) {
var input = $(this);
var inputVal = input.val();
setTimeout(function() {
input.val(inputVal.substring(0,inputVal.length) + "\n");
}, 1);
}
});
}
});
});
</script>
Catch the keydown action using jQuery, determine which textarea has focus, and then use the focus() method to set the focus to the other textarea.
Supposing that your textareas have id="textarea1" and id="textarea2". First you can set focus to the first textarea when the page loads by doing : $('#textarea1').focus();
$("body").keypress(function(e) {
var code = (e.keyCode ? e.keyCode : e.which);
switch(code)
{
case 9:
if($("#textarea1").focus()){
//First one has focus, change to second one
$("#textarea2").focus();
}
else if($("#textarea2").focus()) {
//Second one has focus, change to first one
$("#textarea1").focus();
}
}
});
Ok I have found the solution for for my task! It also includes the simulation of ENTER key just after the TAB key event, so user do not need to hit ENTER to go to the new line. Tested with IE9, FF12, Chrome 18.0.x
Here it is:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<!-- Switching between ICCIDs and MSISDNs textareas + simulating ENTER key pressing after the TAB key event - START -->
<script type="text/javascript">
$(function() {
$(document).ready(function() {
$("#ICCID").focus();
});
var $inp = $('.cls');
$inp.bind('keydown', function(e) {
var key = e.which;
if (key == 9) {
e.preventDefault();
var nxtIdx = $inp.index(this) + 1;
$(".cls:eq(" + nxtIdx + ")").focus();
//Simulate Enter after TAB
var textInput = $("#MSISDN").val();
var lines = textInput .split(/\r|\r\n|\n/);
if (lines > 1) {
$("#MSISDN").on("keyup", function(e) {
if (e.keyCode == 9 || e.which == 9) {
var input = $(this);
var inputVal = input.val();
setTimeout(function() {
input.val(inputVal.substring(0,inputVal.length) + "\r\n");
}, 1);
}
});
}
}
if (key == 9) {
e.preventDefault();
var nxtIdx = $inp.index(this) - 1;
$(".cls:eq(" + nxtIdx + ")").focus();
//Simulate Enter after TAB
$("#ICCID").on("keyup", function(e) {
if (e.keyCode == 9 || e.which == 9) {
var input = $(this);
var inputVal = input.val();
setTimeout(function() {
input.val(inputVal.substring(0,inputVal.length) + "\r\n");
}, 1);
}
});
}
});
});
</script>
<!-- Switching between ICCIDs and MSISDNs textareas + simulating ENTER key pressing after the TAB key event - END -->
What about this.... Im to bored at work i think..
http://jsbin.com/uqalej/3/
HTML:
<input/>
<textarea id="t1"></textarea>
<textarea id="t2"></textarea>
<input/>
<button onClick='window.toggleBetween=true;'>Init</button>
<button onClick='window.toggleBetween=false;'>Destroy</button>
JS:
var d = document,
t1 = d.getElementById("t1"),
t2 = d.getElementById("t2"),
nodeType, nodeTypes = [],
i, iLen,
y, yLen;
nodeTypes.push( d.getElementsByTagName("textarea") );
nodeTypes.push( d.getElementsByTagName("input") );
nodeTypes.push( d.getElementsByTagName("select") );
i = 0;
iLen = nodeTypes.length;
for ( ; i < iLen; i++ ) {
nodeType = nodeTypes[i];
y = 0;
yLen = nodeType.length;
for ( ; y < yLen; y++ ) {
if ( nodeType[y] != t1 && nodeType[y] != t2 ) {
nodeType[y].onfocus = function() {
if ( window.toggleBetween )
t1.focus();
};
}
}
}
Using javascript on page load:
document.getElementById("textarea1").focus();
document.getElementById('textarea1').tabIndex="1";
document.getElementById('textarea2').tabIndex="2";

Categories