Fix: Passt das Verhalten der InputFelder an, dass sich diese wirklich verändern
This commit is contained in:
@@ -36,6 +36,7 @@ class _RecentTransactionsListState extends State<RecentTransactionsList> {
|
|||||||
final Future<List<Transaction>> recentTransactions = _transactionRepository
|
final Future<List<Transaction>> recentTransactions = _transactionRepository
|
||||||
.findBy(
|
.findBy(
|
||||||
account: _accountController.selected.value,
|
account: _accountController.selected.value,
|
||||||
|
dateTo: DateTime.now(),
|
||||||
limit: 5,
|
limit: 5,
|
||||||
orderBy: 'dateDesc',
|
orderBy: 'dateDesc',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../Services/date_service.dart';
|
||||||
import '../../Dialog/dialog_action.dart';
|
import '../../Dialog/dialog_action.dart';
|
||||||
import '../../Dialog/dialog_input_field.dart';
|
import '../../Dialog/dialog_input_field.dart';
|
||||||
import '../../Dialog/dialog_input_field_type_enum.dart';
|
import '../../Dialog/dialog_input_field_type_enum.dart';
|
||||||
@@ -9,16 +10,13 @@ import '../../Dialog/dynamic_dialog.dart';
|
|||||||
class DateRangePicker extends StatefulWidget {
|
class DateRangePicker extends StatefulWidget {
|
||||||
/// Initialisiert eine neue Instanz dieser Klasse
|
/// Initialisiert eine neue Instanz dieser Klasse
|
||||||
const DateRangePicker({
|
const DateRangePicker({
|
||||||
|
this.controller,
|
||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
super.key,
|
super.key,
|
||||||
this.decoration,
|
this.decoration,
|
||||||
this.initialValue,
|
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Der Initiale Wert des Input-Feldes
|
|
||||||
final DateTimeRange? initialValue;
|
|
||||||
|
|
||||||
/// Ob das Feld automatisch ausgewählt werden soll
|
/// Ob das Feld automatisch ausgewählt werden soll
|
||||||
final bool autofocus;
|
final bool autofocus;
|
||||||
|
|
||||||
@@ -28,42 +26,39 @@ class DateRangePicker extends StatefulWidget {
|
|||||||
/// Die Dekoration, wie das Feld aussehen soll
|
/// Die Dekoration, wie das Feld aussehen soll
|
||||||
final InputDecoration? decoration;
|
final InputDecoration? decoration;
|
||||||
|
|
||||||
|
/// Der Controller über den der Wert des Inputfeldes gesetzt
|
||||||
|
/// und ausgelesen werden kann
|
||||||
|
final TextEditingController? controller;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _DateRangePicker();
|
State<StatefulWidget> createState() => _DateRangePicker();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DateRangePicker extends State<DateRangePicker> {
|
class _DateRangePicker extends State<DateRangePicker> {
|
||||||
final ValueNotifier<DateTimeRange?> _value = ValueNotifier(null);
|
final TextEditingController _valueController = TextEditingController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void dispose() {
|
||||||
super.initState();
|
_valueController.dispose();
|
||||||
|
|
||||||
_value.value = widget.initialValue;
|
super.dispose();
|
||||||
_value.addListener(() {
|
|
||||||
widget.onChanged?.call(_value.value);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) => TextField(
|
Widget build(final BuildContext context) => TextField(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
controller: TextEditingController(
|
controller: widget.controller ?? _valueController,
|
||||||
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,
|
|
||||||
),
|
|
||||||
decoration: widget.decoration,
|
decoration: widget.decoration,
|
||||||
onTap: _pickDateRange,
|
onTap: _pickDateRange,
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<void> _pickDateRange() async {
|
Future<void> _pickDateRange() async {
|
||||||
|
final TextEditingController controller =
|
||||||
|
widget.controller ?? _valueController;
|
||||||
|
|
||||||
|
final DateTimeRange<DateTime>? dateTimeRange =
|
||||||
|
DateService.stringToDateTimeRange(controller.text);
|
||||||
|
|
||||||
await DynamicDialog(
|
await DynamicDialog(
|
||||||
title: 'Zeitraum auswählen',
|
title: 'Zeitraum auswählen',
|
||||||
inputFields: [
|
inputFields: [
|
||||||
@@ -72,14 +67,14 @@ class _DateRangePicker extends State<DateRangePicker> {
|
|||||||
label: 'Startdatum',
|
label: 'Startdatum',
|
||||||
keyboardType: TextInputType.datetime,
|
keyboardType: TextInputType.datetime,
|
||||||
inputType: DialogInputFieldTypeEnum.date,
|
inputType: DialogInputFieldTypeEnum.date,
|
||||||
initialValue: _value.value?.start,
|
initialValue: dateTimeRange?.start,
|
||||||
),
|
),
|
||||||
DialogInputField(
|
DialogInputField(
|
||||||
id: 'dateTo',
|
id: 'dateTo',
|
||||||
label: 'Enddatum',
|
label: 'Enddatum',
|
||||||
keyboardType: TextInputType.datetime,
|
keyboardType: TextInputType.datetime,
|
||||||
inputType: DialogInputFieldTypeEnum.date,
|
inputType: DialogInputFieldTypeEnum.date,
|
||||||
initialValue: _value.value?.end,
|
initialValue: dateTimeRange?.end,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
@@ -87,7 +82,8 @@ class _DateRangePicker extends State<DateRangePicker> {
|
|||||||
DialogAction(
|
DialogAction(
|
||||||
label: 'Leeren',
|
label: 'Leeren',
|
||||||
onPressed: (_) {
|
onPressed: (_) {
|
||||||
_value.value = null;
|
controller.text = '';
|
||||||
|
widget.onChanged?.call(null);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
DialogAction(
|
DialogAction(
|
||||||
@@ -98,10 +94,13 @@ class _DateRangePicker extends State<DateRangePicker> {
|
|||||||
values['dateFrom'] is DateTime &&
|
values['dateFrom'] is DateTime &&
|
||||||
values['dateTo'] != null &&
|
values['dateTo'] != null &&
|
||||||
values['dateTo'] is DateTime) {
|
values['dateTo'] is DateTime) {
|
||||||
_value.value = DateTimeRange(
|
final DateTimeRange<DateTime> timeRange = DateTimeRange(
|
||||||
start: values['dateFrom'],
|
start: values['dateFrom'],
|
||||||
end: values['dateTo'],
|
end: values['dateTo'],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
controller.text = DateService.dateTimeRangeToString(timeRange)!;
|
||||||
|
widget.onChanged?.call(timeRange);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:date_field/date_field.dart';
|
import 'package:date_field/date_field.dart';
|
||||||
import 'package:flutter/material.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
|
/// Ein Feld mit Popup über welches man Datumsfelder auswählen kann
|
||||||
class DynamicDateTimeField extends StatefulWidget {
|
class DynamicDateTimeField extends StatefulWidget {
|
||||||
@@ -45,7 +46,7 @@ class _DynamicDateTimeFieldState extends State<DynamicDateTimeField> {
|
|||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) => DateTimeField(
|
Widget build(final BuildContext context) => DateTimeField(
|
||||||
initialPickerDateTime: widget.initialValue,
|
initialPickerDateTime: widget.initialValue,
|
||||||
dateFormat: DateFormat('d.M.y'),
|
dateFormat: DateService.dateFormat,
|
||||||
value: _value,
|
value: _value,
|
||||||
mode: widget.mode,
|
mode: widget.mode,
|
||||||
autofocus: widget.autofocus,
|
autofocus: widget.autofocus,
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class _MonthlyBalanceChart extends State<MonthlyBalanceChart> {
|
|||||||
amountMin: widget.amountMin,
|
amountMin: widget.amountMin,
|
||||||
amountMax: widget.amountMax,
|
amountMax: widget.amountMax,
|
||||||
dateFrom: widget.dateFrom,
|
dateFrom: widget.dateFrom,
|
||||||
dateTo: widget.dateTo,
|
dateTo: (widget.dateTo != null) ? widget.dateTo : DateTime.now(),
|
||||||
),
|
),
|
||||||
builder:
|
builder:
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:routemaster/routemaster.dart';
|
import 'package:routemaster/routemaster.dart';
|
||||||
|
|
||||||
|
import '../../Services/date_service.dart';
|
||||||
import '../Misc/InputFields/date_range_picker.dart';
|
import '../Misc/InputFields/date_range_picker.dart';
|
||||||
|
|
||||||
/// Stellt die Inputfelder für die Verlaufsübersicht dar
|
/// Stellt die Inputfelder für die Verlaufsübersicht dar
|
||||||
@@ -13,7 +14,6 @@ class InputFields extends StatefulWidget {
|
|||||||
this.dateFrom,
|
this.dateFrom,
|
||||||
this.dateTo,
|
this.dateTo,
|
||||||
this.name,
|
this.name,
|
||||||
this.onChanged,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Der Name der Transaktion, nach der gesucht werden soll
|
/// 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
|
///Das Datum der Transaktionen, bis zu welchen beendet wurde
|
||||||
final DateTime? dateTo;
|
final DateTime? dateTo;
|
||||||
|
|
||||||
/// Die Funktion, die bei Veränderung eines Wertes aufgerufen wird
|
|
||||||
final Function()? onChanged;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _InputFields();
|
State<StatefulWidget> createState() => _InputFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _InputFields extends State<InputFields> {
|
class _InputFields extends State<InputFields> {
|
||||||
String? _name;
|
final TextEditingController _nameController = TextEditingController();
|
||||||
double? _amountMin;
|
final TextEditingController _amountMinController = TextEditingController();
|
||||||
double? _amountMax;
|
final TextEditingController _amountMaxController = TextEditingController();
|
||||||
DateTimeRange? _dateTimeRange;
|
final TextEditingController _dateTimeController = TextEditingController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
_name = widget.name;
|
if (widget.name != null) {
|
||||||
_amountMin = widget.amountMin;
|
_nameController.text = widget.name!;
|
||||||
_amountMax = widget.amountMax;
|
}
|
||||||
|
|
||||||
|
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) {
|
if (widget.dateFrom != null && widget.dateTo != null) {
|
||||||
_dateTimeRange = DateTimeRange(
|
final DateTimeRange dateTimeRange = DateTimeRange(
|
||||||
start: widget.dateFrom!,
|
start: widget.dateFrom!,
|
||||||
end: widget.dateTo!,
|
end: widget.dateTo!,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
_dateTimeController.text = DateService.dateTimeRangeToString(
|
||||||
|
dateTimeRange,
|
||||||
|
)!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_nameController.dispose();
|
||||||
|
_amountMinController.dispose();
|
||||||
|
_amountMaxController.dispose();
|
||||||
|
_dateTimeController.dispose();
|
||||||
|
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(final BuildContext context) {
|
Widget build(final BuildContext context) {
|
||||||
final ThemeData theme = Theme.of(context);
|
final ThemeData theme = Theme.of(context);
|
||||||
@@ -68,12 +87,12 @@ class _InputFields extends State<InputFields> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
controller: _nameController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Name',
|
labelText: 'Name',
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
),
|
),
|
||||||
onChanged: (final String value) {
|
onChanged: (final String value) {
|
||||||
_name = value;
|
|
||||||
_updateUrl();
|
_updateUrl();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -81,13 +100,13 @@ class _InputFields extends State<InputFields> {
|
|||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
controller: _amountMinController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Min Betrag €',
|
labelText: 'Min Betrag €',
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
),
|
),
|
||||||
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
||||||
onChanged: (final String value) {
|
onChanged: (final String value) {
|
||||||
_amountMin = double.tryParse(value);
|
|
||||||
_updateUrl();
|
_updateUrl();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -95,13 +114,13 @@ class _InputFields extends State<InputFields> {
|
|||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
controller: _amountMaxController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Max Betrag €',
|
labelText: 'Max Betrag €',
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
),
|
),
|
||||||
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
||||||
onChanged: (final String value) {
|
onChanged: (final String value) {
|
||||||
_amountMax = double.tryParse(value);
|
|
||||||
_updateUrl();
|
_updateUrl();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -109,9 +128,8 @@ class _InputFields extends State<InputFields> {
|
|||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DateRangePicker(
|
child: DateRangePicker(
|
||||||
initialValue: _dateTimeRange,
|
controller: _dateTimeController,
|
||||||
onChanged: (final DateTimeRange? value) {
|
onChanged: (final DateTimeRange? value) {
|
||||||
_dateTimeRange = value;
|
|
||||||
_updateUrl();
|
_updateUrl();
|
||||||
},
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@@ -127,10 +145,10 @@ class _InputFields extends State<InputFields> {
|
|||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_name = null;
|
_nameController.text = '';
|
||||||
_amountMin = null;
|
_amountMinController.text = '';
|
||||||
_amountMax = null;
|
_amountMaxController.text = '';
|
||||||
_dateTimeRange = null;
|
_dateTimeController.text = '';
|
||||||
|
|
||||||
_updateUrl();
|
_updateUrl();
|
||||||
},
|
},
|
||||||
@@ -142,18 +160,24 @@ class _InputFields extends State<InputFields> {
|
|||||||
|
|
||||||
void _updateUrl() {
|
void _updateUrl() {
|
||||||
final params = <String, String>{
|
final params = <String, String>{
|
||||||
if (_name != null && _name != '') 'name': _name!,
|
if (_nameController.text != '') 'name': _nameController.text,
|
||||||
if (_amountMin != null) 'amountMin': _amountMin!.toString(),
|
if (_amountMinController.text != '')
|
||||||
if (_amountMax != null) 'amountMax': _amountMax!.toString(),
|
'amountMin': _amountMinController.text,
|
||||||
|
if (_amountMaxController.text != '')
|
||||||
|
'amountMax': _amountMaxController.text,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_dateTimeRange != null) {
|
if (_dateTimeController.text != '') {
|
||||||
params['dateFrom'] = _dateTimeRange!.start.toIso8601String();
|
final DateTimeRange<DateTime>? range = DateService.stringToDateTimeRange(
|
||||||
params['dateTo'] = _dateTimeRange!.end.toIso8601String();
|
_dateTimeController.text,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (range != null) {
|
||||||
|
params['dateFrom'] = range.start.toIso8601String();
|
||||||
|
params['dateTo'] = range.end.toIso8601String();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Routemaster.of(context).replace('/trend', queryParameters: params);
|
Routemaster.of(context).replace('/trend', queryParameters: params);
|
||||||
|
|
||||||
widget.onChanged?.call();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,8 +62,9 @@ class _TransactionListState extends State<TransactionList> {
|
|||||||
amountMin: widget.amountMin,
|
amountMin: widget.amountMin,
|
||||||
amountMax: widget.amountMax,
|
amountMax: widget.amountMax,
|
||||||
dateFrom: widget.dateFrom,
|
dateFrom: widget.dateFrom,
|
||||||
dateTo: widget.dateTo,
|
dateTo: (widget.dateTo != null) ? widget.dateTo : DateTime.now(),
|
||||||
account: _accountController.selected.value,
|
account: _accountController.selected.value,
|
||||||
|
orderBy: 'dateDesc',
|
||||||
),
|
),
|
||||||
builder:
|
builder:
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -44,9 +44,6 @@ class _TrendState extends State<Trend> {
|
|||||||
amountMax: amountMax,
|
amountMax: amountMax,
|
||||||
dateFrom: dateFrom,
|
dateFrom: dateFrom,
|
||||||
dateTo: dateTo,
|
dateTo: dateTo,
|
||||||
onChanged: () {
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user