Search Bar Filter is a real time filtering technique used in almost all Android and iOS applications to filter the JSON data in FlatList and ListView by typing text in TextInput component. It will filter the ListView according to user typed value and set the newly filter result again in ListView. So in this tutorial we would going to make a react native app with Real TimeĀ Search Bar Filter on JSON Parsing ListView. So let’s get started š .
Contents in this projectĀ Add Search Bar Filter on JSON Listview Android iOS Tutorial :
1. Read my previous tutorial about JSON Parsing FlatList. Because we are using same JSON in current tutorial as i was used in this tutorial. So reading this tutorial is must to understand, how we are converting the MySQL data to JSON.
JSON Screenshot:
2. ImportĀ Text, StyleSheet, View, ListView, TextInput, ActivityIndicator and Alert component in your project.
1 2 3 |
import React, { Component } from 'react'; import { Text, StyleSheet, View, ListView, TextInput, ActivityIndicator, Alert } from 'react-native'; |
3. Create constructor() in your class. Now make 2 State variables named asĀ isLoading and text. isLoading state is used to show and hide theĀ ActivityIndicator and text state is used to set text insideĀ TextInput. Now we would make a Global Array named asĀ arrayholder=[] .We would use this Array Array to Filter the ListView.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
constructor(props) { super(props); this.state = { isLoading: true, text: '', } this.arrayholder = [] ; } |
4. Create Fetch() API inĀ componentDidMount() method. The Fetch() Web API is used in this project to Parse JSON from given HTTP URL. We would also store the Parsed JSON insideĀ arrayholder Array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
componentDidMount() { return fetch('https://reactnativecode.000webhostapp.com/FruitsList.php') .then((response) => response.json()) .then((responseJson) => { let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.setState({ isLoading: false, dataSource: ds.cloneWithRows(responseJson), }, function() { // In this block you can do something with new state. this.arrayholder = responseJson ; }); }) .catch((error) => { console.error(error); }); } |
5. Create function named as GetListViewItem() for retrieve selected ListView item and show inside Alert message.
1 2 3 4 5 |
GetListViewItem (fruit_name) { Alert.alert(fruit_name); } |
6. CreateĀ SearchFilterFunction() and pass Text inside it as argument. Now we would filter the JSON array according to given value pass as argument. After filtering data we would set the newly data inĀ dataSource state.
1 2 3 4 5 6 7 8 9 10 11 12 |
SearchFilterFunction(text){ const newData = this.arrayholder.filter(function(item){ const itemData = item.fruit_name.toUpperCase() const textData = text.toUpperCase() return itemData.indexOf(textData) > -1 }) this.setState({ dataSource: this.state.dataSource.cloneWithRows(newData), text: text }) } |
7. CreateĀ ListViewItemSeparator() function to show a horizontal line between each ListView element .
1 2 3 4 5 6 7 8 9 10 11 |
ListViewItemSeparator = () => { return ( <View style={{ height: .5, width: "100%", backgroundColor: "#000", }} /> ); } |
8. Add IF condition in render’s block, which is used to Show and Hide theĀ ActivityIndicator component after parsing the JSON.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
render() { if (this.state.isLoading) { return ( <View style={{flex: 1, paddingTop: 20}}> <ActivityIndicator /> </View> ); } return ( ); } |
9. Now create a Root View in render’s return block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
render() { if (this.state.isLoading) { return ( <View style={{flex: 1, paddingTop: 20}}> <ActivityIndicator /> </View> ); } return ( <View style={styles.MainContainer}> </View> ); } |
10. Create a TextInputĀ and ListView component in root view. This is used to get search input from user.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
render() { if (this.state.isLoading) { return ( <View style={{flex: 1, paddingTop: 20}}> <ActivityIndicator /> </View> ); } return ( <View style={styles.MainContainer}> <TextInput style={styles.TextInputStyleClass} onChangeText={(text) => this.SearchFilterFunction(text)} value={this.state.text} underlineColorAndroid='transparent' placeholder="Search Here" /> <ListView dataSource={this.state.dataSource} renderSeparator= {this.ListViewItemSeparator} renderRow={(rowData) => <Text style={styles.rowViewContainer} onPress={this.GetListViewItem.bind(this, rowData.fruit_name)} >{rowData.fruit_name}</Text>} enableEmptySections={true} style={{marginTop: 10}} /> </View> ); } |
11. Create Style classes :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
const styles = StyleSheet.create({ MainContainer :{ justifyContent: 'center', flex:1, margin: 7, }, rowViewContainer: { fontSize: 17, padding: 10 }, TextInputStyleClass:{ textAlign: 'center', height: 40, borderWidth: 1, borderColor: '#009688', borderRadius: 7 , backgroundColor : "#FFFFFF" } }); |
12. Complete source code forĀ App.jsĀ File :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
import React, { Component } from 'react'; import { Text, StyleSheet, View, ListView, TextInput, ActivityIndicator, Alert } from 'react-native'; export default class MyProject extends Component { constructor(props) { super(props); this.state = { isLoading: true, text: '', } this.arrayholder = [] ; } componentDidMount() { return fetch('https://reactnativecode.000webhostapp.com/FruitsList.php') .then((response) => response.json()) .then((responseJson) => { let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.setState({ isLoading: false, dataSource: ds.cloneWithRows(responseJson), }, function() { // In this block you can do something with new state. this.arrayholder = responseJson ; }); }) .catch((error) => { console.error(error); }); } GetListViewItem (fruit_name) { Alert.alert(fruit_name); } SearchFilterFunction(text){ const newData = this.arrayholder.filter(function(item){ const itemData = item.fruit_name.toUpperCase() const textData = text.toUpperCase() return itemData.indexOf(textData) > -1 }) this.setState({ dataSource: this.state.dataSource.cloneWithRows(newData), text: text }) } ListViewItemSeparator = () => { return ( <View style={{ height: .5, width: "100%", backgroundColor: "#000", }} /> ); } render() { if (this.state.isLoading) { return ( <View style={{flex: 1, paddingTop: 20}}> <ActivityIndicator /> </View> ); } return ( <View style={styles.MainContainer}> <TextInput style={styles.TextInputStyleClass} onChangeText={(text) => this.SearchFilterFunction(text)} value={this.state.text} underlineColorAndroid='transparent' placeholder="Search Here" /> <ListView dataSource={this.state.dataSource} renderSeparator= {this.ListViewItemSeparator} renderRow={(rowData) => <Text style={styles.rowViewContainer} onPress={this.GetListViewItem.bind(this, rowData.fruit_name)} >{rowData.fruit_name}</Text>} enableEmptySections={true} style={{marginTop: 10}} /> </View> ); } } const styles = StyleSheet.create({ MainContainer :{ justifyContent: 'center', flex:1, margin: 7, }, rowViewContainer: { fontSize: 17, padding: 10 }, TextInputStyleClass:{ textAlign: 'center', height: 40, borderWidth: 1, borderColor: '#009688', borderRadius: 7 , backgroundColor : "#FFFFFF" } }); |
Screenshot in Android device :
Screenshot in iOS Application :
Hi there!
Thanks for your tutorial!
here’s a question,
the search bar within my application would need to search for different fields e.g. person’s name; person’s address
is it possible to return more than one field in searchfilterfunction ?
Yes Jonathan you can do this and i will soon publish a new tutorial regarding to your query.
Thank you very much!!
Your tutorials really helped me in my work !
Welcome Jonathan š .
does it work in FlatList ?
I have tried it, but error
Yes Andy it will work in FlatList too.
How do i make a search bar like google or Facebook app which is in centre of the app screen but as we click or typing to search it gets at top position of the app and background is also visible.
Rohit you need to move the search bar on selection at the top of the screen.
Hi there!
hereās a question,
the search bar within my application would need to search for different fields e.g. personās name; personās address
is it possible to return more than one field in searchfilterfunction ?
Munish you need to search between multiple field, i will soon publish tutorial on this topic š .
Thanks sir for your reply,
please let me know it ASAP…
Sure Munish :).
Hi admin,you have done a wonderful job!Thanks.What to know if i can upload file from mobile(react native) to web server (mysql).if yes,how?
Aruna i have not tried yet uploading code but soon i will upload new tutorial regarding to uploading content online to server š .
Hi, I have followed your tutorial step by step, but it constantly gives me an error that I can not identify. I am using my own API in laravel that returns the data in json format.
My apk uploads all the data to me at the beginning. The problem is that when I write in the TextInput it returns “undefined is not a function (evaluating ‘this.arrayholder.filter”). Thank you for your attention.
Gilbe just create SearchFilterFunction() inside your class and check that you have created arrayholder=[] array in constructor.
I solved the problem. My json return the array on a variable.
{“my_fruits”:[{“id”:1,”fruit_name”:”Apple”},{“id”:2,”fruit_name”:”Apricot”},
{“id”:3,”fruit_name”:”Avocado”},{“id”:4,”fruit_name”:”Banana”}]}
I add the name on the line:
this.arrayholder=responseJson.my_fruits.
Thanks
Welcome Gilbe š .
good tutorial man, thank you
Welcome Jacob š .
How to show the list only after something has been typed in TextInput.
Abhishek then all you have to do is set the list empty at the first time and on start typing update the data source value.
Hi, you could share the code because I wanted to do it and it did not come out. š
Valentin yes i can share the code, can i send the code on your mail address.
Hello sir, when I am trying to apply the same filtering with flatlist then it is working properly but when i clear back the last character in the search inputtext the app will crash….Why so??
Sangeeta you need to put a condition and check it the search box is empty then set the dataSource value is null or empty .
Hello, firstly thank you for tutorial. I have a question, when I run code, keyboard won’t open, can you please help me?
Regards
Sezer sometimes keyboard will not respond correctly into Simulators, trying to install and run the app in real device.
Hi bro
when I use it with FlatList instead ListView I take an Error:”undefined is not a function (evaluating this.state.datasource.cloneWith….).
Reza share your code with us.
Hi Bro,
Thanks a lot for your tutorial. It helps me a lot.
I want one more favor from you if you could please help me out.
I have an array of dictionaries and each dictionary has a key with one more array and this array has a key with one more array within.
So for example:
mainArray = [
{
key1: [{
key2: [{
key3: value
}]
}]
}]
How could I perform search for this kind of nested arrays in a single function? My need is, if I type in any character then it should be searched in all arrays i.e. mainArray, key1 subArray and key2 subArray simultaneously.
I know it’s very tough task to complete but could you please help me to get it work?
Thanks a lot in advance.
Kirtish sorry but i really have not tried yet.
Hi Bro,
Could you please give a try and help me out to make it possible.
Thanks in advance.
Sure kirtish i will soon reply your comment with an update on this topic.
Hi bro
I am trying to apply the same filtering with ListView and it is working properly but when i clear characters by pressing back arrow button of keyboard in the search input text the app is crashing with an Error:āundefined is not an object (evaluating ‘this.state.dataSource.cloneWithRows’)”.
I’m setting my array in constructor of my class like below:
constructor(props)
{
super(props);
this.state = {
width: Dimensions.get(‘window’).width,
height: Dimensions.get(‘window’).height,
isLoading: true,
searchText: ”,
}
// global variables
this.iDeviceWidth = Dimensions.get(‘window’).width
this.myData = [];
}
yeahhh, worked for me.
But couldnot type in simulator ( I-Phone -8), for that goto Hardware> Keyboard>connect hardware keyboard and works fluently fine. Thanks š
Welcome Aastha š .
Thank you so much for this .. you have no idea how much i needed it. i have one question please, what if i want to fetch the json file from the app directory instead of the web.. the same file you scereenshoted .. how can i fetch it locally?
fetch(‘./jsonfile.php’) doesnt work
it creates an error.
(attempt to invoke string.equals(object) on a null ref)
Here locally means local database ? like local host , please explain .
Thanks a lot Jonathan you have saved my time.
No not at all he means to say .json file saved in local system
can you please tell how to perform this same functionality on flatlist instead of listview..I think listView is deprecated now….
Samar i will post a tutorial soon with this search functionality with FlatList.
is it possible to return more than one field in searchfilterfunction ?
Yes yogesh it is possible, You want to filter data from multiple fields.
Could you give the example using Flatlist instead of ListView as because ListView is now deprecated.
And also provide the example with Yogesh criteria. May be It is very common for you, but as a fresher we need the help of master like you.
Yes Chinmay i will post this same tutorial using FlatList within a week.
Hi. Thank you for the code. But I have some error like “ListView is deprecated and will be removed in a future release” please help me. Thank you!
i want to insert listview or flatlist data in mysql …
please anybody…