From a83b32bf527bed3550eddbe08bed0dccd664cebe Mon Sep 17 00:00:00 2001 From: Joons Date: Wed, 12 Oct 2022 11:43:37 +0200 Subject: [PATCH] add input date picker --- CHANGELOG.md | 3 +- example/lib/example_pages/age_page.dart | 2 +- example/lib/example_pages/carousel_page.dart | 2 +- example/lib/example_pages/date_page.dart | 42 ++++++++++ example/lib/example_pages/name_page.dart | 2 +- example/lib/form_example.dart | 16 ++++ example/pubspec.lock | 2 +- example/pubspec.yaml | 1 + .../input_date_picker/date_picker.dart | 63 ++++++++++++++ .../input_date_picker/input_date_picker.dart | 83 +++++++++++++++++++ .../input/input_types/input_types.dart | 1 + pubspec.yaml | 4 +- 12 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 example/lib/example_pages/date_page.dart create mode 100644 lib/src/widgets/input/input_types/input_date_picker/date_picker.dart create mode 100644 lib/src/widgets/input/input_types/input_date_picker/input_date_picker.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 70a6ea9..fa4ea98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,10 @@ -## 0.0.1 - September 29th 2022 +## 0.0.2 - October 10th 2022 - Initial release ## 0.0.2 - October 12th 2022 - Added a multi line plain text input widget +- Added date input widget - Ability to set the scrolldirection of the pageview - Ability to set the scrollphysics of the pages' scrollview. diff --git a/example/lib/example_pages/age_page.dart b/example/lib/example_pages/age_page.dart index 83d6c93..66f0f92 100644 --- a/example/lib/example_pages/age_page.dart +++ b/example/lib/example_pages/age_page.dart @@ -25,7 +25,7 @@ class _AgePageState extends State { fontSize: fontSize, title: "What is your age?", pageNumber: 1, - amountOfPages: 3, + amountOfPages: 4, flutterFormWidgets: [ FlutterFormInputNumberPicker( minValue: 12, diff --git a/example/lib/example_pages/carousel_page.dart b/example/lib/example_pages/carousel_page.dart index ac763c4..01d567b 100644 --- a/example/lib/example_pages/carousel_page.dart +++ b/example/lib/example_pages/carousel_page.dart @@ -27,7 +27,7 @@ class _CarouselPageState extends State { fontSize: fontSize, title: "What's your favorite car?", pageNumber: 3, - amountOfPages: 3, + amountOfPages: 4, flutterFormWidgets: [ FlutterFormInputCarousel( controller: widget.inputController, items: getCars()) diff --git a/example/lib/example_pages/date_page.dart b/example/lib/example_pages/date_page.dart new file mode 100644 index 0000000..ee3a498 --- /dev/null +++ b/example/lib/example_pages/date_page.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_form/flutter_form.dart'; +import 'package:form_example/template_page.dart'; +import 'package:intl/intl.dart'; + +class DatePage extends StatefulWidget { + const DatePage({ + required this.dateController, + super.key, + }); + + final FlutterFormInputPlainTextController dateController; + + @override + State createState() => _DatePageState(); +} + +class _DatePageState extends State { + @override + Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + var fontSize = size.height / 40; + + return TemplatePage( + size: size, + fontSize: fontSize, + pageNumber: 4, + amountOfPages: 4, + title: "Please enter a date", + flutterFormWidgets: [ + Padding( + padding: const EdgeInsets.fromLTRB(40, 0, 40, 40), + child: FlutterFormInputDate( + dateFormat: DateFormat.yMd(), + label: const Text("Date"), + controller: widget.dateController, + ), + ), + ], + ); + } +} diff --git a/example/lib/example_pages/name_page.dart b/example/lib/example_pages/name_page.dart index 0b8edcf..d3e2772 100644 --- a/example/lib/example_pages/name_page.dart +++ b/example/lib/example_pages/name_page.dart @@ -28,7 +28,7 @@ class _NamePageState extends State { size: size, fontSize: fontSize, pageNumber: 2, - amountOfPages: 3, + amountOfPages: 4, title: "Please enter your name", flutterFormWidgets: [ Padding( diff --git a/example/lib/form_example.dart b/example/lib/form_example.dart index 0d7c025..92e8723 100644 --- a/example/lib/form_example.dart +++ b/example/lib/form_example.dart @@ -6,6 +6,8 @@ import 'package:form_example/example_pages/carousel_page.dart'; import 'package:form_example/example_pages/check_page.dart'; import 'package:form_example/example_pages/name_page.dart'; +import 'example_pages/date_page.dart'; + class FormExample extends ConsumerStatefulWidget { const FormExample({Key? key}) : super(key: key); @@ -60,6 +62,15 @@ class _FormExampleState extends ConsumerState { }, ); + FlutterFormInputPlainTextController dateController = + FlutterFormInputPlainTextController( + mandatory: true, + id: "date", + checkPageTitle: (dynamic date) { + return "Date: $date"; + }, + ); + @override void initState() { super.initState(); @@ -189,6 +200,11 @@ class _FormExampleState extends ConsumerState { cars: cars, ), ), + FlutterFormPage( + child: DatePage( + dateController: dateController, + ), + ), ], checkPage: CheckPageExample() .showCheckpage(context, size, fontSize, checkPageText), diff --git a/example/pubspec.lock b/example/pubspec.lock index c0b7486..0ae6b69 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -94,7 +94,7 @@ packages: source: sdk version: "0.0.0" intl: - dependency: transitive + dependency: "direct main" description: name: intl url: "https://pub.dartlang.org" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index c13fe9e..2d60953 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -16,6 +16,7 @@ dependencies: flutter_riverpod: ^1.0.4 flutter_form: path: ../ + intl: ^0.17.0 dev_dependencies: diff --git a/lib/src/widgets/input/input_types/input_date_picker/date_picker.dart b/lib/src/widgets/input/input_types/input_date_picker/date_picker.dart new file mode 100644 index 0000000..b3b3686 --- /dev/null +++ b/lib/src/widgets/input/input_types/input_date_picker/date_picker.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_form/utils/translation_service.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:intl/intl.dart'; +import '../../../../../flutter_form.dart'; + +/// Generates a [TextFormField] for passwords. It requires a [FlutterFormInputController] +/// as the [controller] parameter and an optional [Widget] as [label] +class DateInputField extends ConsumerStatefulWidget { + const DateInputField( + {Key? key, + required this.controller, + this.label, + this.showIcon = true, + this.icon = Icons.calendar_today, + required this.dateFormat}) + : super( + key: key, + ); + final FlutterFormInputController controller; + final DateFormat dateFormat; + final bool showIcon; + final IconData icon; + final Widget? label; + @override + ConsumerState createState() => _DateInputFieldState(); +} + +class _DateInputFieldState extends ConsumerState { + @override + Widget build(BuildContext context) { + String Function(String, {List? params}) _ = + getTranslator(context, ref); + + return TextFormField( + key: Key(widget.controller.value.toString()), + initialValue: widget.controller.value, + onSaved: (value) { + widget.controller.onSaved(value); + }, + onTap: () async { + DateTime? pickedDate = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime.now(), + lastDate: DateTime.now().add( + const Duration(days: 2000), + ), + ); + if (pickedDate != null) { + widget.controller.value = widget.dateFormat.format(pickedDate); + setState(() {}); + } + }, + validator: (value) => widget.controller.onValidate(value, _), + decoration: InputDecoration( + suffixIcon: widget.showIcon ? Icon(widget.icon) : null, + focusColor: Theme.of(context).primaryColor, + label: widget.label ?? const Text("Date"), + ), + ); + } +} diff --git a/lib/src/widgets/input/input_types/input_date_picker/input_date_picker.dart b/lib/src/widgets/input/input_types/input_date_picker/input_date_picker.dart new file mode 100644 index 0000000..80d6416 --- /dev/null +++ b/lib/src/widgets/input/input_types/input_date_picker/input_date_picker.dart @@ -0,0 +1,83 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_form/src/widgets/input/input_types/input_date_picker/date_picker.dart'; +import 'package:flutter_form/utils/translation_service.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:intl/intl.dart'; + +import '../../../../../flutter_form.dart'; + +/// Input for a date used in a [FlutterForm]. +/// +/// Standard controller is [FlutterFormInputDateController]. +class FlutterFormInputDate extends FlutterFormInputWidget { + const FlutterFormInputDate( + {Key? key, + required FlutterFormInputController controller, + Widget? label, + this.showIcon = true, + this.icon = Icons.calendar_today, + required this.dateFormat}) + : super( + key: key, + controller: controller, + label: label, + ); + final DateFormat dateFormat; + final bool showIcon; + final IconData icon; + + @override + Widget build(BuildContext context, WidgetRef ref) { + String Function(String, {List? params}) _ = + getTranslator(context, ref); + super.registerController(context); + + return DateInputField(controller: controller, dateFormat: dateFormat); + } +} + +/// Controller for dates used by a [FlutterFormInputWidget] used in a [FlutterForm]. +/// +/// Mainly used by [FlutterFormInputDate]. +class FlutterFormInputDateController + implements FlutterFormInputController { + FlutterFormInputDateController({ + required this.id, + this.mandatory = true, + this.value, + this.checkPageTitle, + this.checkPageDescription, + }); + + @override + String? id; + + @override + String? value; + + @override + bool mandatory; + + @override + String Function(String value)? checkPageTitle; + + @override + String Function(String value)? checkPageDescription; + + @override + void onSaved(dynamic value) { + this.value = value; + } + + @override + String? onValidate(String? value, + String Function(String, {List? params}) translator) { + if (mandatory) { + if (value == null || value.isEmpty) { + return translator('shell.form.error.empty'); + } + } + + return null; + } +} diff --git a/lib/src/widgets/input/input_types/input_types.dart b/lib/src/widgets/input/input_types/input_types.dart index 8920d92..2966836 100644 --- a/lib/src/widgets/input/input_types/input_types.dart +++ b/lib/src/widgets/input/input_types/input_types.dart @@ -4,3 +4,4 @@ export 'input_number_picker/input_number_picker.dart'; export 'input_password/input_password.dart'; export 'input_plain_text.dart'; export 'input_slider/input_slider.dart'; +export 'input_date_picker/input_date_picker.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index 6cf096c..90f7de4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,7 +6,7 @@ homepage: publish_to: none environment: - sdk: '>=2.18.0 <3.0.0' + sdk: ">=2.18.0 <3.0.0" flutter: ">=1.17.0" dependencies: @@ -15,8 +15,8 @@ dependencies: flutter_localizations: sdk: flutter flutter_riverpod: ^1.0.4 + intl: ^0.17.0 localization: ^2.1.0 - sliding_up_panel: ^2.0.0+1 uuid: ^3.0.6