grooot
grooot

Reputation: 466

Need a Advanced Search Filter - React native

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

  1. Visiting hour.
  2. He knew the visit hour.
  3. visit and hour.

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

Answers (2)

Ravi
Ravi

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

cltsang
cltsang

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

Related Questions