Reputation: 1968
i am new to programming and i want to implement a dropdown menu that could be navigated with up or down arrow and enter keywboard keys.
what i am trying to do? I have a dropdown component that lists the items that were passed to it from parent component. currently it selects item in dropdown menu by mouseclick. i want it be also usable with up and down arrow keys and enter keys.
What i have tried to do? below code snippet works with mouseclick.
class Parent extends React.PureComponent {
state = {
input_val: '',
}
handle_item_select = (val) => {
this.setState({input_val: val});
}
handle_input_change = (e) => {
this.setState({input_val: e.target.value;
}
render = () => {
return (
<input
on_change={this.handle_input_change}/>
<DropDown
on_change={this.handle_item_select}
values={this.state.items}/>
)
}
}
class DropDown extends React.PureComponent {
handle_item_select = (value) => {
this.props.on_change(value);
};
render() {
return (
<div>
{this.props.values.map((value, index) =>
<Item
key={index}
value={value}
on_select={this.handle_item_select}
/>)}
</div>
);
}
}
class Item extends React.PureComponent {
handle_item_select = e => {
e.stopPropagation();
this.props.on_select(this.props.value);
};
render = () => {
return (
<div onClick={this.handle_item_select}>
{this.props.value.name}
</div>
);
}
}
Could someone help me fix this. how can i navigate through the dropdown items using arrow up/down keys and enter keys.
Thanks.
Upvotes: 1
Views: 4326
Reputation: 1378
you can try something like this
const myTextInput = props => {
const [list, setList] = useState(
[{name: 'London', id: 1},
{name: 'usa', id: 2},
]);
const [active, setActive] = useState(0);
const keyDownHandler = event => {
if (event.keyCode === 38 && active > 0) {
setActive(active - 1);
} else if (event.keyCode === 40 && active < list.length - 1) {
setActive(active + 1);
}
};
return (
<div>
<input onKeyDown={keyDownHandler} />
<ul>
{list.map((city, i) => (
<li key={city.id} className={active === i ? 'active' : 'no-active'}>
{city.name}
</li>
))}
</ul>
</div>
);
};
Upvotes: 6