I'm creating a ponent that contains an input that directs the user to a new tab upon pressing enter or clicking the search button. The search button functions correctly, however I'm having trouble getting the input to call the handleSubmit method on enter key press. As of now, pressing the enter key does nothing. How can I achieve this? code:
const LinkCard = (props) => {
const [searchInput, setSearchInput] = useState("");
const handleChange = (e) => {
setSearchInput(e.target.value);
};
const handleClick = (e) => {
e.preventDefault();
location.assign(";);
};
const handleSubmit = (e) => {
e.preventDefault();
location.assign(";);
};
return (
<Flex borderWidth="1px" borderRadius="lg" alignItems="center">
{props.icon}
<Box>{props.websiteName}</Box>
<InputGroup>
<Input
placeholder={"Search " + props.websiteName}
onChange={handleChange}
onSubmit={handleSubmit}
flexGrow="1"
m="2%"
/>
<Link href={props.url} passHref={true}>
<a>
<InputRightElement m="2%">
<Button onClick={handleClick}>
<FaSearch />
</Button>
</InputRightElement>
</a>
</Link>
</InputGroup>
</Flex>
);
};
I'm creating a ponent that contains an input that directs the user to a new tab upon pressing enter or clicking the search button. The search button functions correctly, however I'm having trouble getting the input to call the handleSubmit method on enter key press. As of now, pressing the enter key does nothing. How can I achieve this? code:
const LinkCard = (props) => {
const [searchInput, setSearchInput] = useState("");
const handleChange = (e) => {
setSearchInput(e.target.value);
};
const handleClick = (e) => {
e.preventDefault();
location.assign("http://www.mozilla");
};
const handleSubmit = (e) => {
e.preventDefault();
location.assign("http://www.mozilla");
};
return (
<Flex borderWidth="1px" borderRadius="lg" alignItems="center">
{props.icon}
<Box>{props.websiteName}</Box>
<InputGroup>
<Input
placeholder={"Search " + props.websiteName}
onChange={handleChange}
onSubmit={handleSubmit}
flexGrow="1"
m="2%"
/>
<Link href={props.url} passHref={true}>
<a>
<InputRightElement m="2%">
<Button onClick={handleClick}>
<FaSearch />
</Button>
</InputRightElement>
</a>
</Link>
</InputGroup>
</Flex>
);
};
Share
Improve this question
asked Aug 30, 2021 at 6:14
JacobDClarkJacobDClark
771 gold badge1 silver badge6 bronze badges
3 Answers
Reset to default 5const [value, setValue] = React.useState('');
return (
<form
onSubmit={e=> {
e.preventDefault();
location.assign('?wd=' + value)
}}>
<input value={value} onChange={(e)=> setValue(e.currentTarget.value)} />
<button type="submit">Search</button>
</form>
)
or
const [value, setValue] = React.useState('');
return (
<>
<input
value={value}
onChange={(e)=> setValue(e.currentTarget.value)}
onKeyPress={e=> {
if (e.key === 'Enter') {
location.assign('?wd=' + value)
}
}}
/>
<button onClick={()=> location.assign('?wd=' + value)}>Search</button>
</>
);
There are 2 possible ways you can achieve that:
- Add a key listener on your
submitHandler
:
const handleSubmit = e => {
e.preventDefault();
if (e.key === "Enter") {
location.assign("http://www.mozilla");
}
};
- Having a
form
around your input and add submit an event:
<form onSubmit={handleSubmit}>
<Input
placeholder={"Search " + props.websiteName}
onChange={handleChange}
onSubmit={handleSubmit}
flexGrow="1"
m="2%"
/>
</form>;
Typescript Answer
I found this was a mon enough problem to create a few util helper functions for:
import {KeyboardEvent} from "react"
export function handleEnterKeyPress<T = Element>(f: () => void){
return handleKeyPress<T>(f, "Enter")
}
function handleKeyPress<T = Element>(f: () => void, key: string){
return (e: KeyboardEvent<T>) => {
if(e.key === key){
f()
}
}
}
The functions are "higher order" in the sense that they lift a regular, zero argument void function up and give you back a nicely typed event handler that can be passed straight into the onKeyDown
method.
Sample code:
<Input {...props} onKeyDown={handleEnterKeyPress(myFunction)}/>
Where myFunction
is any void function you'd like to run whenever the enter key is pressed.
Note: You should use onKeyDown
rather than onKeyPress
as the latter is deprecated.
Update
If you want to handle multiple keys, I've found a slightly more flexible version of the above to be helpful:
import {KeyboardEvent} from "react"
export function handleEnterKeyPress<T = Element>(f: () => void){
return handleKeyPress<T>({Enter: f})
}
export type KeyPressMap = {
[key: string]: () => void
}
export function handleKeyPress<T = Element>(map: KeyPressMap){
return (e: KeyboardEvent<T>) => {
const handler = map[e.key]
if(handler !== undefined){
handler()
}
}
}
Then in your ponent, you can call it with something like this for example, where handleEnter
and handleEscape
are assumed to be some functions accessible to your ponent:
const keyPressHandlers = {
Enter: handleEnter,
Escape: handleEscape
}
return <Input onKeyDown={handleKeyPress(keyPressHandlers)}/>