From 58cbd2a4625a4883bb0626fe88d8afcb569884d8 Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Thu, 1 Jan 2026 23:19:49 +0100 Subject: [PATCH] =?UTF-8?q?Fix:=20Passt=20das=20Verhalten=20der=20InputFel?= =?UTF-8?q?der=20an,=20dass=20sich=20diese=20wirklich=20ver=C3=A4ndern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dashboard/recent_transactions_list.dart | 1 + .../Misc/InputFields/date_range_picker.dart | 51 ++++++------ .../InputFields/dynamic_date_time_field.dart | 5 +- lib/Pages/Misc/monthly_balance_chart.dart | 2 +- lib/Pages/Trend/input_fields.dart | 82 ++++++++++++------- lib/Pages/Trend/transaction_list.dart | 3 +- lib/Pages/Trend/trend.dart | 3 - 7 files changed, 85 insertions(+), 62 deletions(-) diff --git a/lib/Pages/Dashboard/recent_transactions_list.dart b/lib/Pages/Dashboard/recent_transactions_list.dart index e96882f..7e0a2bb 100644 --- a/lib/Pages/Dashboard/recent_transactions_list.dart +++ b/lib/Pages/Dashboard/recent_transactions_list.dart @@ -36,6 +36,7 @@ class _RecentTransactionsListState extends State { final Future> recentTransactions = _transactionRepository .findBy( account: _accountController.selected.value, + dateTo: DateTime.now(), limit: 5, orderBy: 'dateDesc', ); diff --git a/lib/Pages/Misc/InputFields/date_range_picker.dart b/lib/Pages/Misc/InputFields/date_range_picker.dart index c1005df..e7456e5 100644 --- a/lib/Pages/Misc/InputFields/date_range_picker.dart +++ b/lib/Pages/Misc/InputFields/date_range_picker.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../../../Services/date_service.dart'; import '../../Dialog/dialog_action.dart'; import '../../Dialog/dialog_input_field.dart'; import '../../Dialog/dialog_input_field_type_enum.dart'; @@ -9,16 +10,13 @@ import '../../Dialog/dynamic_dialog.dart'; class DateRangePicker extends StatefulWidget { /// Initialisiert eine neue Instanz dieser Klasse const DateRangePicker({ + this.controller, this.autofocus = false, super.key, this.decoration, - this.initialValue, this.onChanged, }); - /// Der Initiale Wert des Input-Feldes - final DateTimeRange? initialValue; - /// Ob das Feld automatisch ausgewählt werden soll final bool autofocus; @@ -28,42 +26,39 @@ class DateRangePicker extends StatefulWidget { /// Die Dekoration, wie das Feld aussehen soll final InputDecoration? decoration; + /// Der Controller über den der Wert des Inputfeldes gesetzt + /// und ausgelesen werden kann + final TextEditingController? controller; + @override State createState() => _DateRangePicker(); } class _DateRangePicker extends State { - final ValueNotifier _value = ValueNotifier(null); + final TextEditingController _valueController = TextEditingController(); @override - void initState() { - super.initState(); + void dispose() { + _valueController.dispose(); - _value.value = widget.initialValue; - _value.addListener(() { - widget.onChanged?.call(_value.value); - }); + super.dispose(); } @override Widget build(final BuildContext context) => TextField( readOnly: true, - controller: TextEditingController( - text: widget.initialValue != null - ? '${widget.initialValue!.start.day}' - '.${widget.initialValue!.start.month}' - '.${widget.initialValue!.start.year}' - ' - ' - '${widget.initialValue!.end.day}' - '.${widget.initialValue!.end.month}' - '.${widget.initialValue!.end.year}' - : null, - ), + controller: widget.controller ?? _valueController, decoration: widget.decoration, onTap: _pickDateRange, ); Future _pickDateRange() async { + final TextEditingController controller = + widget.controller ?? _valueController; + + final DateTimeRange? dateTimeRange = + DateService.stringToDateTimeRange(controller.text); + await DynamicDialog( title: 'Zeitraum auswählen', inputFields: [ @@ -72,14 +67,14 @@ class _DateRangePicker extends State { label: 'Startdatum', keyboardType: TextInputType.datetime, inputType: DialogInputFieldTypeEnum.date, - initialValue: _value.value?.start, + initialValue: dateTimeRange?.start, ), DialogInputField( id: 'dateTo', label: 'Enddatum', keyboardType: TextInputType.datetime, inputType: DialogInputFieldTypeEnum.date, - initialValue: _value.value?.end, + initialValue: dateTimeRange?.end, ), ], actions: [ @@ -87,7 +82,8 @@ class _DateRangePicker extends State { DialogAction( label: 'Leeren', onPressed: (_) { - _value.value = null; + controller.text = ''; + widget.onChanged?.call(null); }, ), DialogAction( @@ -98,10 +94,13 @@ class _DateRangePicker extends State { values['dateFrom'] is DateTime && values['dateTo'] != null && values['dateTo'] is DateTime) { - _value.value = DateTimeRange( + final DateTimeRange timeRange = DateTimeRange( start: values['dateFrom'], end: values['dateTo'], ); + + controller.text = DateService.dateTimeRangeToString(timeRange)!; + widget.onChanged?.call(timeRange); } }, ), diff --git a/lib/Pages/Misc/InputFields/dynamic_date_time_field.dart b/lib/Pages/Misc/InputFields/dynamic_date_time_field.dart index bf91e81..a4ed6f9 100644 --- a/lib/Pages/Misc/InputFields/dynamic_date_time_field.dart +++ b/lib/Pages/Misc/InputFields/dynamic_date_time_field.dart @@ -1,6 +1,7 @@ import 'package:date_field/date_field.dart'; import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; + +import '../../../Services/date_service.dart'; /// Ein Feld mit Popup über welches man Datumsfelder auswählen kann class DynamicDateTimeField extends StatefulWidget { @@ -45,7 +46,7 @@ class _DynamicDateTimeFieldState extends State { @override Widget build(final BuildContext context) => DateTimeField( initialPickerDateTime: widget.initialValue, - dateFormat: DateFormat('d.M.y'), + dateFormat: DateService.dateFormat, value: _value, mode: widget.mode, autofocus: widget.autofocus, diff --git a/lib/Pages/Misc/monthly_balance_chart.dart b/lib/Pages/Misc/monthly_balance_chart.dart index 1765041..c96ab3d 100644 --- a/lib/Pages/Misc/monthly_balance_chart.dart +++ b/lib/Pages/Misc/monthly_balance_chart.dart @@ -62,7 +62,7 @@ class _MonthlyBalanceChart extends State { amountMin: widget.amountMin, amountMax: widget.amountMax, dateFrom: widget.dateFrom, - dateTo: widget.dateTo, + dateTo: (widget.dateTo != null) ? widget.dateTo : DateTime.now(), ), builder: ( diff --git a/lib/Pages/Trend/input_fields.dart b/lib/Pages/Trend/input_fields.dart index 769a30e..6eb81d4 100644 --- a/lib/Pages/Trend/input_fields.dart +++ b/lib/Pages/Trend/input_fields.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:routemaster/routemaster.dart'; +import '../../Services/date_service.dart'; import '../Misc/InputFields/date_range_picker.dart'; /// Stellt die Inputfelder für die Verlaufsübersicht dar @@ -13,7 +14,6 @@ class InputFields extends StatefulWidget { this.dateFrom, this.dateTo, this.name, - this.onChanged, }); /// Der Name der Transaktion, nach der gesucht werden soll @@ -31,35 +31,54 @@ class InputFields extends StatefulWidget { ///Das Datum der Transaktionen, bis zu welchen beendet wurde final DateTime? dateTo; - /// Die Funktion, die bei Veränderung eines Wertes aufgerufen wird - final Function()? onChanged; - @override State createState() => _InputFields(); } class _InputFields extends State { - String? _name; - double? _amountMin; - double? _amountMax; - DateTimeRange? _dateTimeRange; + final TextEditingController _nameController = TextEditingController(); + final TextEditingController _amountMinController = TextEditingController(); + final TextEditingController _amountMaxController = TextEditingController(); + final TextEditingController _dateTimeController = TextEditingController(); @override void initState() { super.initState(); - _name = widget.name; - _amountMin = widget.amountMin; - _amountMax = widget.amountMax; + if (widget.name != null) { + _nameController.text = widget.name!; + } + + if (widget.amountMin != null) { + _amountMinController.text = widget.amountMin!.toString(); + } + + if (widget.amountMax != null) { + _amountMaxController.text = widget.amountMax!.toString(); + } if (widget.dateFrom != null && widget.dateTo != null) { - _dateTimeRange = DateTimeRange( + final DateTimeRange dateTimeRange = DateTimeRange( start: widget.dateFrom!, end: widget.dateTo!, ); + + _dateTimeController.text = DateService.dateTimeRangeToString( + dateTimeRange, + )!; } } + @override + void dispose() { + _nameController.dispose(); + _amountMinController.dispose(); + _amountMaxController.dispose(); + _dateTimeController.dispose(); + + super.dispose(); + } + @override Widget build(final BuildContext context) { final ThemeData theme = Theme.of(context); @@ -68,12 +87,12 @@ class _InputFields extends State { children: [ Expanded( child: TextField( + controller: _nameController, decoration: const InputDecoration( labelText: 'Name', border: OutlineInputBorder(), ), onChanged: (final String value) { - _name = value; _updateUrl(); }, ), @@ -81,13 +100,13 @@ class _InputFields extends State { const SizedBox(width: 8), Expanded( child: TextField( + controller: _amountMinController, decoration: const InputDecoration( labelText: 'Min Betrag €', border: OutlineInputBorder(), ), keyboardType: const TextInputType.numberWithOptions(decimal: true), onChanged: (final String value) { - _amountMin = double.tryParse(value); _updateUrl(); }, ), @@ -95,13 +114,13 @@ class _InputFields extends State { const SizedBox(width: 8), Expanded( child: TextField( + controller: _amountMaxController, decoration: const InputDecoration( labelText: 'Max Betrag €', border: OutlineInputBorder(), ), keyboardType: const TextInputType.numberWithOptions(decimal: true), onChanged: (final String value) { - _amountMax = double.tryParse(value); _updateUrl(); }, ), @@ -109,9 +128,8 @@ class _InputFields extends State { const SizedBox(width: 8), Expanded( child: DateRangePicker( - initialValue: _dateTimeRange, + controller: _dateTimeController, onChanged: (final DateTimeRange? value) { - _dateTimeRange = value; _updateUrl(); }, decoration: InputDecoration( @@ -127,10 +145,10 @@ class _InputFields extends State { const SizedBox(width: 8), IconButton( onPressed: () { - _name = null; - _amountMin = null; - _amountMax = null; - _dateTimeRange = null; + _nameController.text = ''; + _amountMinController.text = ''; + _amountMaxController.text = ''; + _dateTimeController.text = ''; _updateUrl(); }, @@ -142,18 +160,24 @@ class _InputFields extends State { void _updateUrl() { final params = { - if (_name != null && _name != '') 'name': _name!, - if (_amountMin != null) 'amountMin': _amountMin!.toString(), - if (_amountMax != null) 'amountMax': _amountMax!.toString(), + if (_nameController.text != '') 'name': _nameController.text, + if (_amountMinController.text != '') + 'amountMin': _amountMinController.text, + if (_amountMaxController.text != '') + 'amountMax': _amountMaxController.text, }; - if (_dateTimeRange != null) { - params['dateFrom'] = _dateTimeRange!.start.toIso8601String(); - params['dateTo'] = _dateTimeRange!.end.toIso8601String(); + if (_dateTimeController.text != '') { + final DateTimeRange? range = DateService.stringToDateTimeRange( + _dateTimeController.text, + ); + + if (range != null) { + params['dateFrom'] = range.start.toIso8601String(); + params['dateTo'] = range.end.toIso8601String(); + } } Routemaster.of(context).replace('/trend', queryParameters: params); - - widget.onChanged?.call(); } } diff --git a/lib/Pages/Trend/transaction_list.dart b/lib/Pages/Trend/transaction_list.dart index 591e9a2..1bd1ffc 100644 --- a/lib/Pages/Trend/transaction_list.dart +++ b/lib/Pages/Trend/transaction_list.dart @@ -62,8 +62,9 @@ class _TransactionListState extends State { amountMin: widget.amountMin, amountMax: widget.amountMax, dateFrom: widget.dateFrom, - dateTo: widget.dateTo, + dateTo: (widget.dateTo != null) ? widget.dateTo : DateTime.now(), account: _accountController.selected.value, + orderBy: 'dateDesc', ), builder: ( diff --git a/lib/Pages/Trend/trend.dart b/lib/Pages/Trend/trend.dart index 8f34039..0f172d1 100644 --- a/lib/Pages/Trend/trend.dart +++ b/lib/Pages/Trend/trend.dart @@ -44,9 +44,6 @@ class _TrendState extends State { amountMax: amountMax, dateFrom: dateFrom, dateTo: dateTo, - onChanged: () { - setState(() {}); - }, ), const SizedBox(height: 24),