React: How do you filter search results based on multiple values (regardless of order that the words are typed) Example: I want to be able to search for the title of a document whether I type "phone repair process", "repair phone process", or "process phone repair".
(Currently the search only works if I don't skip words and they must be in order) Note: I'm still learning React and I did try researching for this information on my own with no luck.
Below is my code:
App.js
class App extends Component {
constructor() {
super()
this.state = {
documents: documents,
searchField: '',
}
}
onSearchChange = (event) => {
this.setState({searchField: event.target.value})
}
render() {
const filteredDocuments = this.state.documents.filter(documents => {
return documents.title.toLowerCase().includes(this.state.searchField.toLowerCase())
})
return (
<div>
<h1 className='p-5 text-teal-800 text-xl'>Documentation</h1>
<div className='p-5'>
<Searchbox searchChange={this.onSearchChange} />
</div>
<div>
<Button />
</div>
<div className='m-5 md:m-10 xl:m-20'>
<CardList documents={filteredDocuments} />
</div>
</div>
);
}
}
export default App;
Searchbox.js
import React from "react";
const Searchbox =({searchChange}) => {
return (
<input type="search"
placeholder='Search Document Title...'
className='bg-gray-100 rounded-md px-2 py-1 border border-gray-400 outline-none'
onChange={searchChange}
/>
)
}
export default Searchbox;
CodePudding user response:
it's more of a javascript question than a React. the only part you actually need to edit is
const filteredDocuments = this.state.documents.filter(documents => {
return documents.title.toLowerCase().includes(this.state.searchField.toLowerCase())
try splitting the string into an array of words:
const words = this.state.searchField.toLowerCase().split(" ");
then use the every
method on Boolean. which checks if a condition is met on every element.
const filteredDocuments = this.state.documents.filter(document => {
return words.every(word => document.title.toLowerCase().includes(word))
})
you should note that this method searches the string word by word and does not care if the words are close to each other.
I suggest using specialized libraries like Fuse.js which provide an easy to use, yet powerful search APIs.