Create Autocomplete in React

React Native, ReactJS

Autocomplete is an feature in which an application predicts the rest of output based on the user input. Autocomplete is used in mainly in E-Commerce, Booking applications or websites. Here we will Create Autocomplete in React websites or applications.

Create Autocomplete in React

First, we will create autocomplete in react with the react-autosuggest node package. You can read about this package in detail here.

React Autosuggest Install

yarn add react-autosuggest

or

npm install react-autosuggest --save

Use Autosuggest Component in React

Here we are using Autosuggest component in our App Component. Also we have created some functions to match or filter the inputs and outputs.

function getRegexAnywhere(val) {
	return new RegExp(`${val}`, 'i');
}

function getMatchingUser(value, data) {
	const escapedValue = escapeRegexCharacters(value.trim());
	if (escapedValue === '') {
		return [];
	}
	const regex = getRegexAnywhere(escapedValue);
	return data.filter(user => regex.test(user.name));
}

function sortMatches(matchesArr, query) {
	return matchesArr.sort ( (a,b) => {
		const matches1 = _.startsWith(a.name, query)
		const matches2 = _.startsWith(b.name, query)
		if (!matches1 && matches2)
			return true
		else if (matches1 && !matches2)
			return false
		return a.name < b.name ? -1 : +(a.name > b.name)
	}).slice(0,4)
}


function escapeRegexCharacters(str) {
	return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

function getSuggestionValue(suggestion) {
	return suggestion.name;
}

function renderSuggestion(suggestion, {
	query
}) {
	const regexp = new RegExp(`^(.*?)(${query})(.*)$`, 'i')
	let matches = getSuggestionValue(suggestion).match(regexp);
	if (!matches || matches.length < 3) return null;
	if (matches) {
		matches.shift();
		matches[0] = <b>{matches[0]}</b>;
		matches[2] = <b>{matches[2]}</b>;
	} else {
		matches = suggestion.name;
	}
	return (
		<span className="suggestion">
		<em className="username">{suggestion.username}</em><span className="name">{matches}</span>
		</span>
	);
}

class App extends React.Component {
	constructor() {
		super();

		this.state = {
			value: '',
			suggestions: [],
			selections: [],
			isLoading: false
		};

		this.cache = {
			suggestions: this.state.suggestions
		};

		this.lastRequestId = null;
	}

	loadSuggestions(value) {

		// Cancel the previous request
		if (this.lastRequestId !== null) {
			this.lastRequestId = null
		}

		if (this.cache.suggestions.length)
			this.setState({
				isLoading: true,
				suggestions: sortMatches(getMatchingUser(value, this.cache.suggestions), value)
			})
		else {
			this.setState({
				isLoading: true,
				suggestions: []
			})
		}

		this.lastRequestId = axios.get('https://jsonplaceholder.typicode.com/users?a='+Math.random())
			.then(res => {
				this.cache.suggestions = [...this.cache.suggestions, ...res.data]
				this.cache.suggestions = _.uniqBy(this.cache.suggestions, (s) => s.name)
				this.setState({
					isLoading: false,
					suggestions: sortMatches(getMatchingUser(value, this.cache.suggestions), value)
				})
			}).catch(err => {
				const data = this.cache.suggestions
				this.setState({
					isLoading: false,
					suggestions: sortMatches(getMatchingUser(value, data), value)
				})
			})
	}

	onChange = (event, {
		newValue
	}) => {
		this.setState({
			value: newValue
		});
	};

	onSuggestionsFetchRequested = ({
		value
	}) => {
		this.loadSuggestions(value);
	};

	onSuggestionsClearRequested = () => {
		this.setState({
			suggestions: []
		});
	};

	onSuggestionSelected = (evt, {
		suggestion
	}) => {
		this.setState({
			value: '',
			selections: [...this.state.selections, suggestion]
		});
	};

	render() {
		const {
			value,
			suggestions,
			isLoading
		} = this.state;
		const inputProps = {
			placeholder: "Type 'b'",
			value,
			onChange: this.onChange
		};

		return (
			<div className="wrapper">
		<section className="wrapper-input">
				{isLoading ? <span className="loading-spinner"></span> : null}
				<Autosuggest 
          suggestions={suggestions}
          onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
          onSuggestionsClearRequested={this.onSuggestionsClearRequested}
          getSuggestionValue={getSuggestionValue}
          renderSuggestion={renderSuggestion}
			onSuggestionSelected={this.onSuggestionSelected}
          inputProps={inputProps} />
		</section>
		<section className="selections">
			<h3>You have selected:</h3>
			<ul>
				{this.state.selections.map (s => <li>{s.name}</li>)}
			</ul>
				</section>
      </div>
		);
	}
}

ReactDOM.render(<App />, document.body);

Autocomplete CSS React

$clr-primary: steelblue;

.wrapper {
	width: 100vw;
	height: 100%;
	display: flex;
	flex-flow: column nowrap;
	justify-content: center;
	align-items: center;
	overflow: hidden;
}

.wrapper-input {
	display: flex;
	justify-content: center;
	align-items: center;
	position: relative;
}

.loading-spinner {
	color: red;
	position: absolute;
	left: -3em;
	content: "";
	border: 2px solid rgba(black, 0.2);
	border-top: 2px solid rgba(black, 0.4);
	width: 1em;
	height: 1em;
	border-radius: 50%;
	animation: spin 1s linear infinite;
}

@keyframes spin {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(360deg);
	}
}

