'how to search a listview items (generated from an api) using a serach textfield by typing a name/id depending on the list items needed to be found?
i have a list generated from an api, and i want to be able to filter it using a serach bar
for example i only want to display the employe 'salim' when i type his name
here's my code
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:p1/ConfigFile.dart';
import 'package:p1/Details.dart';
import 'package:p1/add_emp.dart';
class EmpData extends StatefulWidget {
final String token;
DateTime now = new DateTime.now();
EmpData({required this.token});
@override
_EmpDataState createState() => _EmpDataState();
}
class _EmpDataState extends State<EmpData> {
int currentPage = 1;
List empList = [];
ConfigFile confObj = new ConfigFile();
//todo: get the data in a list of Strings
Future<List> getEmpData(String token,) async {
String ip = await confObj.readIp();
final response = await http.get(Uri.parse("http://$ip/personnel/api/employees/?page_=$currentPage" ),
headers:{
"Content-Type": "application/json",
"Authorization": "JWT "+token,
});
final String t = response.body;
var jsonData =jsonDecode(t)['data'];
return jsonData;
}
final TextEditingController editingController = TextEditingController();
Future<String> getIp() async{
String ip = await confObj.readIp();
return ip;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Employees List"),
centerTitle: true,
),
body: Column(
children: <Widget>[
//todo: chearch field
TextField(
controller: editingController,
onChanged: changed,
decoration: InputDecoration(
labelText: "Search",
hintText: "Search",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(25.0)))),
),
FutureBuilder<List>(
future: getEmpData(widget.token),
builder: (ctx,ss){
if(ss.hasData){
empList = ss.data!;
return Expanded(child: ListView.builder(
itemCount: empList==null?0:empList.length,
itemBuilder: (ctx,i){
return ListTile(
onTap: (){
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context)=>Details(
token: widget.token,
emp: empList[i]['emp_code'],
first_name: empList[i]['first_name'],
last_name: empList[i]['last_name'],
photo: empList[i]['photo'],
)
));
},
leading: SizedBox(
//todo: get the emp photo from the database using the conf ip adress
child: FutureBuilder(
future: getIp(),
builder: (ctx,ss){
if(ss.hasData){
return SizedBox(child: Image.network("http://${ss.data}/${empList[i]['photo']}", width: 50,height: 50,));
}else{
return Center(child: CircularProgressIndicator());
}
},
),
),
subtitle: Text("id: #${empList[i]['emp_code']}"),
title: Text("${empList[i]['first_name']} ${empList[i]['last_name']}"),
);
}
));
}else{
return Center(child: CircularProgressIndicator());
}
}
)
],
)
);
}
this is where i was going to put the search function which was called by TextField onchanged
//todo: this is searching function
void changed(String Query) {
}
}
this is how the page looks like homePage
Solution 1:[1]
A simple approach would be using a ValueNotifier with a ValueListenableBuilder if you only want to listen to a single value being changed (the search bar field) and you want to have the List render only the found values based on your match. Check out this Gist that I did based on some of your code.
Pretty much we load all data upfront, and using your changed event handler attached to the textfield's onChanged, we capture every keystroke and filter out the list based on only the matched first_name (you could add the last name or any other criteria). Then we trigger the ValueNotifier empName to trigger the updated list with the filtered results.
This is the simplest approach you could go for. Other approaches would be using a simple state management solution like a Provider and using ChangeNotifiers as well as Consumer widgets, which follow pretty much the same idea as above, but more robust and durable.
It should look like the GIF below once you put it all together:
Hope that works out for your purposes.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Roman Jaquez |

