Filter functionality is used in nearly every mobile applications which has dynamic content. There are many types of filter functionality available in mobile apps. Today we are going to Flutter Apply Filter On JSON ListView Using PHP MySQL Show Selected Item on next activity screen. We are filtering all the record based on Record ID. So let’s get started š .
What we are doing in this project (Must Read):-
We are creating MySQL database on our online hosting server and then we would create a Table in MySQL database. Now we would enter some records in our MySQL table. We are using PHP scripting language to make server API which converts all the database data into JSON format which we would parse into our flutter ListView. We would Add Item click onPress event on ListView and on onPress event get the selected item ID and send the ID to next activity. In next activity we would again hit a web API created on our server and pass the ID along with it using post method. Now on the server API it will filter the record from MySQL table based on ID and returns us the Complete student record which we would parse into our flutter activity and show inside ListView.
Contents in this project Flutter Apply Filter On JSON ListView Using PHP MySQL Show Selected Item on Next Activity Screen in Android iOS Example Tutorial:
1. Creating MySQL Database with Table:
1. I am using my own sub-domain name flutter-examples.000webhostapp.com connected with web hosting. I am using MySQL database in current tutorial. So open your PhpMyAdmin control panel in your hosting panel because the MySQL database is hosted in PhpMyAdmin. Now create a new database or you can use your own already existed database like i did in below screenshot.
3. There are 4 column present in our Table. id, student_name, student_phone_number and student_class. The id datatype should be set as integer and all the other three columns type is Varchar. We are using Varchar datatype for other columns because it can store both integer and string characters. The length should be 255 and id should be set as Primary Key with Auto Increment. Hit the Save button.
4. After we save the Table. The table structure should look like below screenshot.
5. Our table is yet empty so we have to insert some records manually in our table. Click on the Insert button.
6. After we insert few records our table structure should look like below screenshot.
Here you go guys. Now our database part is done.
2. Creating Web API Using PHP Scripting Language:
1. We are using PHP to create Web API in our tutorial. We will create 3 .php extension files.
2. Creating a PHP file named as DatabaseConfig.php . This file will contain all the major database connection configration. You have to change all the details present in this file as per your Database configuration. After done making changes we have to upload this file into our hosting server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php //Define your host here. $HostName = "localhost"; //Define your MySQL Database Name here. $DatabaseName = "id11189654_flutter_db"; //Define your Database UserName here. $HostUser = "id11189654_root"; //Define your Database Password here. $HostPass = "1234567890"; ?> |
3. Create a PHP file named as Students_List.php . Using this file we will convert all the MySQL database details into JSON Format. We would upload this file on hosting server using file manager. After done uploading the file the complete API URL will be flutter-examples.000webhostapp.com/getStudentInfo.phpĀ . We would use this URL in our flutter project.
Complete Source code for Students_List.php 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 |
<?php include 'DatabaseConfig.php'; // Creating connection $conn = new mysqli($HostName, $HostUser, $HostPass, $DatabaseName); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Creating SQL command to fetch all records from Student_Data Table. $sql = "SELECT * FROM Student_Data"; $result = $conn->query($sql); if ($result->num_rows >0) { while($row[] = $result->fetch_assoc()) { $item = $row; $json = json_encode($item, JSON_NUMERIC_CHECK); } } else { echo "No Data Found."; } echo $json; $conn->close(); ?> |
Screenshot of JSON:
4. Create another PHP file named as GetStudent.php . We would also upload this file on our hosting server. In this file we would first receive the ID sent by flutter application and return only the selected record based on ID filter. After done uploading the file API URL will be
flutter-examples.000webhostapp.com/filter/GetStudent.php .
Complete Source Code for GetStudent.php 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 |
<?php // Importing DatabaseConfig.php file. include 'DatabaseConfig.php'; // Creating MySQL Connection. $con = mysqli_connect($HostName, $HostUser, $HostPass, $DatabaseName); // Getting the received ID in JSON Format into $json variable. $json = file_get_contents('php://input'); // Decoding the received JSON. $obj = json_decode($json,true); // Populate ID from JSON $obj array and store into $ID variable. $ID = $obj['id']; //Fetching the selected record as per ID. $CheckSQL = "SELECT * FROM Student_Data WHERE id='$ID'"; $result = $con->query($CheckSQL); if ($result->num_rows >0) { while($row[] = $result->fetch_assoc()) { $Item = $row; $json = json_encode($Item, JSON_NUMERIC_CHECK); } }else { echo "No Results Found."; } echo $json; $con->close(); ?> |
Now the API creating part is finished.
3. Installing the http.dart package in our Flutter Project:
1. We are using the http.dart package in our flutter project to sent and receive data from server using Get and Post methods. So open your Flutter Project root folder and open pubspec.yaml file in code editor.
2. Open pubspec.yaml file in code editor and find dependencies and Put http: ^0.12.0 in next line like i did in below code.
1 2 3 4 |
dependencies: http: ^0.12.0 flutter: sdk: flutter |
Complete Source code for my pubspec.yaml file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
name: myproject description: A new Flutter project. version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" dependencies: http: ^0.12.0 flutter: sdk: flutter cupertino_icons: ^0.1.2 dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true |
3. After done saving the file we have to open the flutter project root folder in Command Prompt or Terminal and execute flutter pub get command. This command will refresh the complete project and download the newly added package in current project.
4. Start Coding For Flutter App:
1. Import material.dart, dart:convert and http.dart package in your flutter project’s main.dart file.
1 2 3 |
import 'package:flutter/material.dart'; import 'dart:convert'; import 'package:http/http.dart' as http; |
2. Create void main runApp() inbuilt function and here we would call our main MyApp class.
1 |
void main() => runApp(MyApp()); |
3. Creating our main MyApp class extends with State less widget. In this class we would call the MainListView class.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Apply Item Filter on JSON ListView') ), body: MainListView(), ), ); } } |
4. Create a class named as Studentdata. We would use this class to populate items from JSON coming from server one by one. We would make 4 variable named asĀ studentID, studentName, studentPhoneNumber, studentSubject which would hold and populate items from JSON.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class Studentdata { int studentID; String studentName; int studentPhoneNumber; String studentSubject; Studentdata({ this.studentID, this.studentName, this.studentPhoneNumber, this.studentSubject }); factory Studentdata.fromJson(Map<String, dynamic> json) { return Studentdata( studentID: json['id'], studentName: json['student_name'], studentPhoneNumber: json['student_phone_number'], studentSubject: json['student_class'] ); } } |
5. Create a class named as MainListView extends StatefulWidget. In this class we would make the createState() method and pass the child MainListViewState class along with it.
1 2 3 4 5 |
class MainListView extends StatefulWidget { MainListViewState createState() => MainListViewState(); } |
6. Create a class named as MainListViewState extends with State. This is our main First Screen for flutter application. In this class we would parse JSON from server using API URL and display the items into ListView.
1 2 3 4 |
class MainListViewState extends State { } |
7. Creating a String variable named as apiURL in MainListViewState. In this variable we would pass the web API URL.
1 |
final String apiURL = 'https://flutter-examples.000webhostapp.com/getStudentInfo.php'; |
8. Creating a function named as fetchStudents()Ā In MainListViewState class. In this function we would fetch all the records from JSON.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Future<List<Studentdata>> fetchStudents() async { var response = await http.get(apiURL); if (response.statusCode == 200) { final items = json.decode(response.body).cast<Map<String, dynamic>>(); List<Studentdata> studentList = items.map<Studentdata>((json) { return Studentdata.fromJson(json); }).toList(); return studentList; } else { throw Exception('Failed to load data from Server.'); } } |
9. Create a function named as navigateToNextActivity with 2 arguments Context and dataHolder in MainListViewState class. We would call this function on each ListView item click event so when app user clicks on the ListView item it would automatically navigate to next activity and send the Selected Item ID along with it.
1 2 3 4 5 6 7 8 9 |
navigateToNextActivity(BuildContext context, int dataHolder) { Navigator.of(context).push( MaterialPageRoute( builder: (context) => SecondScreenState(dataHolder.toString()) ) ); } |
10. Creating Widget Build Area in MainListViewState class. Now we would make the Future Builder widget and returns the ListView widget. We would also display the CircularProgressIndicator() widget while data is loading from server as Loader.
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 |
Widget build(BuildContext context) { return FutureBuilder<List<Studentdata>>( future: fetchStudents(), builder: (context, snapshot) { if (!snapshot.hasData) return Center( child: CircularProgressIndicator() ); return ListView( children: snapshot.data .map((data) => Column(children: <Widget>[ GestureDetector( onTap: (){navigateToNextActivity(context, data.studentID);}, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.fromLTRB(20, 5, 0, 5), child: Text(data.studentName, style: TextStyle(fontSize: 21), textAlign: TextAlign.left)) ]),), Divider(color: Colors.black), ],)) .toList(), ); }, ); } |
Complete Source code for MainListViewState class:
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 |
class MainListViewState extends State { final String apiURL = 'https://flutter-examples.000webhostapp.com/getStudentInfo.php'; Future<List<Studentdata>> fetchStudents() async { var response = await http.get(apiURL); if (response.statusCode == 200) { final items = json.decode(response.body).cast<Map<String, dynamic>>(); List<Studentdata> studentList = items.map<Studentdata>((json) { return Studentdata.fromJson(json); }).toList(); return studentList; } else { throw Exception('Failed to load data from Server.'); } } navigateToNextActivity(BuildContext context, int dataHolder) { Navigator.of(context).push( MaterialPageRoute( builder: (context) => SecondScreenState(dataHolder.toString()) ) ); } @override Widget build(BuildContext context) { return FutureBuilder<List<Studentdata>>( future: fetchStudents(), builder: (context, snapshot) { if (!snapshot.hasData) return Center( child: CircularProgressIndicator() ); return ListView( children: snapshot.data .map((data) => Column(children: <Widget>[ GestureDetector( onTap: (){navigateToNextActivity(context, data.studentID);}, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.fromLTRB(20, 5, 0, 5), child: Text(data.studentName, style: TextStyle(fontSize: 21), textAlign: TextAlign.left)) ]),), Divider(color: Colors.black), ],)) .toList(), ); }, ); } } |
11. Create a class named as SecondScreenState extends StatefulWidget. In this class we would first receive the sent ID from previous activity and make the createState() method of State and pass the SecondScreen class name along with it.
1 2 3 4 5 6 7 8 |
class SecondScreenState extends StatefulWidget { final String idHolder; SecondScreenState(this.idHolder); @override State<StatefulWidget> createState() { return SecondScreen(this.idHolder); } } |
12. Create a Class named as SecondScreen. This is our next screen where the selected ListView item record will displayed.
1 2 3 4 |
class SecondScreen extends State<SecondScreenState> { } |
13. Create a String variable named as idHolder in SecondScreen class. Now we would make the Constructor of this class and pass the idHolder variable init. Using this method we can store the selected item ID in idHolder variable.
1 2 3 |
final String idHolder ; SecondScreen(this.idHolder); |
14. Create a String variable named as url in SecondScreen class. Here we would pass our filter record API URL.
1 |
var url = 'https://flutter-examples.000webhostapp.com/filter/GetStudent.php'; |
15. Create a function named as fetchStudent() in SecondScreen class. In this function we would First store the ID into data variable with param. Now we would call the API URL and make the POST method and send the ID to server and in return server returns us the complete record based on ID.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Future<List<Studentdata>> fetchStudent() async { var data = {'id': int.parse(idHolder)}; var response = await http.post(url, body: json.encode(data)); if (response.statusCode == 200) { print(response.statusCode); final items = json.decode(response.body).cast<Map<String, dynamic>>(); List<Studentdata> studentList = items.map<Studentdata>((json) { return Studentdata.fromJson(json); }).toList(); return studentList; } else { throw Exception('Failed to load data from Server.'); } } |
16. Create Widget Build area in SecondScreen class. Now we would make the FutureBuilder widget with ListView return. We would also display the CircularProgressIndicator() widget on data loading time.
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 |
Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Showing Selected Item Details'), automaticallyImplyLeading: true, leading: IconButton(icon:Icon(Icons.arrow_back), onPressed:() => Navigator.pop(context, false), ) ), body: FutureBuilder<List<Studentdata>>( future: fetchStudent(), builder: (context, snapshot) { if (!snapshot.hasData) return Center( child: CircularProgressIndicator() ); return ListView( children: snapshot.data .map((data) => Column(children: <Widget>[ GestureDetector( onTap: (){print(data.studentName);}, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.fromLTRB(0, 20, 0, 10), child: Text('ID = ' + data.studentID.toString(), style: TextStyle(fontSize: 21))), Padding( padding: EdgeInsets.fromLTRB(0, 0, 0, 10), child: Text('Name = ' + data.studentName, style: TextStyle(fontSize: 21))), Padding( padding: EdgeInsets.fromLTRB(0, 0, 0, 10), child: Text('Phone Number = ' + data.studentPhoneNumber.toString(), style: TextStyle(fontSize: 21))), Padding( padding: EdgeInsets.fromLTRB(0, 0, 0, 10), child: Text('Class = ' + data.studentSubject, style: TextStyle(fontSize: 21))), ]),) ],)) .toList(), ); }, ) )); } |
17. Complete source code for main.dart 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 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
import 'package:flutter/material.dart'; import 'dart:convert'; import 'package:http/http.dart' as http; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Apply Item Filter on JSON ListView') ), body: MainListView(), ), ); } } class Studentdata { int studentID; String studentName; int studentPhoneNumber; String studentSubject; Studentdata({ this.studentID, this.studentName, this.studentPhoneNumber, this.studentSubject }); factory Studentdata.fromJson(Map<String, dynamic> json) { return Studentdata( studentID: json['id'], studentName: json['student_name'], studentPhoneNumber: json['student_phone_number'], studentSubject: json['student_class'] ); } } class MainListView extends StatefulWidget { MainListViewState createState() => MainListViewState(); } class MainListViewState extends State { final String apiURL = 'https://flutter-examples.000webhostapp.com/getStudentInfo.php'; Future<List<Studentdata>> fetchStudents() async { var response = await http.get(apiURL); if (response.statusCode == 200) { final items = json.decode(response.body).cast<Map<String, dynamic>>(); List<Studentdata> studentList = items.map<Studentdata>((json) { return Studentdata.fromJson(json); }).toList(); return studentList; } else { throw Exception('Failed to load data from Server.'); } } navigateToNextActivity(BuildContext context, int dataHolder) { Navigator.of(context).push( MaterialPageRoute( builder: (context) => SecondScreenState(dataHolder.toString()) ) ); } @override Widget build(BuildContext context) { return FutureBuilder<List<Studentdata>>( future: fetchStudents(), builder: (context, snapshot) { if (!snapshot.hasData) return Center( child: CircularProgressIndicator() ); return ListView( children: snapshot.data .map((data) => Column(children: <Widget>[ GestureDetector( onTap: (){navigateToNextActivity(context, data.studentID);}, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.fromLTRB(20, 5, 0, 5), child: Text(data.studentName, style: TextStyle(fontSize: 21), textAlign: TextAlign.left)) ]),), Divider(color: Colors.black), ],)) .toList(), ); }, ); } } class SecondScreenState extends StatefulWidget { final String idHolder; SecondScreenState(this.idHolder); @override State<StatefulWidget> createState() { return SecondScreen(this.idHolder); } } class SecondScreen extends State<SecondScreenState> { final String idHolder ; SecondScreen(this.idHolder); // API URL var url = 'https://flutter-examples.000webhostapp.com/filter/GetStudent.php'; Future<List<Studentdata>> fetchStudent() async { var data = {'id': int.parse(idHolder)}; var response = await http.post(url, body: json.encode(data)); if (response.statusCode == 200) { print(response.statusCode); final items = json.decode(response.body).cast<Map<String, dynamic>>(); List<Studentdata> studentList = items.map<Studentdata>((json) { return Studentdata.fromJson(json); }).toList(); return studentList; } else { throw Exception('Failed to load data from Server.'); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Showing Selected Item Details'), automaticallyImplyLeading: true, leading: IconButton(icon:Icon(Icons.arrow_back), onPressed:() => Navigator.pop(context, false), ) ), body: FutureBuilder<List<Studentdata>>( future: fetchStudent(), builder: (context, snapshot) { if (!snapshot.hasData) return Center( child: CircularProgressIndicator() ); return ListView( children: snapshot.data .map((data) => Column(children: <Widget>[ GestureDetector( onTap: (){print(data.studentName);}, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.fromLTRB(0, 20, 0, 10), child: Text('ID = ' + data.studentID.toString(), style: TextStyle(fontSize: 21))), Padding( padding: EdgeInsets.fromLTRB(0, 0, 0, 10), child: Text('Name = ' + data.studentName, style: TextStyle(fontSize: 21))), Padding( padding: EdgeInsets.fromLTRB(0, 0, 0, 10), child: Text('Phone Number = ' + data.studentPhoneNumber.toString(), style: TextStyle(fontSize: 21))), Padding( padding: EdgeInsets.fromLTRB(0, 0, 0, 10), child: Text('Class = ' + data.studentSubject, style: TextStyle(fontSize: 21))), ]),) ],)) .toList(), ); }, ) )); } } |
Screenshots:
Thanks for the amazing tutorial . is there anyway to auto update the list when a new record is added in mysql database
Archa you have to run a background JOB to check for update in every few minutes or seconds.
This is cool tutorials
Thanks š .
Please i am getting this error and i dont really know what to do i am actually new in flutter please kindly help me out this the error message “NoSuchMethodError: The method ‘map’ was called on null.
Receiver: null
Tried calling:
map(Closure:
(Studentdata) => Column)
And i have tested my API URL and it is able to display all my records in my database in json format. Thank you in advance
Ii am also getting same error .
thanks mas bro
this is awesome tutorial
thanks this one helped me
Welcome bro š .
hello please i’m getting an error, the list is not loading. its showing the progress bar. please i need help on it
Marc the list is not loading because on the server which I am using in current tutorial is expired. So all the data is lost. You have to manually configured all the data on your server then It will run.
hello please, Iām getting an error, the list is not loading. it’s showing the progress bar. please
Anugrah the list is not loading because the URL is expired on my test hosting sever. If you use it with your URL it will work surely .
May I ask the API URL is get from or need to create by ourselves?
Tam you can use any Api URl or also create as per your requirement, I am using PHP to create APi.
Am getting his error and i dont know what is wrong
The method ‘map’ can’t be unconditionally invoked because the receiver can be ‘null’.
Try making the call conditional (using ‘?.’) or adding a null check to the target (‘!’)
thanks a lot, this code is running well.
please create chat system using php mysql