main
1import 'package:blood_pressure_app/features/input/forms/form_base.dart';
2import 'package:blood_pressure_app/model/storage/storage.dart';
3import 'package:flutter/material.dart';
4import 'package:flutter/services.dart';
5import 'package:blood_pressure_app/l10n/app_localizations.dart';
6import 'package:health_data_store/health_data_store.dart';
7import 'package:provider/provider.dart';
8
9/// A form to enter [Weight] in the preferred unit.
10class WeightForm extends FormBase<Weight> {
11 /// Create a form to enter [Weight] in the preferred unit.
12 const WeightForm({super.key, super.initialValue});
13
14 @override
15 FormStateBase<Weight, WeightForm> createState() => WeightFormState();
16}
17
18/// State of a form to enter [Weight] in the preferred unit.
19class WeightFormState extends FormStateBase<Weight, WeightForm> {
20 final TextEditingController _controller = TextEditingController();
21
22 String? _error;
23
24 @override
25 void initState() {
26 super.initState();
27 if (widget.initialValue != null) {
28 final w = context.read<Settings>().weightUnit.extract(widget.initialValue!);
29 _controller.text = w.toString();
30 }
31 }
32
33 @override
34 void dispose() {
35 _controller.dispose();
36 super.dispose();
37 }
38
39 @override
40 bool validate() {
41 if (_controller.text.isNotEmpty && double.tryParse(_controller.text) == null) {
42 setState(() => _error = AppLocalizations.of(context)!.errNaN);
43 return false;
44 }
45 setState(() => _error = null);
46 return true;
47 }
48
49 @override
50 Weight? save() {
51 if((validate(), double.tryParse(_controller.text)) case (true, final double x)) {
52 return context.read<Settings>().weightUnit.store(x);
53 }
54 return null;
55 }
56
57 @override
58 bool isEmptyInputFocused() => false;
59
60 @override
61 void fillForm(Weight? value) {
62 if (value == null) {
63 _controller.text = '';
64 } else {
65 final w = context.read<Settings>().weightUnit.extract(widget.initialValue!);
66 _controller.text = w.toString();
67 }
68 }
69
70 @override
71 Widget build(BuildContext context) => TextField(
72 decoration: InputDecoration(
73 labelText: AppLocalizations.of(context)!.weight,
74 suffix: Text(context.select((Settings s) => s.weightUnit).name),
75 errorText: _error,
76 ),
77 controller: _controller,
78 inputFormatters: [FilteringTextInputFormatter.allow(RegExp('[0-9,.]'))],
79 keyboardType: const TextInputType.numberWithOptions(decimal: true),
80 );
81}