someuser2491
someuser2491

Reputation: 1968

How to make the dropdown usable with up and down keyboard arrow keys and enter keys using react?

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

Answers (1)

Vahid
Vahid

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

Related Questions