我有一个表,显示了我的数据库中的一些数据。我在同一屏幕上有一个按钮,用于显示弹出窗口,即一个表单。我使用此表单在数据库中输入新数据。我希望它是这样的,只要我向数据库提交数据,在后台打开的表应更新并显示添加的数据。
我希望当我按下弹出窗体中的添加按钮时,后台的表格应显示添加的数据。
销售记录表:
import 'package:ame/models/sales.dart';
import 'package:ame/screens/Records/sales_entry_form.dart';
import 'package:ame/services/saleServices.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class SalesRecords extends StatefulWidget {
const SalesRecords({super.key});
@override
State<SalesRecords> createState() => _SalesRecordsState();
}
class _SalesRecordsState extends State<SalesRecords> {
var now = DateTime.now();
late DateTime _selectedDate = DateTime(now.year, now.month, now.day);
late int _selectedDateSeconds = _selectedDate.millisecondsSinceEpoch;
var saleService = SaleServices();
List<Sale> sales = [];
List<Sale> filteredSales = [];
Color receiptedRowColor = Colors.lightGreenAccent;
int totalSales = 0;
bool receiptedFiltered = false;
final searchController = TextEditingController();
fetchSalesList(BuildContext context) async {
var response =
await saleService.fetchSalesByDate(context, _selectedDateSeconds);
setState(() {
sales = response;
totalSales = 0;
for (var sale in sales) {
totalSales = totalSales + sale.amount;
}
});
}
fetchReceiptedSales(BuildContext context) async {
var response =
await saleService.fetchReceiptedSales(context, _selectedDateSeconds);
setState(() {
sales = response;
totalSales = 0;
for (var sale in sales) {
totalSales = totalSales + sale.amount;
}
});
}
updatesale(BuildContext context, int id, Map<String, dynamic> info) async {
await saleService.updateSale(context, id, info);
}
Future<void> _selectDate() async {
final DateTime? d = await showDatePicker(
context: context,
initialDate: _selectedDate,
firstDate: DateTime(2015, 8),
lastDate: DateTime(2101),
);
if (d != null) {
setState(() {
_selectedDate = d;
_selectedDateSeconds = d.millisecondsSinceEpoch;
});
fetchSalesList(context);
}
}
toggleReceiptedSales(BuildContext context) async {
setState(() {
receiptedFiltered = !receiptedFiltered;
});
receiptedFiltered ? fetchReceiptedSales(context) : fetchSalesList(context);
}
updateSale(BuildContext context, int id, Map<String, dynamic> info) async {
await saleService.updateSale(context, id, info);
}
void _onSearchTextChanged(String text) {
setState(() {
filteredSales = text.isEmpty
? []
: sales
.where((sale) =>
sale.contact.toLowerCase().contains(text.toLowerCase()))
.toList();
});
}
@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () {
fetchSalesList(context);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
margin: const EdgeInsets.all(20.0),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(children: [
SizedBox(
width: MediaQuery.of(context).size.width,
child: Row(mainAxisSize: MainAxisSize.min, children: [
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: const Icon(Icons.arrow_back)),
]),
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Text("Sales Records",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20)),
),
Padding(
padding: const EdgeInsets.all(5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: <Widget>[
InkWell(
child:
Text(DateFormat.yMMMMd("en_US").format(_selectedDate),
textAlign: TextAlign.center,
style: const TextStyle(
color: Color(0xFF000000),
fontSize: 15,
)),
onTap: () {
_selectDate();
},
),
IconButton(
icon: Icon(
Icons.calendar_today,
color: Theme.of(context).colorScheme.primary,
),
tooltip: 'choose date',
onPressed: () async {
_selectDate();
},
),
],
),
Container(
width: 300,
child: TextField(
controller: searchController,
decoration: const InputDecoration(
hintText: "Search Contact",
border: UnderlineInputBorder(
borderRadius: BorderRadius.zero,
),
),
onChanged: _onSearchTextChanged,
),
),
TextButton(
onPressed: () {
formPopUp(context);
},
child: const Text(
"Add New Record",
style: TextStyle(fontWeight: FontWeight.bold),
))
],
),
),
Table(
border: TableBorder(
horizontalInside:
BorderSide(color: Theme.of(context).colorScheme.primary)),
children: [
TableRow(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary),
children: [
SizedBox(
height: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('R_No',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0))
]),
),
SizedBox(
height: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('Contact',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0))
]),
),
SizedBox(
height: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('Description',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0))
]),
),
SizedBox(
height: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('Amount',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0))
]),
),
SizedBox(
height: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text('Delivered',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0))
]),
),
SizedBox(
height: 40,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
toggleReceiptedSales(context);
},
child: const Text('Receipted',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0)),
)
]),
),
]),
if (searchController.text.trim() != "")
for (int i = 0; i < filteredSales.length; i++)
filteredTableRow(context, i)
else
for (int i = 0; i < sales.length; i++)
fullTableRow(context, i)
]),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text("Total: KES. ${NumberFormat('#,###.##').format(totalSales)}",
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 15))
],
)
]),
),
);
}
formPopUp(BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
"Enter New Sale Record",
style: TextStyle(fontWeight: FontWeight.bold),
),
content: SalesEntryForm(date: _selectedDateSeconds),
);
},
);
}
TableRow fullTableRow(BuildContext context, int i) {
return TableRow(
decoration: BoxDecoration(
color: sales[i].receipted
? receiptedRowColor
: (i) % 2 == 0
? const Color.fromRGBO(7, 96, 49, 0)
: const Color.fromARGB(100, 7, 96, 49),
),
children: [
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: EditableText(
controller: TextEditingController(text: sales[i].rNo),
style: const TextStyle(fontSize: 15.0, color: Colors.black),
backgroundCursorColor: Theme.of(context).colorScheme.primary,
cursorColor: Theme.of(context).colorScheme.primary,
focusNode: FocusNode(),
textAlign: TextAlign.center,
onSubmitted: (value) {
updateSale(context, sales[i].id, {"R_No": value});
},
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: EditableText(
controller: TextEditingController(text: sales[i].contact),
style: const TextStyle(fontSize: 15.0, color: Colors.black),
backgroundCursorColor: Theme.of(context).colorScheme.primary,
cursorColor: Theme.of(context).colorScheme.primary,
focusNode: FocusNode(),
textAlign: TextAlign.center,
onSubmitted: (value) {
updateSale(context, sales[i].id, {"contact": value});
},
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: EditableText(
controller: TextEditingController(text: sales[i].description),
style: const TextStyle(fontSize: 15.0, color: Colors.black),
backgroundCursorColor: Theme.of(context).colorScheme.primary,
cursorColor: Theme.of(context).colorScheme.primary,
focusNode: FocusNode(),
textAlign: TextAlign.center,
onSubmitted: (value) {
updateSale(context, sales[i].id, {"description": value});
},
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: EditableText(
controller:
TextEditingController(text: sales[i].amount.toString()),
style: const TextStyle(fontSize: 15.0, color: Colors.black),
backgroundCursorColor: Theme.of(context).colorScheme.primary,
cursorColor: Theme.of(context).colorScheme.primary,
focusNode: FocusNode(),
textAlign: TextAlign.center,
onSubmitted: (value) {
updateSale(context, sales[i].id, {"amount": int.parse(value)});
},
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Checkbox(
value: sales[i].delivered,
onChanged: ((newValue) {
setState(() {
sales[i].delivered = newValue!;
});
updateSale(context, sales[i].id, {"delivered": newValue!});
}),
activeColor: Theme.of(context).colorScheme.primary,
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Checkbox(
value: sales[i].receipted,
onChanged: ((newValue) {
setState(() {
sales[i].receipted = newValue!;
});
updateSale(context, sales[i].id, {"receipted": newValue!});
}),
activeColor: Theme.of(context).colorScheme.primary,
),
),
]);
}
TableRow filteredTableRow(BuildContext context, int i) {
return TableRow(
decoration: BoxDecoration(
color: filteredSales[i].receipted
? receiptedRowColor
: (i) % 2 == 0
? const Color.fromRGBO(7, 96, 49, 0)
: const Color.fromARGB(100, 7, 96, 49),
),
children: [
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: EditableText(
controller: TextEditingController(text: filteredSales[i].rNo),
style: const TextStyle(fontSize: 15.0, color: Colors.black),
backgroundCursorColor: Theme.of(context).colorScheme.primary,
cursorColor: Theme.of(context).colorScheme.primary,
focusNode: FocusNode(),
textAlign: TextAlign.center,
onSubmitted: (value) {
updateSale(context, filteredSales[i].id, {"R_No": value});
},
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: EditableText(
controller: TextEditingController(text: filteredSales[i].contact),
style: const TextStyle(fontSize: 15.0, color: Colors.black),
backgroundCursorColor: Theme.of(context).colorScheme.primary,
cursorColor: Theme.of(context).colorScheme.primary,
focusNode: FocusNode(),
textAlign: TextAlign.center,
onSubmitted: (value) {
updateSale(context, filteredSales[i].id, {"contact": value});
},
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: EditableText(
controller:
TextEditingController(text: filteredSales[i].description),
style: const TextStyle(fontSize: 15.0, color: Colors.black),
backgroundCursorColor: Theme.of(context).colorScheme.primary,
cursorColor: Theme.of(context).colorScheme.primary,
focusNode: FocusNode(),
textAlign: TextAlign.center,
onSubmitted: (value) {
updateSale(
context, filteredSales[i].id, {"description": value});
},
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: EditableText(
controller: TextEditingController(
text: filteredSales[i].amount.toString()),
style: const TextStyle(fontSize: 15.0, color: Colors.black),
backgroundCursorColor: Theme.of(context).colorScheme.primary,
cursorColor: Theme.of(context).colorScheme.primary,
focusNode: FocusNode(),
textAlign: TextAlign.center,
onSubmitted: (value) {
updateSale(
context, filteredSales[i].id, {"amount": int.parse(value)});
},
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Checkbox(
value: filteredSales[i].delivered,
onChanged: ((newValue) {
setState(() {
filteredSales[i].delivered = newValue!;
});
updateSale(
context, filteredSales[i].id, {"delivered": newValue!});
}),
activeColor: Theme.of(context).colorScheme.primary,
),
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.middle,
child: Checkbox(
value: filteredSales[i].receipted,
onChanged: ((newValue) {
setState(() {
filteredSales[i].receipted = newValue!;
});
updateSale(
context, filteredSales[i].id, {"receipted": newValue!});
}),
activeColor: Theme.of(context).colorScheme.primary,
),
),
]);
}
}
销售登记表:
import 'package:ame/services/saleServices.dart';
import 'package:flutter/material.dart';
class SalesEntryForm extends StatefulWidget {
SalesEntryForm({super.key, required this.date});
int date;
@override
State<SalesEntryForm> createState() => _SalesEntryFormState();
}
class _SalesEntryFormState extends State<SalesEntryForm> {
static final _formKey = GlobalKey<FormState>();
var saleService = SaleServices();
final TextEditingController _contactController = TextEditingController();
final TextEditingController _amountController = TextEditingController();
final TextEditingController _descriptionController = TextEditingController();
Future<void> addNewSale() async {
try {
var resposne = await saleService.insertNewSale(context, {
"date": widget.date,
"contact": _contactController.text.trim(),
"amount": int.parse(_amountController.text.trim()),
"description": _descriptionController.text.trim()
});
} catch (e) {
print(e);
} finally {
_formKey.currentState?.reset();
}
}
@override
Widget build(BuildContext context) {
var heightVariable = MediaQuery.of(context).size.height;
return SizedBox(
height: heightVariable * 0.5,
width: heightVariable * 0.7,
child: Form(
key: _formKey,
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.2,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
margin: const EdgeInsets.all(10.0),
child: TextFormField(
decoration: InputDecoration(
labelText: "Contact",
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.colorScheme
.primary),
borderRadius: BorderRadius.zero),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
borderRadius: BorderRadius.zero)),
controller: _contactController,
),
),
),
Expanded(
child: Container(
margin: const EdgeInsets.all(10.0),
child: TextFormField(
decoration: InputDecoration(
labelText: "Amount",
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.colorScheme
.primary),
borderRadius: BorderRadius.zero),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
borderRadius: BorderRadius.zero)),
controller: _amountController,
),
),
),
],
),
Expanded(
child: Container(
margin: const EdgeInsets.all(10.0),
child: TextFormField(
decoration: InputDecoration(
labelText: "Description",
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.primary),
borderRadius: BorderRadius.zero),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
borderRadius: BorderRadius.zero)),
controller: _descriptionController,
maxLines: 20,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
margin: const EdgeInsets.all(10.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: const BeveledRectangleBorder(),
padding: const EdgeInsets.symmetric(
vertical: 16.0, horizontal: 20.0),
),
onPressed: () {
addNewSale();
},
child: const Text("Add")),
),
],
)
],
),
)),
);
}
}
1条答案
按热度按时间5vf7fwbs1#
您应该向SalesEntryForm中注入一个回调,以更新您的销售列表,因此在try/catch中,在
var response = await saleService.insertNewSale(...
之后,您使用销售示例调用此回调,我不知道您是否可以使用这些数据进行销售,或者响应中是否包含销售示例。