I'm trying to action a function when either a button is clicked or the spacebar is pressed.
I have this working to some degree but it's not how I want it.
Here's my function:
const showText = () => {
const x = ToughSpellings.toString();
console.log(x);
}
Here's my button and spacebar actions:
<input type="text" id="one" onKeyUp={showText} />
<button onClick={showText}>Show Next Letter</button>
I cannot work out how to use onKeyUp without an input field. How can I use this function when the user is simply looking at the website?
Without using an input field, you'd need to setup a document event listener to listen for keyboard events.
You could have the following code in your React component:
const keyDownHandler = (event) => {
console.log(event.keyCode); // Key UP would return `38`
// Handle key event here based on `event.keyCode`
};
useEffect(() => {
document.addEventListener("keydown", keyDownHandler);
return () => document.removeEventListener("keydown", keyDownHandler);
}, []);
Related
When calling stepDown and stepUp on a <input type='range'>, the input or change events are not being triggered.
Here's a code sample of the issue in action:
<p>J and K move slider left and right but aren't triggering event.
Using mouse though successfully updates label.</p>
<p>Label isn't updating on keypress which is
calling <code>stepDown()</code> and <code>stepUp()</code></p>
<input type='range' id='number' step='10'/>
<label id='value'>50</label>
const numberEl = document.getElementById('number')
const valueEl = document.getElementById('value')
// Same issue is present when listening to 'change'
numberEl.addEventListener('input', (event) => {
valueEl.innerText = event.target.value
})
document.addEventListener('keydown', (event) => {
if (event.code === 'KeyJ'){
numberEl.stepDown()
}
if (event.code === 'KeyK'){
numberEl.stepUp()
}
})
You'll have to trigger the change event in the key down event manually since onchange only fires when the element loses focus
...
if (event.code === 'KeyJ'){
numberEl.stepDown()
}
if (event.code === 'KeyK'){
numberEl.stepUp()
}
const ev = new Event('change');
numberEl.dispatchEvent(ev);
...
I have a input for searchbox. I must make like; Write my words fors search then after i press enter it must need go another page with input value. So i can access that value with query string. So how can i route another page with value of input after i press enter ? Thank you for help! I Just add That codes for catch enter press.
useEffect(() => {
const listener = (event) => {
if (event.code === "Enter" || event.code === "NumpadEnter") {
alert("Enter key was pressed. Run your function.");
event.preventDefault();
}
};
document.addEventListener("keydown", listener);
return () => {
document.removeEventListener("keydown", listener);
};
}, []);
You don't necessarily have to set an event listener, using onKeyDown event handler will also do. Enter key has a code of 13, so we just have to detect that.
Keep your value in a state (here, myValue), detect that you've pressed Enter key (here, using keyPressHandler method), and finally, pass the parameter to your route.
import {useHistory} from "react-router-dom"
function App() {
let history = useHistory();
const [myValue, setMyValue] = useState("");
const handleChange = ({ target: { value } }) => {
setMyValue(value);
};
const keyPressHandler = (e) => {
if (e.which === 13) {
// alert("You pressed enter!");
history.push("/process/" + myValue);
}
};
return (
<div className="App">
<input value={myValue} onKeyDown={keyPressHandler} onChange={handleChange} />
</div>
);
}
UPDATE:
According to MDN Web Docs, e.which is non-standard [Source] and e.keyCode is deprecated [Source], so you should be using e.key instead like:
const keyPressHandler = (e) => {
if (e.key=== 'Enter') {
// alert("You pressed enter!");
history.push("/process/" + myValue);
}
};
Working CodeSandbox Link
I need to know if I can verify if user pressed a key or not only with onchange event, because I get the text on input with a QR reader, but there also exists the possibility for the user to manually enter the data.
I have this code (example):
_getValue = (event) => {
let value = event.target.value;
}
render() {
<input type="text" onChange={this._getValue} />
}
So, on _getValue method, which is from an onchange event, I need to check if the change is coming from a key or from the QR reader.
Thank you to all!
You could use the keydown event.
You would probably end up with something like this
_getValue = (event) => {
let value = event.target.value;
}
const handleKeyPress = (e) => {
e.preventDefault();
return;
}
render() {
<input type="text" onChange={this._getValue} onKeyPress={handleKeyPress} />
}
You can read more on the event on MDN
When a user types something in an <input type="text"> and removes the focus, both blur and change are fired.
However, when I do the same thing in JavaScript using the blur() method, only the blur event is fired and not the change event. Is there a reason for this inconsistency?
See this example code (jsfiddle):
<input type="text">
<button>Test</button>
const input = document.querySelector("input")
input.addEventListener("blur", () => console.log("blur"))
input.addEventListener("change", () => console.log("change"))
const button = document.querySelector("button")
button.addEventListener("click", () => {
setTimeout(() => {
input.focus()
input.value = "something"
input.blur()
}, 1000)
})
When clicking the button, after a second, it should focus the input, change the value and blur the input. However, only the blur event is fired. Doing the same by hand will fire both events.
I like to trigger some validation logic on the change event and it works perfectly fine in real-live but when I try to recreate the workflow in a unittest it fails and I'm not sure why and how to solve it.
So the alternative question is: How can I trigger the change event from JavaScript?
This issue
The change event is specifically emitted when a user interacts with an element. This is built in a was intentional. #see HTMLElement: change event.
The solution
Use synthetic events to mimic user interaction in changing the value: input.dispatchEvent(new Event("change"));
Below is a working example with the logic in its own function updateValueWithChangeEvent .
const input = document.querySelector("input")
input.addEventListener("blur", () => console.log("blur"))
input.addEventListener("change", () => console.log("change"))
// Updates the value of an input and triggers the change Event.
const updateValueWithChangeEvent = (input, value) => {
if (input.value === value) return
input.value = value
input.dispatchEvent(new Event("change"));
}
// Updated example using function above
const button = document.querySelector("button")
button.addEventListener("click", () => {
setTimeout(() => {
// This will update value and trigger change event
updateValueWithChangeEvent(input, "something")
// This will trigger the blur event
input.focus()
input.blur()
}, 1000)
})
<input type="text">
<button>Test</button>
You can trigger an event like this:
const input = document.querySelector("input");
const event = new Event("change");
// blur the input
input.blur();
// dispatch change event manually
input.dispatchEvent(event);
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
I have a button that can be highlighted with Tab, where pressing Enter when the button is highlighted creates an Input field. That input field is then focused.
The input field has a keyUp event and if the key is Enter/Return, blur the field (and save the info that was put into the field).
The issue:
Tab to select Button
Keydown Enter/Return to create Input field
Input field is now focused
Keyup Enter/Return
Input becomes blurred
What I need is to know if the enter/return key was pressed on mount and stop the Keyup event from firing if that is true.
export default function EditableLabel({
active,
value: valueProp,
variant,
...rest
}) {
const [returnPressedOnMount, setReturnPressedOnMount] = useState(false);
let isReturnPressed = false;
// Only set this listener on mount
useEffect(() => {
document.addEventListener('keypress', isReturnKey, false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
function isReturnKey(event) {
console.log(event.keyCode);
if (!returnPressedOnMount && event.keyCode === 13) {
console.log('In the return key func');
setReturnPressedOnMount(true);
isReturnPressed=true;
console.log(isReturnPressed)
}
document.removeEventListener('keypress', isReturnKey, false);
}
function handleBlur(evt) {
setIsEditing(false);
rest.onChange && rest.onChange({ target: { value } });
rest.onBlur && rest.onBlur(evt);
}
function handleKeyUp(evt) {
console.log(returnPressedOnMount);
console.log(isReturnPressed);
if (evt.key === 'Enter') {
if (!returnPressedOnMount) {
const target = evt.target;
setTimeout(() => target.blur(), 0);
} else {
setReturnPressedOnMount(false);
}
}
rest.onKeyUp && rest.onKeyUp(evt);
}
return (
<Input .../>
);
}
This code works if I hold the Enter/Return key down for a long time, but if someone presses the key normally (just tap the key, not holding it down) the State/Variable do not update in time for the onKeyUp.
How do I get the knowledge of the Return key being pressed on Mount to the onKeyUp function?