.status {
	line-height: 52px;
}

.react-autosuggest__container {
	width: 24em;
	height: auto;
	position: relative;
}

.react-autosuggest__input {
	display: block;
	width: 100%;
	height: 4em;
	padding: 1em 1.5em;
	box-sizing: border-box;
	font-size: 1em;
	border: 1px solid #aaa;
	border-radius: 2em;
	outline: none;
	transition: border-radius 250ms ease;
	&:focus {
		outline: none;
		border: 1px solid $clr-primary;
	}
	.react-autosuggest__container--open & {
		border-bottom-left-radius: 0;
		border-bottom-right-radius: 0;
		border-bottom: 0;
	}
}

.react-autosuggest__suggestions-container {
	width: 100%;
	visibility: hidden;
	will-change: opacity;
	position: relative;
	overflow: hidden;
	transform-origin: 50% 0%;
	transform: scale(1, 0);
	opacity: 0;
	transition: all 250ms ease;
	.react-autosuggest__container--open & {
		display: block;
		position: absolute;
		top: 3em;
		width: 100%;
		transform: scale(1, 1);
		visibility: visible;
		opacity: 1;
		box-sizing: border-box;
		border: 1px solid $clr-primary;
		border-top: 0;
		background-color: #fff;
		font-family: Helvetica, sans-serif;
		border-radius: 2em;
		border-top-left-radius: 0;
		border-top-right-radius: 0;
		z-index: 2;
		.suggestion {
			display: flex;
			justify-content: flex-start;
			align-items: center;
		}
		.name {
			color: #ccc;
		}
		.username {
			font-size: 0.7em;
			padding: 0.25em 0.5em;
			box-sizing: border-box;
			background: #ccc;
			color: white;
			margin-right: 1em;
		}
	}
}

.react-autosuggest__suggestions-list {
	margin: 0;
	padding: 0;
	list-style-type: none;
}

.react-autosuggest__suggestion {
		cursor: default;
		box-sizing: border-box;
		padding: 1em 1.5em;
		.name b {
			font-weight: bold;
			color: #888;
		}
}

.react-autosuggest__suggestion--focused .suggestion{
	color: lighten($clr-primary, 10%);
	b {
		color: darken($clr-primary, 5%);
	}
}

Recommendation

Create Searchbar Component in React

Create Barcode in React

Using MongoDB in Node.js

Create QR Code in React

Create Tooltips in React

How to validate form in React

Create Progressbar in React

Context Menu in React

How to create charts in ReactJS

Create Popup Component in React

Create Drag and Drop List in React

MultiSelect Components in React

Types of Storage For React

Card Components in React

For more React Tutorials Click hereNode.js Tutorials Click here.

If you like this, share this.

Follow us on FacebookTwitterTumblrLinkedInYouTube.

Comments are closed.