Billy Koswara
Billy Koswara

Reputation: 497

How to make search filter with list item in react-native

I have been wanting to make search filter in this listitem but i kind of get confused, if you are experienced with this, please take a look at my code.

import React, { Component } from 'react'; 
import {   Text,   View,   ScrollView,   TextInput, } from 'react-native'; 
import { List, ListItem } from 'react-native-elements'; 
import { users } from '../config/data';

class Feed extends Component {   constructor(props){
    super(props);
    this.state = {
      user:'',
    }   }   onLearnMore = (user) => {
    this.props.navigation.navigate('Details', { ...user });   };

  filterSearch(text){
    const newData = users.filter((item)=>{
      const itemData = item.name.first.toUpperCase()
      const textData = text.toUpperCase()
      return itemData.indexOf(textData)>-1
    })
    this.setState({
      text:text
    })   }

  render() {
    return (
      <ScrollView>
        <TextInput
            onChangeText={(text) => this.filterSearch(text)}
            value={this.state.text}
          />
        <List>
          {users.map((user) => (
            <ListItem
              key={user.login.username}
              roundAvatar
              avatar={{ uri: user.picture.thumbnail }}
              title={`${user.name.first.toUpperCase()} ${user.name.last.toUpperCase()}`}
              subtitle={user.email}
              onPress={() => this.onLearnMore(user)}
            />
          ))}
        </List>
      </ScrollView>
    );   } }

export default Feed;

i have been surfing the internet but i found that most of it discuss about listview instead of list item from react-native-elements, help me!

Upvotes: 4

Views: 10339

Answers (2)

Billy Koswara
Billy Koswara

Reputation: 497

why do i keep answering my own answer i am so sorry to this forum that i waste some space but i thought posting this answer will help some of you especially a beginner like me

    import React, {Component} from 'react';
import { StyleSheet, Text, View, ListView, TouchableHighlight, TextInput} from 'react-native';
import { List, ListItem } from 'react-native-elements';
import { users } from '../config/data';

export default class Feed extends Component {
  constructor(props){
    super(props);
    const ds = new ListView.DataSource({rowHasChanged: (r1,r2) => r1 !== r2})
    this.state = {
      dataSource: ds.cloneWithRows(users),
      text:'',
    }
  }
  onLearnMore = (rowData) => {
    this.props.navigation.navigate('Details', { ...rowData });
  };
  renderRow(rowData){
    return(
        <ListItem
          key={rowData.login.username}
          roundAvatar
          avatar={{ uri: rowData.picture.thumbnail }}
          title={`${rowData.name.first.toUpperCase()} ${rowData.name.last.toUpperCase()}`}
          subtitle={rowData.email}
          onPress={() => this.onLearnMore(rowData)}
        />
    );
  }
  filterSearch(text){
      const newData = users.filter(function(item){
          const itemData = item.email.toUpperCase()
          const textData = text.toUpperCase()
          return itemData.indexOf(textData) > -1
      })
      this.setState({
          dataSource: this.state.dataSource.cloneWithRows(newData),
          text: text
      })
  }

  render() {
    return (
      <View style={{flex:1}}>
        <TextInput
          onChangeText={(text) => this.filterSearch(text)}
          value={this.state.text}
          />
        <ListView
          enableEmptySections={true}
          style={{marginHorizontal:10}}
          renderRow={this.renderRow.bind(this)}
          dataSource={this.state.dataSource}
        />
      </View>
    );
  }
}

just compare the question's code and the answer code and lastly i get the answer by reading the link below

https://react-native-training.github.io/react-native-elements/API/lists/

feel free to check it out again

Upvotes: 3

bennygenel
bennygenel

Reputation: 24660

You were almost correct. You successfully filter your users but then render the same not filtered users in your list. To change this easily you can use component state.

Example

import React, { Component } from 'react'; 
import {   Text,   View,   ScrollView,   TextInput, } from 'react-native'; 
import { List, ListItem } from 'react-native-elements'; 
import { users } from '../config/data';

class Feed extends Component {   
  constructor(props){
    super(props);
      this.state = {
        user:'',
        users: users // we are setting the initial state with the data you import
      }
  }   

  onLearnMore = (user) => {
    this.props.navigation.navigate('Details', { ...user });
  };

  filterSearch(text){
    const newData = users.filter((item)=>{
      const itemData = item.name.first.toUpperCase()
      const textData = text.toUpperCase()
      return itemData.indexOf(textData)>-1
    });
    this.setState({
      text:text,
      users: newData // after filter we are setting users to new array
    });
  }

  render() {
    // rather than mapping users loaded from data file we are using state value
    return (
      <ScrollView>
        <TextInput
            onChangeText={(text) => this.filterSearch(text)}
            value={this.state.text}
          />
        <List>
          {this.state.users.map((user) => (
            <ListItem
              key={user.login.username}
              roundAvatar
              avatar={{ uri: user.picture.thumbnail }}
              title={`${user.name.first.toUpperCase()} ${user.name.last.toUpperCase()}`}
              subtitle={user.email}
              onPress={() => this.onLearnMore(user)}
            />
          ))}
        </List>
      </ScrollView>
    );   } }

export default Feed;

Upvotes: 3

Related Questions