This is the function I want to invoke in an input type:
_handleOnEnterPress = (e, receiverUserId) => {
if (e.keyCode === 13) { // guess keycode 13 is enter?
console.log("pressed enter. user id = ",receiverUserId)
}
};
and this is the input type I want to invoke when ENTER is pressed, I used onKeydown
<input className="popup-input"
onKeyDown={this._handleOnEnterPress(chatFriendPopPup.id)}
onChange={this._handleMessageTextChange}
type='text'
/>
when I press enter, it's not logging on the console. I used e(event) default arg so it can detect the keycode 13 (enter) but I guess the if fails? since the receiverUserId is on 2nd index, do I not have to pass e (event) arg on onKeyDown when the function is invoked?
Have you tried onKeyDown={(e) => this._handleOnEnterPress(e, chatFriendPopPup.id)} ?
Try using an arrow function to catch the event and then pass that event object as well any argument you like to the handler method of your choosing.
handler(e, someInput) {
// do something in here
if (someInput === 'foo') console.log('bar');
}
render() {
const someArg = 'foo';
return (
<button onClick={e => this.handler(e, someArg)}>Do something</button>
)
}
Related
document.addEventListener('keydown', (event) => {
var name = event.key;
var code = event.code;
if (name === 'Control') {
location.replace(classroom.google.com)
}
if (event.ctrlKey) {
alert(`Combination of ctrlKey + ${name} \n Key code Value: ${code}`);
} else {
alert(`Key pressed ${name} \n Key code Value: ${code}`);
}
}, false);
// Add event listener on keyup
document.addEventListener('keyup', (event) => {
var name = event.key;
if (name === 'Control') {
location.replace(classroom.google.com)
}
}, false);
How currently when I press the control key, nothing happens. If I make it run an alert instead, then the alert will successfully run. Do I need to use the window.location function instead?
The issue with your code is that you aren't passing a string to location.replace().
Right now, your code looks like this.
location.replace(classroom.google.com);
The issue with this code is that you are not surrounding it with quotes to make it a string, so JavaScript thinks that you are referencing a property of an object, of an object.
Below is what JavaScript thinks is happening.
const classroom = {
google: {
com: undefined,
}
};
console.log(classroom.google.com); // undefined
To fix it, simply surround your parameter in quotes, as so.
location.replace("classroom.google.com");
This should successfully redirect you to classroom.google.com!
I set up debounce inside my functional component like this:
const debouncedFunc= debounce(myFunction, 500);
I have the below TextField
<TextField
id="myField"
maxLength={8}
onChange={(e) => debouncedFunc(e.target?.value)}
/>
I have the myFunction like this
function myFunction(val) {
if (val.length === 8) {
console.log(val);
}
}
So this works well. It prints value when a user types eight characters into the field. The problem is that I need to empty the value in this field when a user types eight characters, and debounced function does kick in. Normally, TextField, I can empty the value in the field by e.target.value="". Since I am in the debounce function, I do not have a reference to the e, so I cannot empty it.
Long question short, what is the best way to empty the textfield from a debounce function?
My current and only solution is this, anyone that can think of a better solution please do share
export default function DebounceFeaturedTextfield() {
const debouncedFunc= debounce(myFunction, 500);
let TextFieldRef = "";
function myFunction(val) {
if (val.length === 8) {
TextFieldRef.setInputValue("");
}
}
return (
<TextField
ref={(r) => {
TextFieldRef = r;
}}
id="myField"
maxLength={8}
onChange={(e) => debouncedFunc(e.target?.value)}
/>
);
}
I'm detecting keypresses in a component that is aware of what dialog component is currently open elsewhere in the app via a prop, currentDialog. Normally I'd be able to access this prop in a nested function but it seems this isn't possible when using useCallback:
export const AllAreaNav = (props) => {
console.log('AllAreaNav / props.currentDialog: ', props.currentDialog); // displays correct dialog
const handleKeyPress = useCallback((event) => {
console.log('AllAreaNav / handleKeyPress / props.currentDialog: ', props.currentDialog); // displays undefined
if(event.keyCode === 70) {
//Do whatever when F is pressed
console.log("F key pressed");
if (props.currentDialog == "DialogSearchBar") {
// Take action based on DialogSearchBar being active
} else {
// Take action based on DialogSearchBar NOT being active
}
}
}, []);
useEffect(() => {
// Listener for keypresses
document.addEventListener("keydown", handleKeyPress, false);
return () => {
document.removeEventListener("keydown", handleKeyPress, false);
};
}, []);
return (
{jsxElements}
)
};
So now I'm a little unsure of a straightforward way of passing this as a parameter - assuming this would be the next step. From researching I believe it's fine to add another parameter alongside event? That this should work as I intend:
const handleKeyPress = useCallback((event, currentDialog) => {
However, I'm not entirely sure of how to initially pass this to the function. If I modify the listener to be:
document.addEventListener("keydown", handleKeyPress(event, props.currentDialog, false);
I'm unsure if this is correct, or where exactly to define event in this context, in the manner handleKeyPress defaults its as a parameter.
It seems that you were trying to resolve the problem by parametrizing the callback but you did not have an event in your context. In order to parametrize AND have the event in context, you must create a closure on the currentDialog parameter.
You can try this solution:
/**
* move callback definition outside the component
* and create a closure on currentDialog (function returning a function)
*/
const handleKeyPress = (currentDialog) => (event) => {
if (event.keyCode === 70) {
//Do whatever when F is pressed
console.log("F key pressed");
if (currentDialog == "DialogSearchBar") {
// Take action based on DialogSearchBar being active
} else {
// Take action based on DialogSearchBar NOT being active
}
}
};
export const AllAreaNav = (props) => {
console.log("AllAreaNav / props.currentDialog: ", props.currentDialog); // displays correct dialog
useEffect(() => {
// Listener for keypresses
const listener = handleKeyPress(props.currentDialog); // use closure to create a callback closured on currentDialog value
document.addEventListener(
"keydown",
listener,
false
);
return () => {
document.removeEventListener(
"keydown",
listener,
false
);
};
}, [handleKeyPress, props.currentDialog]); // pass callback and currentDialog value to dependency array
return { jsxElements };
};
I find this code interesting because every time I press a key from my keyboard it alerts it. However how to detect a key with combination
Example
Alt + 1 -- I want to alert something
Alt + 2 -- same here
ETC. Any combination that I want.
I try his code and create an if statement to it
$(document).keypress(function(event){
alert(String.fromCharCode(event.which));
if( String.fromCharCode(event.which) == "a"){
alert("Hi A.");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Credit to Coyod
If you change the event to keydown you will get extra event data that will tell you if any modifier keys are pressed.
Then inside the event callback you can check event.altKey to check if the alt key is currently pressed.
$(document).keydown(function(event) {
if (event.altKey) {
switch (String.fromCharCode(event.which)) {
case 'A':
console.log('Hi A')
break
case 'B':
console.log('Hi B')
break
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Here is a better example that will keep the state of all pressed keys, allowing you to test if more than one key is pressed at the same time. In the callback you have a function checkKeysPressed which takes the keys you wish to add the event for, if those keys are pressed the function will return true.
It's using ES6 syntax, functions and objects, but it could be converted to ES5 easily or just run through babel.
const multipleKeysEventListener = (element, callback) => {
const keysPressed = new Set
const describeKey = e => {
switch(e.which) {
case 18:
return 'ALT'
case 16:
return 'SHIFT'
default:
return String.fromCharCode(e.which)
}
}
const checkPressedKeys = (...keys) =>
keys.every(x =>
keysPressed.has(
typeof(x) === 'number'
? String.fromCharCode(x)
: x
)
)
const down = e => {
keysPressed.add(describeKey(e))
return callback(checkPressedKeys, e)
}
const up = e => {
keysPressed.delete(describeKey(e))
}
$(element).keydown(down)
$(element).keyup(up)
}
multipleKeysEventListener(document, (checkKeysPressed, e) => {
switch (true) {
// you can pass keys
case checkKeysPressed('A', 'B'):
console.log('A and B pressed')
break
// you can pass modifiers
case checkKeysPressed('ALT', 'A'):
console.log('ALT and A pressed')
break
// and you can pass keyCodes
case checkKeysPressed('ALT', 67):
console.log('ALT and C pressed')
break
default:
console.log(String.fromCharCode(e.which))
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
if I want to handle input of character *, I can use handleBeforeInput(str):
handleBeforeInput(str) {
if (str !== '*') {
return false;
}
// handling
return true;
}
if I want to handle input of ENTER, I can use the hook handleReturn(e)
but if I want to handle input of DELETE, how to do?
Draft's Editor component takes an optional prop called keyBindingFn. If you assign a function to it, that function will receive all keyDown events. In theory, you could do whatever you want in this function, but its responsibility is really to return a command, of type string, that should be executed for a specific key (or combination of keys). It could look something like this:
function keyBindingFn(e) {
if (e.key === 'Delete') {
return 'delete-me' // name this whatever you want
}
// This wasn't the delete key, so we return Draft's default command for this key
return Draft.getDefaultKeyBinding(e)
}
The Editor component also takes another optional prop called handleKeyCommand. If a function is assigned to this, it will receive all commands executed in the editor. This means that it, if you used my example above, would receive the command 'delete-me', whenever the delete key is pressed. This is the place to handle that command.
function handleKeyCommand(command) {
if (command === 'delete-me') {
// Do what you want to here, then tell Draft that we've taken care of this command
return 'handled'
}
// This wasn't the 'delete-me' command, so we want Draft to handle it instead.
// We do this by telling Draft we haven't handled it.
return 'not-handled'
}
To clarify, you pass these functions to the Editor component like this:
<Editor
keyBindingFn={keyBindingFn}
handleKeyCommand={handleKeyCommand}
... // other props
/>
You can read more about it in the Draft docs.
The way to do it in draft-js version ^0.11.7 is:
import Editor, {getDefaultKeyBinding, KeyBindingUtil} from 'draft-js';
const {hasCommandModifier} = KeyBindingUtil;
class MyEditor extends React.Component {
constructor(props) {
super(props);
this.handleKeyCommand = this.handleKeyCommand.bind(this);
}
// ...
handleKeyCommand(command: string): DraftHandleValue {
if (command === 'enter_command') {
console.log('enter_command');
return 'handled';
}
if (command === 'ctrl_s_command') {
console.log('ctrl_s_command');
return 'handled';
}
return 'not-handled';
}
myKeyBindingFn = (e) => {
if (e.keyCode === 13 /* `enter` key */ ) {
return 'enter_command';
}
if (e.keyCode === 83 /* `S` key */ && hasCommandModifier(e) /* + `Ctrl` key */) {
return 'ctrl_s_command';
}
//else...
return getDefaultKeyBinding(e);
}
render() {
return (
<Editor
editorState={this.state.editorState}
handleKeyCommand={this.handleKeyCommand}
keyBindingFn={myKeyBindingFn}
...
/>
);
}
}
You can detect Delete key using JavaScript's keydown event as follows:
var input_field = document.getElementById('your_text_field');
input_field.addEventListener('keydown', function () {
if (event.keyCode == 46) { //Here 46 is key-code of "Delete" key
//...your work when delete key pressed..
}
});
Hope, you needed this.