Add the Form widget and get the fields working with it. Still need to pull the values into a usable object for saving.

This commit is contained in:
Hyperling 2025-02-05 04:20:10 -07:00
parent 7ead0e5ebb
commit 99b1ec82e6

View File

@ -166,59 +166,106 @@ class ExpenseInputDialog extends StatefulWidget {
}
class _ExpenseInputDialogState extends State<ExpenseInputDialog> {
final _expenseFormKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
const inputWidth = 300.0;
const inputHeight = 50.0;
const recurrenceValues = <DropdownMenuEntry>[
DropdownMenuEntry(value: Recurrence.daily, label: "Daily"),
DropdownMenuEntry(value: Recurrence.weekly, label: "Weekly"),
DropdownMenuEntry(value: Recurrence.biweekly, label: "Biweekly"),
DropdownMenuEntry(value: Recurrence.montly, label: "Monthly"),
DropdownMenuEntry(value: Recurrence.yearly, label: "Yearly"),
const recurrenceValues = <DropdownMenuItem>[
DropdownMenuItem(value: Recurrence.daily, child: Text("Daily")),
DropdownMenuItem(value: Recurrence.weekly, child: Text("Weekly")),
DropdownMenuItem(value: Recurrence.biweekly, child: Text("Biweekly")),
DropdownMenuItem(value: Recurrence.montly, child: Text("Monthly")),
DropdownMenuItem(
value: Recurrence.yearly,
child: Text(
"Yearly",
)),
];
return AlertDialog(
title: Center(child: Text("Add New Expense")),
content: Column(mainAxisSize: MainAxisSize.min, spacing: 10, children: [
SizedBox(
content: Form(
key: _expenseFormKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(mainAxisSize: MainAxisSize.min, spacing: 10, children: [
SizedBox(
width: inputWidth,
height: inputHeight,
child: TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: "Name",
hintText: "Example: Red Pocket Phone Bill",
),
validator: (value) {
if (value!.isEmpty) {
return "Name must be provided.";
}
return null;
},
onChanged: (newValue) {
// _expenseFormKey.currentState!.reset();
},
)),
SizedBox(
width: inputWidth,
height: inputHeight,
child: TextField(
keyboardType: TextInputType.text,
child: TextFormField(
keyboardType: TextInputType.numberWithOptions(decimal: true),
decoration: InputDecoration(
labelText: "Name",
hintText: "Example: Red Pocket Phone Bill",
),
// https://docs.flutter.dev/cookbook/forms/retrieve-input
//controller: nameFieldController,
)),
SizedBox(
width: inputWidth,
height: inputHeight,
child: TextField(
keyboardType: TextInputType.numberWithOptions(decimal: true),
decoration:
InputDecoration(labelText: "Cost", hintText: "Example: 10.00"),
labelText: "Cost", hintText: "Example: 10.00"),
validator: (value) {
if (value!.isEmpty) {
return "Cost must be provided.";
}
if (double.tryParse(value!) == null) {
return "Cost must be a valid number.";
}
return null;
},
onChanged: (newValue) {
//_expenseFormKey.currentState!.reset();
},
),
),
),
DropdownMenu(
dropdownMenuEntries: recurrenceValues,
width: inputWidth,
label: Text("Recurrence"),
hintText: "Example: Monthly",
),
SizedBox(
SizedBox(
width: inputWidth,
height: inputHeight,
child: TextField(
keyboardType: TextInputType.text,
child: DropdownButtonFormField(
items: recurrenceValues,
decoration: InputDecoration(
labelText: "Description",
hintText: "Example: 1GB data with unlimited talk & text."),
)),
]),
labelText: "Recurrence", hintText: "Example: Monthly"),
validator: (value) {
if (value == null) {
return "Recurrence must be provided.";
}
return null;
},
onChanged: (newValue) {
//_expenseFormKey.currentState!.reset();
},
),
),
SizedBox(
width: inputWidth,
height: inputHeight,
child: TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: "Description",
hintText: "Example: 1GB data with unlimited talk & text."),
validator: (value) {
return null;
},
onChanged: (newValue) {
//_expenseFormKey.currentState!.reset();
},
)),
]),
),
actions: [
SizedBox(
width: inputWidth,
@ -238,7 +285,10 @@ class _ExpenseInputDialogState extends State<ExpenseInputDialog> {
ElevatedButton.icon(
onPressed: () {
print("TODO: Save expense!");
Navigator.of(context).pop();
if (_expenseFormKey.currentState!.validate()) {
_expenseFormKey.currentState!.save();
Navigator.of(context).pop();
}
},
icon: Icon(Icons.save),
label: Text('Submit'),