Reputation: 3
I am new to flutter and trying to finish the last remaining part of my app. I am using Firebase realtime database to store out employee data and listing it using a ListView.builder. I am able to show all the information in the list but I want to implement the search bar. I started off and have it in a controller and shows in the terminal but not sure how to implement it properly to filter the data.
I will past my full code but remove the firebase database as it is open right now for testing.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'directory_details_screen.dart';
class Directory extends StatefulWidget {
// const ({Key? key}) : super(key: key);
@override
_DirectoryState createState() => _DirectoryState();
}
class _DirectoryState extends State<Directory> {
TextEditingController _searchController = TextEditingController();
Future getEmpData() async {
var response = await http.get(Uri.parse(
'FIREBASE REMOVED'));
var jsonData = jsonDecode(response.body);
List<Employee> employees = [];
for (var e in jsonData) {
Employee employee = Employee(
e["displayName"],
e["department"],
e["jobTitle"],
e["mobilePhone"],
e["workEmail"],
e["photoUrl"],
e["workPhoneExtension"]);
employees.add(employee);
}
print(employees.length);
return employees;
}
@override
void initState() {
super.initState();
_searchController.addListener(_onSearchChanged);
}
@override
void dispose() {
_searchController.removeListener(_onSearchChanged);
_searchController.dispose();
super.dispose();
}
_onSearchChanged() {
print(_searchController.text);
}
String searchString = "";
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TextField(
onChanged: (value) {
setState(() {
searchString = value;
});
},
controller: _searchController,
decoration: InputDecoration(
labelText: 'Search',
suffixIcon: Icon(Icons.search),
),
),
),
SizedBox(height: 10),
Expanded(
child: FutureBuilder(
future: getEmpData(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, i) {
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
snapshot.data[i].photoUrl
),
),
//leading: Icon(Icons.account_circle),
isThreeLine: true,
title: Text(snapshot.data[i].displayName,
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text("Department: " +
snapshot.data[i].department +
"\n" +
"Title: " +
snapshot.data[i].jobTitle),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => EmployeeDetails(
employee: snapshot.data[i])));
},
),
);
});
},
),
),
],
),
);
}
}
class Employee {
final String displayName,
department,
jobTitle,
mobilePhone,
workEmail,
photoUrl,
workPhoneExtension;
Employee(this.displayName, this.department, this.jobTitle, this.mobilePhone,
this.workEmail, this.photoUrl, this.workPhoneExtension);
}
Upvotes: 0
Views: 1673
Reputation: 1497
You can try something like this:
...
} else {
final result = _search(snapshot.data);
return ListView.builder(
itemCount: result.length,
itemBuilder: (context, i) {
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
result[i].photoUrl
),
),
//leading: Icon(Icons.account_circle),
isThreeLine: true,
title: Text(result[i].displayName,
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text("Department: " +
result[i].department +
"\n" +
"Title: " +
result[i].jobTitle),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
EmployeeDetails(
employee: result[i])));
},
),
);
});
...
and search method like
List<Employee> _search(List<Employee>? employee) {
if(searchString?.isNotEmpty == true) {
//search logic what you want
return employee?.where((element) => element.department.contains(searchString))
.toList() ?? <Employee>[];
}
return employee ?? <Employee>[];
}
Upvotes: 1