Manipulating integers using a keyboard - javascript

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);
})

Related

JavaScript KeyDown event

I have the following function for example
function RequestInputType(Input) {
inputType: Input
}
So now i want to call this function to cycle throug with an input value if key is pressed.
window.addEventListener('keydown', e => {
if (9 === e.keyCode) {
e.preventDefault();
RequestInputType(0)
//i Want it if key is pressed again then switch from RequestInputType(0) to RequestInputType(1)
RequestInputType(1)
//and if pressed again
RequestInputType(2)
//and so on
}, false);
How do i go about that?
You can create a keydown counter.
var keydownCounter = 0;
window.addEventListener('keydown', e => {
if (9 === e.keyCode) {
e.preventDefault();
keydownCounter++
if(keydownCounter % 3 == 0){
RequestInputType(0)
}
else if(keydownCounter % 3 == 1){
RequestInputType(1)
}
else if(keydownCounter % 3 == 2){
RequestInputType(2)
}
}
},false)
Use a global variable to hold the current argument to pass to requestInputType(). Then you can increment it and wrap around after each call.
let curInputType = 0;
let maxInputType = 3;
window.addEventListener('keydown', e => {
if (9 === e.keyCode) {
e.preventDefault();
RequestInputType(curInputType);
curInputType = (curInputType + 1) % maxInputType;
}
}, false);

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>

Setting focus to next page element on keypress

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

Change character when keydown is held

I am trying to make a simple way to change a character in an input field when the key is held down for more than 1second. For example holding down a would then change the character to á.
The exact thing I am looking to do can be seen on fluencia.com.
Also there is a need to be able to change the character if it is held for a further second.
So far, all I have done is detect the key held with the following code:
count = 0;
$(document).bind('keypress', function(e){
keyisdown = false;
key = e.which
if (e.which === key) {
keyisdown = true;
count ++;
if(count>1){
}
}
}).bind('keyup',function(){
keyisdown = false;
count = 0;
console.log('key up');
});
Thanks
Adam
This should do it for key "a".. You'll need to look up your keycode
var fired = false;
$(document).on("keydown", function(e) {
if (e.keyCode == 65) {
var timer = setTimeout(function() {
if (!fired) console.log('its held');
fired = true;
}, 1000);
$(document).on("keyup", function() {
clearTimeout(timer);
});
}
});
fiddle - http://jsfiddle.net/0a9rftt2/
With help from Graham T above and a bit of playing around I come up with the following:
var fired = false;
var keycode = null;
var key = null;
$("#loginEmail").on("keypress", function(e) {
keycode = e.which;
key = String.fromCharCode(keycode);
});
$("#loginEmail").on("keydown", function(e) {
var s = this.value;
var str = this.value;
if (e.keyCode == 65) {
var timer = setTimeout(function() {
if (!fired) console.log('its held');
fired = true;
if(fired){
s = $("#loginEmail").val();
str = s.substring(0, s.length - 1);
replacewith = 'á';
str = str+replacewith;
$("#loginEmail").val(str);
}
}, 500);
$(document).on("keyup", function() {
clearTimeout(timer);
fired = false;
});
}
});
It is not cleaned up as yet. I had to use keypress to get the true character (capitalised or not) and then used keydown to detect key being held down.

capturing simultaneous left and right mouse button clicks in javascript

What is the best way to capture a left AND right mouse click in javascript? I'm not using jQuery (it's next on my to-learn list), just javascript for now. Basically, I want to do something like
onClick()=javascript:rightClickFunction() // do right click function
onContextMenu()=javascript:leftClickFunction() /
onBoth() ???
The only thing I could find on stackoverflow was:
How to distinguish between left and right mouse click with jQuery
How should I capture the double-button click? Can i check if the opposite button is also clicked during the R and L button routines?
You could track which mouse buttons are down with some boolean variables like this:
var leftButtonDown = false;
var rightButtonDown = false;
$(document).mousedown(function() {
if(e.which == 1) {
leftButtonDown = true;
} else if (e.which == 3) {
rightButtonDown = true;
}
});
$(document).mouseup(function() {
if(e.which == 1) {
leftButtonDown = false;
} else if (e.which == 3) {
rightButtonDown = false;
}
});
$(document).click(function() {
if(leftButtonDown && rightButtonDown) {
// left and right buttons are clicked at the same time
}
});
If both booleans are true, the right and left mouse buttons are both being clicked.
Pure Javascript solution based on the answer by Elliot:
var leftButtonDown = false;
var rightButtonDown = false;
document.addEventListener("mousedown", function () {
if (e.which == 1) {
leftButtonDown = true;
} else if (e.which == 3) {
rightButtonDown = true;
}
});
document.addEventListener("mouseup", function () {
if (e.which == 1) {
leftButtonDown = false;
} else if (e.which == 3) {
rightButtonDown = false;
}
});
document.addEventListener("click", function () {
if (leftButtonDown && rightButtonDown) {
// Click with both LMB and RMB.
}
});
For anyone still interested in a recent answer, as event.which is deprecated you can use the following code with ES6 syntax.
let leftButtonDown = false;
let rightButtonDown = false;
document.addEventListener("mousedown", (e) => {
// left click
if (e.button === 0) {
leftButtonDown = true;
}
// right click
if (e.button === 2) {
rightButtonDown = true;
}
if (leftButtonDown && rightButtonDown) {
// insert code here
}
});
document.addEventListener("mouseup", (e) => {
if (e.button === 0) {
leftButtonDown = false;
}
if (e.button === 2) {
rightButtonDown = false;
}
});
If you want to prevent the context menu from popping up you can try a variation of this:
let leftButtonDown = false;
let rightButtonDown = false;
document.addEventListener("mousedown", (e) => {
// left click
if (e.button === 0) {
leftButtonDown = true;
}
// right click
if (e.button === 2) {
rightButtonDown = true;
}
if (leftButtonDown && rightButtonDown) {
// insert code here
}
});
document.addEventListener("mouseup", (e) => {
if (e.button === 0) {
leftButtonDown = false;
}
});
document.addEventListener("contextmenu", (e) => {
if (leftButtonDown && rightButtonDown) {
e.preventDefault();
}
rightButtonDown = false;
});
Modern browsers mouse buttons mapping:
left click = 0
middle click = 1
right click = 2
IE8 and earlier mouse buttons mapping:
left click = 1
middle click = 4
right click = 2

Categories