forked from yaso_meth/mih-project
1) Update search field to cater for ontap of icon and required and editable parameters.
2) remove Unnesasay signed in user from widget, add menu height. 3) add medicine object to cater for results of med api call. 4) update search input to cater for new parameters. 5) create prescriotion popUp widget. 6) Create medicine search pop Up widget
This commit is contained in:
47
Frontend/patient_manager/lib/components/buildMedList.dart
Normal file
47
Frontend/patient_manager/lib/components/buildMedList.dart
Normal file
@@ -0,0 +1,47 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/objects/medicine.dart';
|
||||
|
||||
class BuildMedicinesList extends StatefulWidget {
|
||||
final TextEditingController contoller;
|
||||
final List<Medicine> medicines;
|
||||
//final searchString;
|
||||
|
||||
const BuildMedicinesList({
|
||||
super.key,
|
||||
required this.contoller,
|
||||
required this.medicines,
|
||||
//required this.searchString,
|
||||
});
|
||||
|
||||
@override
|
||||
State<BuildMedicinesList> createState() => _BuildMedicinesListState();
|
||||
}
|
||||
|
||||
int indexOn = 0;
|
||||
|
||||
class _BuildMedicinesListState extends State<BuildMedicinesList> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView.separated(
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return const Divider();
|
||||
},
|
||||
itemCount: widget.medicines.length,
|
||||
itemBuilder: (context, index) {
|
||||
//final patient = widget.patients[index].id_no.contains(widget.searchString);
|
||||
return ListTile(
|
||||
title: Text(widget.medicines[index].name),
|
||||
subtitle: Text(
|
||||
"${widget.medicines[index].unit} - ${widget.medicines[index].form}"),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
widget.contoller.text = widget.medicines[index].name;
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
},
|
||||
trailing: const Icon(Icons.arrow_forward),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
152
Frontend/patient_manager/lib/components/medicineSearch.dart
Normal file
152
Frontend/patient_manager/lib/components/medicineSearch.dart
Normal file
@@ -0,0 +1,152 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/components/buildMedList.dart';
|
||||
import 'package:patient_manager/components/myErrorMessage.dart';
|
||||
import 'package:patient_manager/objects/medicine.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
class MedicineSearch extends StatefulWidget {
|
||||
final TextEditingController searchVlaue;
|
||||
const MedicineSearch({
|
||||
super.key,
|
||||
required this.searchVlaue,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MedicineSearch> createState() => _MedicineSearchState();
|
||||
}
|
||||
|
||||
class _MedicineSearchState extends State<MedicineSearch> {
|
||||
final String endpointMeds = "http://localhost:80/users/medicine/";
|
||||
|
||||
//TextEditingController searchController = TextEditingController();
|
||||
|
||||
late Future<List<Medicine>> futueMeds;
|
||||
//String searchString = "";
|
||||
|
||||
Future<List<Medicine>> getMedList(String endpoint) async {
|
||||
final response = await http.get(Uri.parse(endpoint));
|
||||
if (response.statusCode == 200) {
|
||||
Iterable l = jsonDecode(response.body);
|
||||
List<Medicine> medicines =
|
||||
List<Medicine>.from(l.map((model) => Medicine.fromJson(model)));
|
||||
// List<Medicine> meds = [];
|
||||
// medicines.forEach((element) => meds.add(element.name));
|
||||
return medicines;
|
||||
} else {
|
||||
internetConnectionPopUp();
|
||||
throw Exception('failed to load medicine');
|
||||
}
|
||||
}
|
||||
|
||||
void internetConnectionPopUp() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MyErrorMessage(errorType: "Internet Connection");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
futueMeds = getMedList(endpointMeds + widget.searchVlaue.text);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Dialog(
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
width: 700.0,
|
||||
//height: 475.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(25.0),
|
||||
border: Border.all(color: Colors.blueAccent, width: 5.0),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
"Select Medicine",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.blueAccent,
|
||||
fontSize: 35.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25.0),
|
||||
// MySearchField(
|
||||
// controller: searchController,
|
||||
// hintText: "Medicine",
|
||||
// onChanged: (value) {
|
||||
// setState(() {
|
||||
// searchString = value;
|
||||
// });
|
||||
// },
|
||||
// required: true,
|
||||
// editable: true,
|
||||
// onTap: () {},
|
||||
// ),
|
||||
FutureBuilder(
|
||||
future: futueMeds,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const SizedBox(
|
||||
height: 400,
|
||||
child: const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
} else if (snapshot.hasData) {
|
||||
final medsList = snapshot.data!;
|
||||
return SizedBox(
|
||||
height: 400,
|
||||
child: BuildMedicinesList(
|
||||
contoller: widget.searchVlaue,
|
||||
medicines: medsList,
|
||||
//searchString: searchString,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return const SizedBox(
|
||||
height: 400,
|
||||
child: const Center(
|
||||
child: Text("Error Loading Medicines"),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 5,
|
||||
right: 5,
|
||||
width: 50,
|
||||
height: 50,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.red,
|
||||
size: 35,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/objects/appUser.dart';
|
||||
|
||||
class MyDropdownField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final AppUser signedInUser;
|
||||
final String hintText;
|
||||
final bool required;
|
||||
final List<String> dropdownOptions;
|
||||
@@ -13,7 +11,6 @@ class MyDropdownField extends StatefulWidget {
|
||||
const MyDropdownField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.signedInUser,
|
||||
required this.hintText,
|
||||
required this.dropdownOptions,
|
||||
required this.required,
|
||||
@@ -92,6 +89,7 @@ class _MyDropdownFieldState extends State<MyDropdownField> {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25.0),
|
||||
child: DropdownMenu(
|
||||
menuHeight: 300,
|
||||
controller: widget.controller,
|
||||
expandedInsets: EdgeInsets.zero,
|
||||
label: setRequiredText(),
|
||||
|
||||
@@ -1,36 +1,113 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MySearchField extends StatelessWidget {
|
||||
final controller;
|
||||
class MySearchField extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String hintText;
|
||||
final bool required;
|
||||
final bool editable;
|
||||
final void Function(String)? onChanged;
|
||||
final void Function() onTap;
|
||||
|
||||
const MySearchField({
|
||||
super.key,
|
||||
required this.controller,
|
||||
required this.hintText,
|
||||
required this.onChanged,
|
||||
required this.required,
|
||||
required this.editable,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MySearchField> createState() => _MySearchFieldState();
|
||||
}
|
||||
|
||||
class _MySearchFieldState extends State<MySearchField> {
|
||||
bool startup = true;
|
||||
FocusNode _focus = FocusNode();
|
||||
|
||||
bool makeEditable() {
|
||||
if (widget.editable) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
String? get _errorText {
|
||||
final text = widget.controller.text;
|
||||
if (startup) {
|
||||
return null;
|
||||
}
|
||||
if (!widget.required) {
|
||||
return null;
|
||||
}
|
||||
if (text.isEmpty) {
|
||||
return "${widget.hintText} is required";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void _onFocusChange() {
|
||||
setState(() {
|
||||
startup = false;
|
||||
});
|
||||
}
|
||||
|
||||
Widget setRequiredText() {
|
||||
if (widget.required) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
"*",
|
||||
style: TextStyle(color: Colors.red),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8.0,
|
||||
),
|
||||
Text(widget.hintText,
|
||||
style: const TextStyle(color: Colors.blueAccent)),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Text(widget.hintText,
|
||||
style: const TextStyle(color: Colors.blueAccent));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focus.addListener(_onFocusChange);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25.0),
|
||||
child: TextField(
|
||||
onChanged: onChanged,
|
||||
controller: controller,
|
||||
onChanged: widget.onChanged,
|
||||
controller: widget.controller,
|
||||
readOnly: makeEditable(),
|
||||
focusNode: _focus,
|
||||
obscureText: false,
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
prefixIcon: const Icon(
|
||||
Icons.search,
|
||||
color: Colors.blueAccent,
|
||||
prefixIcon: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.search,
|
||||
color: Colors.blueAccent,
|
||||
),
|
||||
onPressed: () {
|
||||
if (widget.controller.text != "") {
|
||||
widget.onTap();
|
||||
}
|
||||
},
|
||||
),
|
||||
filled: true,
|
||||
label: Text(hintText),
|
||||
labelStyle: const TextStyle(color: Colors.blueAccent),
|
||||
//hintText: hintText,
|
||||
//hintStyle: TextStyle(color: Colors.blueGrey[400]),
|
||||
label: setRequiredText(),
|
||||
errorText: _errorText,
|
||||
enabledBorder: const OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.blueAccent,
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:patient_manager/components/myErrorMessage.dart';
|
||||
import 'package:patient_manager/components/mySuccessMessage.dart';
|
||||
import 'package:patient_manager/components/myTextInput.dart';
|
||||
import 'package:patient_manager/components/mybutton.dart';
|
||||
import 'package:patient_manager/components/prescipInput.dart';
|
||||
import 'package:patient_manager/main.dart';
|
||||
import 'package:patient_manager/objects/appUser.dart';
|
||||
import 'package:patient_manager/objects/files.dart';
|
||||
@@ -41,6 +42,13 @@ class _PatientFilesState extends State<PatientFiles> {
|
||||
final endDateTextController = TextEditingController();
|
||||
final retDateTextController = TextEditingController();
|
||||
final selectedFileController = TextEditingController();
|
||||
final medicineController = TextEditingController();
|
||||
final quantityController = TextEditingController();
|
||||
final dosageController = TextEditingController();
|
||||
final timesDailyController = TextEditingController();
|
||||
final noDaysController = TextEditingController();
|
||||
final noRepeatsController = TextEditingController();
|
||||
final outputController = TextEditingController();
|
||||
|
||||
late Future<List<PFile>> futueFiles;
|
||||
late String userEmail = "";
|
||||
@@ -301,6 +309,70 @@ class _PatientFilesState extends State<PatientFiles> {
|
||||
);
|
||||
}
|
||||
|
||||
void prescritionPopUp() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => Dialog(
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
width: 900.0,
|
||||
//height: 475.0,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(25.0),
|
||||
border: Border.all(color: Colors.blueAccent, width: 5.0),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
"Create Precrition",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.blueAccent,
|
||||
fontSize: 35.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25.0),
|
||||
PrescripInput(
|
||||
medicineController: medicineController,
|
||||
quantityController: quantityController,
|
||||
dosageController: dosageController,
|
||||
timesDailyController: timesDailyController,
|
||||
noDaysController: noDaysController,
|
||||
noRepeatsController: noRepeatsController,
|
||||
outputController: outputController,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 5,
|
||||
right: 5,
|
||||
width: 50,
|
||||
height: 50,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.close,
|
||||
color: Colors.red,
|
||||
size: 35,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void uploudFilePopUp() {
|
||||
showDialog(
|
||||
context: context,
|
||||
@@ -486,7 +558,9 @@ class _PatientFilesState extends State<PatientFiles> {
|
||||
icon: const Icon(Icons.sick_outlined),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
onPressed: () {
|
||||
prescritionPopUp();
|
||||
},
|
||||
icon: const Icon(Icons.medication_outlined),
|
||||
),
|
||||
IconButton(
|
||||
|
||||
216
Frontend/patient_manager/lib/components/prescipInput.dart
Normal file
216
Frontend/patient_manager/lib/components/prescipInput.dart
Normal file
@@ -0,0 +1,216 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:patient_manager/components/medicineSearch.dart';
|
||||
import 'package:patient_manager/components/myDropdownInput.dart';
|
||||
import 'package:patient_manager/components/myMLTextInput.dart';
|
||||
import 'package:patient_manager/components/mySearchInput.dart';
|
||||
import 'package:patient_manager/components/mybutton.dart';
|
||||
|
||||
class PrescripInput extends StatefulWidget {
|
||||
final TextEditingController medicineController;
|
||||
final TextEditingController quantityController;
|
||||
final TextEditingController dosageController;
|
||||
final TextEditingController timesDailyController;
|
||||
final TextEditingController noDaysController;
|
||||
final TextEditingController noRepeatsController;
|
||||
final TextEditingController outputController;
|
||||
|
||||
const PrescripInput({
|
||||
super.key,
|
||||
required this.medicineController,
|
||||
required this.quantityController,
|
||||
required this.dosageController,
|
||||
required this.timesDailyController,
|
||||
required this.noDaysController,
|
||||
required this.noRepeatsController,
|
||||
required this.outputController,
|
||||
});
|
||||
|
||||
@override
|
||||
State<PrescripInput> createState() => _PrescripInputState();
|
||||
}
|
||||
|
||||
class _PrescripInputState extends State<PrescripInput> {
|
||||
String searchString = "";
|
||||
|
||||
final numberOptions = [
|
||||
"0",
|
||||
"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"
|
||||
];
|
||||
|
||||
void getMedsPopUp(TextEditingController medSearch) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MedicineSearch(
|
||||
searchVlaue: medSearch,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
//futueMeds = getMedList(endpointMeds);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: MySearchField(
|
||||
controller: widget.medicineController,
|
||||
hintText: "Medicine",
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
searchString = value;
|
||||
});
|
||||
},
|
||||
required: true,
|
||||
editable: true,
|
||||
onTap: () {
|
||||
getMedsPopUp(widget.medicineController);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25.0),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: MyDropdownField(
|
||||
controller: widget.quantityController,
|
||||
hintText: "Quantity",
|
||||
dropdownOptions: numberOptions,
|
||||
required: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25.0),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: MyDropdownField(
|
||||
controller: widget.dosageController,
|
||||
hintText: "Dosage",
|
||||
dropdownOptions: numberOptions,
|
||||
required: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25.0),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: MyDropdownField(
|
||||
controller: widget.timesDailyController,
|
||||
hintText: "Times Daily",
|
||||
dropdownOptions: numberOptions,
|
||||
required: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25.0),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: MyDropdownField(
|
||||
controller: widget.noDaysController,
|
||||
hintText: "No. Days",
|
||||
dropdownOptions: numberOptions,
|
||||
required: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25.0),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: MyDropdownField(
|
||||
controller: widget.noRepeatsController,
|
||||
hintText: "No. Repeats",
|
||||
dropdownOptions: numberOptions,
|
||||
required: true,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
child: MyButton(
|
||||
onTap: () {},
|
||||
buttonText: "Add",
|
||||
buttonColor: Colors.blueAccent,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
//const SizedBox(height: 50.0),
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 550,
|
||||
height: 400,
|
||||
child: MyMLTextField(
|
||||
controller: widget.outputController,
|
||||
hintText: "Prescrion Output",
|
||||
editable: false,
|
||||
required: false,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 300,
|
||||
height: 100,
|
||||
child: MyButton(
|
||||
onTap: () {
|
||||
// if (isMedCertFieldsFilled()) {
|
||||
// generateMedCert();
|
||||
// Navigator.pop(context);
|
||||
// } else {
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) {
|
||||
// return const MyErrorMessage(
|
||||
// errorType: "Input Error");
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
},
|
||||
buttonText: "Generate",
|
||||
buttonColor: Colors.green,
|
||||
textColor: Colors.white,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,6 @@ class _ProfileUserUpdateState extends State<ProfileUserUpdate> {
|
||||
const SizedBox(height: 10.0),
|
||||
MyDropdownField(
|
||||
controller: titleController,
|
||||
signedInUser: widget.signedInUser,
|
||||
hintText: "Title",
|
||||
dropdownOptions: const <String>["Dr.", "Assistant"],
|
||||
required: true,
|
||||
|
||||
19
Frontend/patient_manager/lib/objects/medicine.dart
Normal file
19
Frontend/patient_manager/lib/objects/medicine.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
class Medicine {
|
||||
final String name;
|
||||
final String unit;
|
||||
final String form;
|
||||
|
||||
const Medicine(
|
||||
this.name,
|
||||
this.unit,
|
||||
this.form,
|
||||
);
|
||||
|
||||
factory Medicine.fromJson(dynamic json) {
|
||||
return Medicine(
|
||||
json['name'],
|
||||
json['unit'],
|
||||
json['dosage form'],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -88,6 +88,9 @@ class _PatientManagerState extends State<PatientManager> {
|
||||
MySearchField(
|
||||
controller: searchController,
|
||||
hintText: "ID Search",
|
||||
required: false,
|
||||
editable: true,
|
||||
onTap: () {},
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
searchString = value;
|
||||
|
||||
Reference in New Issue
Block a user