Nicolás Giossa
Nicolás Giossa

Reputation: 41

Building an autocomplete textbox with ReactJS

My idea is to mantain the list of filtered users (suggestions) as state on the component, when the input changes, the state is updated.

How can I display the filtered list below the text box? One option is 'datalist' tag (HTML5), but the list is already filtered, and part of the functionality of this tag is filtering. I can't use any library or framework.

English is not my native language, sorry if you find some mistake.

Thanks.

Upvotes: 2

Views: 11284

Answers (4)

cjn
cjn

Reputation: 1471

Even if you could use dependencies, I tried a bunch of the top current ones and personally wasn't happy with any of them (added dependencies like jQuery, not lightweight to use/understand/customize, css challenges, etc).

In then end, I found this lightweight vanilla React typeahead tutorial (no, I didn't write the tutorial). It's quick, simple, and three's no added dependency tree weight (eg: jQuery) or dependency maintenance. This solution also easily adjusted to the newer React patterns & the libraries I was using, and I'm guessing the same would be true of the patterns/libraries you may be using. Maybe this will help you or someone else like it did me.

Upvotes: 0

Jon B
Jon B

Reputation: 2834

How I did it was to pass in the dataList array as a prop and filterByField prop so that you can change what to filter, then add an event listener to the input (onChange) that passes the value to a function that filters the dataList.

onChangeInput(e) {
  const { dataList, filterByField } = this.props;
  const filteredDataList = dataList.filter(items => items[filterByField].toLowerCase().startsWith(e.target.value.toLowerCase())  );
  // update internal component state to trigger render of dropdown list
  this.setState({filteredList: filteredDataList});
}

I also added a check for no matches found so I can show a message:

if (filteredDataList.length === 0) {
  this.setState({noMatchFound: true});
}

Then in my render() I simply check if filteredList isn't null and show an unordered list that I use css to display below the input.

{this.state.filteredList !== null
  <ul className="autocomplete-list">
    {this.filteredListMarkup()}
  </ul>
}

filteredListMarkup() then uses map to return an <li> for each item with the necessary event handlers to update the selected item into the input and close the autocomplete-list by this.setState({filteredList: null});

Upvotes: 1

Conan
Conan

Reputation: 690

You might also find this one useful:

https://github.com/reactjs/react-autocomplete

Upvotes: 0

Andrew Heekin
Andrew Heekin

Reputation: 671

Try a component from a design library, like the Material-UI autocomplete component http://www.material-ui.com/#/components/auto-complete

The dataSource attribute represents the array of autocomplete options.

Upvotes: 1

Related Questions