Reputation: 466
I have a SearchBar and a simple FlatList. My logic for search filter is working fine but that is fine for simple search.
Example:
If my FlatList has three items
In my SearchBar if i search "visit h" it will render only item 2 -> 2. He knew the visit hour.
I want it to render all 3 items when i search "visit h" My Search filter should look for every item that includes "visit" and "h". It should also include "visit" in "visiting"
How can i capture this type of filter? Is there any js Library that can be used? Any efficient way to execute this search filter?
My current code is below:
export default class HomeComponent extends Component {
constructor(props) {
super(props)
this.state = {
isLoading: true,
notifications: [],
query: '',
temp: []
}
};
componentDidMount() {
fetch('https://140xya6a67.execute-api.ap-southeast-1.amazonaws.com/dev/', {
method: 'GET',
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
notifications: responseJson,
notificationRead: false,
temp: responseJson,
})
})
};
goToDetails() {
return this.props.navigation.navigate(Details);
}
renderItem({item}) {
return <NotificationItem item={item}
onPress={() => {this.goToDetails()}}/>
}
handleSearch(text) {
const newData = _.filter(this.state.temp, (item) => {
const itemData = item.Desc ? item.Desc.toUpperCase() : ''.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({
notifications: newData,
query: text,
});
}
renderContent() {
let {notifications} = this.state;
return (
<View>
<SearchBar placeholder='type here...' lightTheme round value={this.state.query}
onChangeText={(text) => {this.handleSearch(text)}}/>
<FlatList
keyExtractor={(item, id) => item.id}
data={notifications}
renderItem={this.renderItem.bind(this)}
/>
</View>
);
}
render() {
let {fill, container} = styles;
return (
<View style={[fill, container]}>
{this.renderContent()}
</View>
);
}
}
Upvotes: 1
Views: 2367
Reputation: 141
You can write simple filter of your own, like below (not tested):
handleSearch(text) {
if (!text || text.length === 0) {
this.setState({
notifications: this.state.temp,
query: text,
});
return;
}
const newData = _.filter(this.state.temp, item => {
const itemData = item.Desc ? item.Desc.toUpperCase() : ''.toUpperCase();
const textParts = text.toUpperCase().split(' ');
let shouldInclude = true;
for (let i = 0; i < textParts.length; i++) {
const part = textParts[i];
shouldInclude = shouldInclude && (itemData.indexOf(part) > -1);
if (!shouldInclude) {
return false;
}
}
return true;
});
this.setState({
notifications: newData,
query: text,
});
}
Upvotes: 1
Reputation: 1829
You are describing full-text search, or even fuzzy search.
If you have a small list of static data, you can do it purely on frontend during run time with library like fuse.js.
For dynamic data, you need a backend to tokenize and prepare the data beforehand. Frontend then just send what the user has typed, and get feed the search result from backend.
You can build that yourself if you use a modern RDBMS like PostgreSQL or MSSQL. Or use services or tools more purposefully built for this problem, like algolia or Elasticsearch.
Upvotes: 1