I'm trying to implement search function for my paginated data table in flutter. I'm fetching the data from API and created user Model. after that in my page I used StreamBuilder and passed in the source. but I have no idea how to make my table searchable. and I've been searching for a tutorial or an article on this topic. but found none that can work for me.
Here is my code:
StreamBuilder<List<User>>(
stream: fetchUsersFromModel().asStream(),
builder: (context, snapshot) {
if (snapshot.hasData) {
// var data = snapshot.data!;
// switch(""){
// case "searching":
// var filteredList = snapshot.data!.where((element) => element.data!)
// }
return PaginatedDataTable(
sortColumnIndex: sortColumnIndex,
sortAscending: isAscending,
columns: const [
DataColumn(
label: Text("Id"),
),
DataColumn(label: Text("Name")),
DataColumn(
label: Text("Username"),
),
DataColumn(label: Text("Email")),
DataColumn(label: Text("Roles")),
DataColumn(label: Text("Actions")),
],
header: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
"Manage Users",
style: TextStyle(
fontSize: width * 0.04,
fontWeight: FontWeight.normal),
),
MaterialButton(
onPressed: () {
showMaterialModalBottomSheet(
context: context,
builder: (context) =>
SizedBox(
height: height * 0.9,
child:
BottomSheetWidget(),
),
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.only(
topLeft: Radius
.circular(15),
topRight: Radius
.circular(
15))));
},
color: const Color.fromRGBO(
30, 119, 66, 1),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10)),
child: Text(
"Add User",
style: TextStyle(
color: Colors.white,
fontSize: width * 0.03),
),
)
],
),
source: dataSource(
snapshot.data! as List<User>));
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return const Center(
child: CircularProgressIndicator());
});
passed data source as
DataTableSource dataSource(List<User> userList) =>
MyTable(datasList: userList, context: context);
datatable part
class MyTable extends DataTableSource {
MyTable({required this.datasList, required this.context});
final List<User> datasList;
BuildContext context;
final UserController userController = Get.put(UserController());
Widget Button(String title, Color color, String id, bool delete, String? name,
String? email, String? username, String? role) {
return MaterialButton(
onPressed: () async {
final height = MediaQuery.of(context).size.height;
delete
? await deleteUser(id)
: await showMaterialModalBottomSheet(
context: context,
builder: (context) => SizedBox(
height: height * 0.9,
child: BottomSheetEditWidget(
name: name,
email: email,
username: username,
role: role,
id: id,
),
),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15))));
userController.setuserPress(false);
},
child: Text(
title,
style: const TextStyle(color: Colors.white),
),
color: color,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
);
}
void sort<T>(Comparable<T> Function(User d) getField, bool ascending) {
datasList.sort((User a, User b) {
if (!ascending) {
final User c = a;
a = b;
b = c;
}
final Comparable<T> aValue = getField(a);
final Comparable<T> bValue = getField(b);
return Comparable.compare(aValue, bValue);
});
notifyListeners();
}
@override
DataRow? getRow(int index) {
return DataRow.byIndex(index: index, cells: [
DataCell(Text("${index + 1}".toString())),
DataCell(
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 100),
child: Text(
datasList[index].name.toString(),
overflow: TextOverflow.ellipsis,
),
),
),
DataCell(ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 100),
child: Text(
datasList[index].username.toString(),
overflow: TextOverflow.ellipsis,
))),
DataCell(ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 100),
child: Text(
datasList[index].email.toString(),
overflow: TextOverflow.ellipsis,
))),
DataCell(ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 100),
child: Text(
datasList[index].roles![0].name.toString(),
overflow: TextOverflow.ellipsis,
))),
DataCell(Row(
children: [
Button(
"Edit",
Colors.lightBlue,
datasList[index].id.toString(),
false,
datasList[index].name,
datasList[index].email,
datasList[index].username,
datasList[index].roles![0].name),
const SizedBox(
width: 5,
),
Button(
"Delete",
Colors.red,
datasList[index].id.toString(),
true,
datasList[index].name,
datasList[index].email,
datasList[index].username,
datasList[index].roles![0].name),
],
)),
]);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => datasList.length;
@override
int get selectedRowCount => 0;
}
How can I implement this? any example or an article regarding this topic.