Beginner
Beginner

Reputation: 9095

how to obtain scroll to view inside a div

i am having a input box and search results div, whenever i type something i am able to see the results but when i do the navigation through keys the scroll to view is not happening.

how can i achieve this. I have created the working example in codesanbox.

scenario

  1. type "1" in input box
  2. click on down arrow key upto 3rd element you will be able to see red color css as highlight but after that the navigation is going on but the scroll is not happening

any help appreicated

Upvotes: 0

Views: 82

Answers (1)

Cat_Enthusiast
Cat_Enthusiast

Reputation: 15688

Here's your updated sandbox friend: https://codesandbox.io/s/react-codesandbox-5fvk9

The main thing I added was a ref creating logic.

In the component and outside render(), we define an array to keep track of all our refs.

  itemRefs = []

That array gets populated in .map() by passing in the ref prop available in each tag.

{searchResults.map((item, index) => {
    return (
      <li
         ref={ref => (this.itemRefs[index] = ref)}
         onClick={() => this.goToItem(index)}
         className={cursor === index ? 'active' : null}
      >
        <label className="first-lb">{item.id}</label>
        <label className="second-lb">{item.name}</label>
        <label className="third-lb">{item.address}</label>
      </li>
    )
})}

Then we have an onClick-handler that accepts a ref index, which we use to scroll into that selected item.

  goToItem = index => {
    if (this.itemRefs[index]) {
      this.itemRefs[index].scrollIntoView({behavior: 'smooth', nearest: "block"})
    }

    this.setState({
      cursor: index,
    })
  }

Additionally, to handle the scroll events on arrow-key down and arrow-key up.

  _keyDownOnSearchResults = e => {
    const {cursor, searchResults} = this.state
    if (e.keyCode === 38 && cursor > 0) {
      this.itemRefs[cursor - 1].scrollIntoView({
        behavior: 'smooth',
        nearest: 'block',
      })
      this.setState(prevState => ({
        cursor: prevState.cursor - 1,
      }))
    } else if (e.keyCode === 40 && cursor < searchResults.length - 1) {
      this.itemRefs[cursor + 1].scrollIntoView({
        behavior: 'smooth',
        nearest: 'block',
      })
      this.setState(prevState => ({
        cursor: prevState.cursor + 1,
      }))
    }
  }

Upvotes: 1

Related Questions