From 4c4a08a5b36a9f69c06443316698820e25bcb08c Mon Sep 17 00:00:00 2001 From: Gaspard Merten Date: Wed, 9 Nov 2022 12:46:06 +0100 Subject: [PATCH 1/7] Adding click pointer for desktop and web --- CHANGELOG.md | 4 ++++ lib/src/field.dart | 17 ++++++++++------- pubspec.yaml | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d56686a..92e11fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +##3.0.2 + +* Adding click pointer for desktop and web + ##3.0.1 * Fixing [issue #29](https://github.com/GaspardMerten/date_field/issues/29) -> adding 24h format support for material time picker dialog diff --git a/lib/src/field.dart b/lib/src/field.dart index 9d9fc55..d9adfb8 100644 --- a/lib/src/field.dart +++ b/lib/src/field.dart @@ -333,14 +333,17 @@ class _InputDropdown extends StatelessWidget { suffixIcon: Icon(Icons.arrow_drop_down), ); - return GestureDetector( - onTap: onPressed, - child: InputDecorator( - decoration: effectiveDecoration.applyDefaults( - Theme.of(context).inputDecorationTheme, + return MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: onPressed, + child: InputDecorator( + decoration: effectiveDecoration.applyDefaults( + Theme.of(context).inputDecorationTheme, + ), + isEmpty: isEmpty, + child: text == null ? null : Text(text!, style: textStyle), ), - isEmpty: isEmpty, - child: text == null ? null : Text(text!, style: textStyle), ), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 1fc091a..7a00e06 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: date_field description: A widget in the form of a field that lets people choose a date, a time or both. -version: 3.0.1 +version: 3.0.2 homepage: 'https://github.com/GaspardMerten/date_field' environment: From f843d7034ab032fa52288fdc540c698cb10a14d8 Mon Sep 17 00:00:00 2001 From: schalky Date: Tue, 29 Nov 2022 20:09:40 -0800 Subject: [PATCH 2/7] support for providing a different initial time mode --- lib/src/field.dart | 17 ++++++++++++----- lib/src/form_field.dart | 2 ++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/src/field.dart b/lib/src/field.dart index d9adfb8..2511fb6 100644 --- a/lib/src/field.dart +++ b/lib/src/field.dart @@ -24,6 +24,7 @@ typedef DateTimeFieldCreator = DateTimeField Function({ DateTime? lastDate, DateTimeFieldPickerMode mode, bool use24hFormat, + TimePickerEntryMode initialTimePickerEntryMode, }); /// [DateTimeField] @@ -47,6 +48,7 @@ class DateTimeField extends StatelessWidget { DateTime? firstDate, DateTime? lastDate, DateFormat? dateFormat, + this.initialTimePickerEntryMode = TimePickerEntryMode.dial, }) : dateFormat = dateFormat ?? getDateFormatFromDateFieldPickerMode(mode), firstDate = firstDate ?? _kDefaultFirstSelectableDate, lastDate = lastDate ?? _kDefaultLastSelectableDate, @@ -62,6 +64,7 @@ class DateTimeField extends StatelessWidget { this.dateTextStyle, this.use24hFormat = false, this.initialEntryMode = DatePickerEntryMode.calendar, + this.initialTimePickerEntryMode = TimePickerEntryMode.dial, DateTime? firstDate, DateTime? lastDate, }) : initialDatePickerMode = null, @@ -110,6 +113,9 @@ class DateTimeField extends StatelessWidget { /// The initial entry mode for the material date picker dialog final DatePickerEntryMode initialEntryMode; + // the initial entry mode for the material time picker dialog + final TimePickerEntryMode initialTimePickerEntryMode; + /// Shows a dialog asking the user to pick a date ! Future _selectDate(BuildContext context) async { final DateTime initialDateTime; @@ -158,8 +164,9 @@ class DateTimeField extends StatelessWidget { ]; if (modesWithTime.contains(mode)) { - final TimeOfDay? _selectedTime = - await showMaterialTimePicker(context, initialDateTime); + final TimeOfDay? _selectedTime = await showMaterialTimePicker( + context, initialDateTime, + initialEntryMode: initialTimePickerEntryMode); if (_selectedTime != null) { _selectedDateTime = DateTime( @@ -179,12 +186,12 @@ class DateTimeField extends StatelessWidget { /// Launches the Material time picker by invoking [showTimePicker]. /// Can be @[override]n to allow further customization of the picker options Future showMaterialTimePicker( - BuildContext context, - DateTime initialDateTime, - ) async { + BuildContext context, DateTime initialDateTime, + {TimePickerEntryMode initialEntryMode = TimePickerEntryMode.dial}) async { return showTimePicker( initialTime: TimeOfDay.fromDateTime(initialDateTime), context: context, + initialEntryMode: initialEntryMode, builder: (BuildContext context, Widget? child) { return MediaQuery( data: MediaQuery.of(context).copyWith( diff --git a/lib/src/form_field.dart b/lib/src/form_field.dart index d11a4ff..93770d8 100644 --- a/lib/src/form_field.dart +++ b/lib/src/form_field.dart @@ -30,6 +30,7 @@ class DateTimeFormField extends FormField { DatePickerEntryMode initialEntryMode = DatePickerEntryMode.calendar, DatePickerMode initialDatePickerMode = DatePickerMode.day, DateTimeFieldPickerMode mode = DateTimeFieldPickerMode.dateAndTime, + TimePickerEntryMode initialTimePickerEntryMode = TimePickerEntryMode.dial, DateTimeFieldCreator fieldCreator = DateTimeField.new, }) : super( key: key, @@ -68,6 +69,7 @@ class DateTimeFormField extends FormField { mode: mode, initialEntryMode: initialEntryMode, dateTextStyle: dateTextStyle, + initialTimePickerEntryMode: initialTimePickerEntryMode, ); }, ); From 6e62a13d8f99160dee2f36c6fc4c53d351b992e3 Mon Sep 17 00:00:00 2001 From: Gaspard Merten Date: Wed, 25 Jan 2023 13:48:51 +0100 Subject: [PATCH 3/7] Oups --- lib/src/field.dart | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/src/field.dart b/lib/src/field.dart index d9adfb8..3bf5e29 100644 --- a/lib/src/field.dart +++ b/lib/src/field.dart @@ -1,5 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; final DateTime _kDefaultFirstSelectableDate = DateTime(1900); @@ -296,7 +297,7 @@ DateFormat getDateFormatFromDateFieldPickerMode(DateTimeFieldPickerMode mode) { /// Shows a field with a dropdown arrow ! /// It does not show any popup menu, it'll just trigger onPressed whenever the /// user does click on it ! -class _InputDropdown extends StatelessWidget { +class _InputDropdown extends StatefulWidget { const _InputDropdown({ Key? key, required this.text, @@ -326,9 +327,16 @@ class _InputDropdown extends StatelessWidget { /// Defaults to false. final bool isEmpty; + @override + State<_InputDropdown> createState() => _InputDropdownState(); +} + +class _InputDropdownState extends State<_InputDropdown> { + bool focused = false; + @override Widget build(BuildContext context) { - final InputDecoration effectiveDecoration = decoration ?? + final InputDecoration effectiveDecoration = widget.decoration ?? const InputDecoration( suffixIcon: Icon(Icons.arrow_drop_down), ); @@ -336,13 +344,28 @@ class _InputDropdown extends StatelessWidget { return MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( - onTap: onPressed, - child: InputDecorator( - decoration: effectiveDecoration.applyDefaults( - Theme.of(context).inputDecorationTheme, + onTap: widget.onPressed, + child: Focus( + onFocusChange: (bool newFocus) => setState(() { + focused = newFocus; + }), + onKey: (_, RawKeyEvent key) { + if (key.isKeyPressed(LogicalKeyboardKey.space)) { + widget.onPressed?.call(); + return KeyEventResult.handled; + } + return KeyEventResult.ignored; + }, + child: InputDecorator( + isHovering: focused, + decoration: effectiveDecoration.applyDefaults( + Theme.of(context).inputDecorationTheme, + ), + isEmpty: widget.isEmpty, + child: widget.text == null + ? null + : Text(widget.text!, style: widget.textStyle), ), - isEmpty: isEmpty, - child: text == null ? null : Text(text!, style: textStyle), ), ), ); From 600608cde8ed41dcf9266a65abefa03f4c86d032 Mon Sep 17 00:00:00 2001 From: Gaspard Merten Date: Wed, 12 Apr 2023 10:16:47 +0200 Subject: [PATCH 4/7] Updating readme --- CHANGELOG.md | 147 ++++++++++++++++++++---------------------- README.md | 73 ++++++++++++--------- example/.gitignore | 1 - example/lib/main.dart | 1 + pubspec.yaml | 2 +- 5 files changed, 117 insertions(+), 107 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92e11fc..d03005b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,134 +1,129 @@ -##3.0.2 +# 3.0.4 -* Adding click pointer for desktop and web +- Updating Changelog.md -##3.0.1 +# 3.0.3 -* Fixing [issue #29](https://github.com/GaspardMerten/date_field/issues/29) -> adding 24h format support for material time picker dialog +- Updating the README.md file. Adding more information about the package, rewriting the text to make it more appealing. +- Adding support for providing a different initial time mode for the material time picker dialog (thanks to @schalky). -##3.0.0 +# 3.0.2 -* Breaking Upgraded minimum Dart version to 2.15 for Constructor Tearoff support -* Added optional `DateTimeFieldCreator` argument to `DateTimeFormField` to allow specifying custom implementations of `DateTimeField` -* Refactored `DateTimeField` to expose `showMaterialTimePicker`, `showMaterialDatePicker`, and `showMaterialTimePicker` as separate overrideable methods -* Made `kCupertinoDatePickerHeight` and `cupertinoModeFromPickerMode` public for convenience -* Removed `DateTimeFormFieldState`, replaced by an instance of `FormFieldState` -* Fixed the behaviour of the `initialDate' parameter. +Added support for clickable pointer on desktop and web. -##2.1.3 +# 3.0.1 -* [TheGlorySaint](https://github.com/TheGlorySaint) added the possibility to use the 24Hour Format at the Timepicker. Default it is set to false +Fixed issue #29 by adding 24-hour format support for the material time picker dialog. -##2.1.2 +# 3.0.0 -* Adding the possibility to specify the initial date selected in the date picker dialog. +Upgraded the minimum Dart version to 2.15 for constructor tear-off support, which is a breaking change. +Added an optional DateTimeFieldCreator argument to DateTimeFormField for specifying custom implementations of DateTimeField. +Refactored DateTimeField to expose showMaterialTimePicker, showMaterialDatePicker, and showMaterialTimePicker as separate overrideable methods. +Made kCupertinoDatePickerHeight and cupertinoModeFromPickerMode public for convenience. +Removed DateTimeFormFieldState and replaced it with an instance of FormFieldState. +Fixed the behavior of the initialDate parameter. -##2.1.1 +# 2.1.3 -* Formatting with Dart FM +Added the possibility to use the 24-hour format for the time picker. Default is set to false. -##2.1.0 +# 2.1.2 -* Fixing label & hint style issues -* Moving to a more generic architecture -* Updating the analysis_options.yaml file +Added the ability to specify the initial date selected in the date picker dialog. -##2.0.1 +# 2.1.1 -* Adding the ability to specify the entry mode for the material date picker. +Formatted code with Dart FM. -##2.0.0 +# 2.1.0 -* Migrating to null-safety +Fixed label and hint style issues. +Moved to a more generic architecture. +Updated the analysis_options.yaml file. +# 2.0.1 -##1.0.5 +Added the ability to specify the entry mode for the material date picker. -* Removing unused variables -* Improving description +# 2.0.0 +Migrated to null-safety. -##1.0.4 +# 1.0.5 -* Fixing critical issue +Removed unused variables and improved the description. -##1.0.3 +# 1.0.4 -* Improving package description +Fixed a critical issue. -##1.0.2 +# 1.0.3 -* Improving package description +Improved the package description. -##1.0.1 +# 1.0.2 -* Removing the ripple effect +Improved the package description. -##1.0.0 +# 1.0.1 -* Full support for input decoration -* New standardized usage, many deprecations +Removed the ripple effect. -##0.3.3 +# 1.0.0 -* Intl => any support +Added full support for input decoration. +Adopted a new standardized usage, with many deprecations. -Breaking change: -* Removing the label property, please consider using the InputDecoration to customize the label. +# 0.3.3 -##0.3.2 +Changed support from Intl to any, which is a breaking change. +Removed the label property, and suggested using the InputDecoration to customize the label. -* Formating with dartfm +# 0.3.2 -##0.3.1 +Formatted the code with Dart FM. -* Adding the possibility to style the text with TextStyle +# 0.3.1 -## 0.3.0 +Added the possibility to style the text with TextStyle. -Breaking changes: -* No more const constructor. +# 0.3.0 -Deprecated: -* DateField and DateFormField are now deprecated and will be removed in the next version, please consider switching to - DateTimeField and DateTimeFormField. +Removed the const constructor, which is a breaking change. +Deprecated DateField and DateFormField, and added support for time. +Improved performance by setting the default value in the constructor. +Added a .time constructor for the DateField widget only. -Improvements: -* Adding support for time. Now you can ask the user for a time, a date or both. -* Improving performances by setting default value in the constructor. -* Adding .time constructor for the DateField widget only. +# 0.2.2 -## 0.2.2 +Formatted the code with dart-fm to meet pub.dev requirements. -* Auto-formatting with dart-fm to meet pub.dev requirements +# 0.2.1 -## 0.2.1 +Added support for Flutter web. -* Adding support for Flutter web +# 0.2.0 -## 0.2.0 +Changed DateFormField to extend FormField, and rigorously applied the style to match the theme or any customization. -* DateFormField now extends FormField. All issues related to this are now fiex -* The style of the DateField (and by extension the one of DateFormField) is now rigorously applying the theme or any customization. +# 0.1.2 -## 0.1.2 +Fixed an incorrect boolean value (the iOS picker was inverted with the Android one). -* Fixing an incorrect boolean (iOS picker was inverted with the Android one) +# 0.1.1 -## 0.1.1 +Formatted the code with DartFM. -* Formatting with DartFM! +# 0.1.0 -## 0.1.0 +Updated the documentation. -* Updating documentation! +# 0.0.2 -## 0.0.2 +Fixed the README.md and updated the package description. +Formatted the code with DartFM. -* Fixing README.md -* Updating package description -* Formatting with DartFM - -## 0.0.1 +# 0.0.1 * Initial version diff --git a/README.md b/README.md index f5829db..82dbce2 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,12 @@ -# date_field +# Welcome to the Date Field package! 📅 -[![pub package](https://img.shields.io/pub/v/date_field.svg)](https://pub.dartlang.org/packages/date_field) +[![pub package](https://img.shields.io/pub/v/date_field.svg)](https://pub.dev/packages/date_field) +This package provides two widgets, DateTimeField and DateTimeFormField, which allow users to pick a date and/or time from an input field. You can customize the appearance of the widgets using the decoration argument, and specify whether to ask for a date, a time, or both using the mode parameter. -Contains DateTimeField and DateTimeFormField which allows the user to pick a DateTime from an input field! Depending on -the mode, it can ask the user the time, the date or both at the same time ;) ! +## Here's how to get started 🚀 - - -## Usage - -In the `pubspec.yaml` of your flutter project, add the following dependency: +Add the date_field package to your project's dependencies in pubspec.yaml. ```yaml dependencies: @@ -18,34 +14,41 @@ dependencies: date_field: ^3.0.0 ``` -In your library add the following import: + +Import the package in your Dart code. ```dart import 'package:date_field/date_field.dart'; ``` +Use the DateTimeField or DateTimeFormField widget in your code, and customize it using the available parameters. -## Getting Started +## Available Parameters 📝 -There are two widgets in this package: +- onSaved: a callback that is called when the form is saved. +- validator: a callback that is called to validate the value. +- initialValue: the initial value of the field. +- autovalidateMode: when to validate the field. +- enabled: whether the field is enabled or disabled. +- use24hFormat: whether to use a 24-hour format for the time picker. +- dateTextStyle: the text style for the date. +- dateFormat: the format of the date. +- firstDate: the earliest date that can be selected. +- lastDate: the latest date that can be selected. +- initialDate: the initial date that is selected. +- onDateSelected: a callback that is called when a date is selected. +- decoration: the decoration for the field. +- initialEntryMode: the initial entry mode of the date picker. +- initialDatePickerMode: the initial date picker mode. +- mode: the mode of the date and time picker. +- initialTimePickerEntryMode: the initial entry mode of the time picker. +- fieldCreator: the creator of the DateTimeField. -- DateTimeField -- DateTimeFormField +## Example Usage 📖 -It follows the usual Flutter patterns convention, meaning the DateTimeFormField extends the FormField widget and wraps a DateTimeField widget. +Here's an example usage of DateTimeFormField: -You can customize both of these widgets with the decoration argument which is fully supported. - -You can also specify whether you would like to ask the user for a date, a time or both using the mode parameter. - -## Example - -The following picture illustrates some things you can do with this package. - - - - -``` dart +```dart DateTimeFormField( decoration: const InputDecoration( hintStyle: TextStyle(color: Colors.black45), @@ -60,7 +63,19 @@ DateTimeFormField( onDateSelected: (DateTime value) { print(value); }, -), +) ``` -You can check the GitHub repo for a complete example. \ No newline at end of file +You can find more examples and a complete example on the GitHub repository. We hope this package is helpful to you! + +## License 📜 + +This package is released under the MIT license. + +## Contributing 🤝 + +Contributions to this package are welcome! If you find a bug or have a feature request, please create an issue on the GitHub repository. If you'd like to contribute code, please create a pull request with your changes. + +Before submitting a pull request, please make sure to run the tests and ensure they all pass. Additionally, please follow the existing coding style and make sure your code is well-documented. + +Thank you for your contributions! \ No newline at end of file diff --git a/example/.gitignore b/example/.gitignore index 0fa6b67..a1345d0 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -32,7 +32,6 @@ /build/ # Web related -lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols diff --git a/example/lib/main.dart b/example/lib/main.dart index 5b54c39..7ceb620 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -65,6 +65,7 @@ class _MyHomePageState extends State { Form( child: Column( children: [ + DateTimeFormField(), DateTimeFormField( decoration: const InputDecoration( hintStyle: TextStyle(color: Colors.black45), diff --git a/pubspec.yaml b/pubspec.yaml index 7a00e06..b43af9d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: date_field description: A widget in the form of a field that lets people choose a date, a time or both. -version: 3.0.2 +version: 3.0.4 homepage: 'https://github.com/GaspardMerten/date_field' environment: From f0f2dc025d8a3af6830f388ab2d978b95420eaf9 Mon Sep 17 00:00:00 2001 From: Gaspard Merten Date: Wed, 12 Apr 2023 17:00:42 +0200 Subject: [PATCH 5/7] Bumping intl to 0.18.0 --- CHANGELOG.md | 4 ++++ README.md | 2 +- pubspec.yaml | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d03005b..52b1571 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.0.5 + +- Bumping intl to 0.18.0 + # 3.0.4 - Updating Changelog.md diff --git a/README.md b/README.md index 82dbce2..8c10310 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Add the date_field package to your project's dependencies in pubspec.yaml. ```yaml dependencies: ... - date_field: ^3.0.0 + date_field: ^3.0.5 ``` diff --git a/pubspec.yaml b/pubspec.yaml index b43af9d..e9065d0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: date_field description: A widget in the form of a field that lets people choose a date, a time or both. -version: 3.0.4 +version: 3.0.5 homepage: 'https://github.com/GaspardMerten/date_field' environment: @@ -10,5 +10,5 @@ dependencies: flutter: sdk: flutter - intl: ^0.17.0 + intl: ^0.18.0 From 9ee7a69f5dfd89be7bbd4858215d97345b32fee5 Mon Sep 17 00:00:00 2001 From: torbenkeller Date: Thu, 17 Aug 2023 17:01:44 +0200 Subject: [PATCH 6/7] fixes #42 dense empty form field --- CHANGELOG.md | 4 ++++ lib/src/field.dart | 2 +- pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52b1571..32a5554 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 3.0.6 + +- Fixing issue #42 dense empty form field + # 3.0.5 - Bumping intl to 0.18.0 diff --git a/lib/src/field.dart b/lib/src/field.dart index fa65066..aa8c6b9 100644 --- a/lib/src/field.dart +++ b/lib/src/field.dart @@ -370,7 +370,7 @@ class _InputDropdownState extends State<_InputDropdown> { ), isEmpty: widget.isEmpty, child: widget.text == null - ? null + ? Text('', style: widget.textStyle) : Text(widget.text!, style: widget.textStyle), ), ), diff --git a/pubspec.yaml b/pubspec.yaml index e9065d0..540005e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: date_field description: A widget in the form of a field that lets people choose a date, a time or both. -version: 3.0.5 +version: 3.0.6 homepage: 'https://github.com/GaspardMerten/date_field' environment: From c8214efdb9356620cabf24e25715ff28891511dd Mon Sep 17 00:00:00 2001 From: Dominic Grimm Date: Sat, 16 Dec 2023 18:52:38 +0100 Subject: [PATCH 7/7] Add controller support --- lib/src/field.dart | 21 +++++++-------------- lib/src/form_field.dart | 25 ++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/lib/src/field.dart b/lib/src/field.dart index aa8c6b9..28dff95 100644 --- a/lib/src/field.dart +++ b/lib/src/field.dart @@ -133,23 +133,20 @@ class DateTimeField extends StatelessWidget { } if (Theme.of(context).platform == TargetPlatform.iOS) { - final DateTime? _selectedDateTime = - await showCupertinoPicker(context, initialDateTime); + final DateTime? _selectedDateTime = await showCupertinoPicker(context, initialDateTime); if (_selectedDateTime != null) { onDateSelected!(_selectedDateTime); } } else { DateTime _selectedDateTime = initialDateTime; - const List modesWithDate = - [ + const List modesWithDate = [ DateTimeFieldPickerMode.dateAndTime, DateTimeFieldPickerMode.date ]; if (modesWithDate.contains(mode)) { - final DateTime? _selectedDate = - await showMaterialDatePicker(context, initialDateTime); + final DateTime? _selectedDate = await showMaterialDatePicker(context, initialDateTime); if (_selectedDate != null) { _selectedDateTime = _selectedDate; @@ -158,15 +155,13 @@ class DateTimeField extends StatelessWidget { } } - final List modesWithTime = - [ + final List modesWithTime = [ DateTimeFieldPickerMode.dateAndTime, DateTimeFieldPickerMode.time ]; if (modesWithTime.contains(mode)) { - final TimeOfDay? _selectedTime = await showMaterialTimePicker( - context, initialDateTime, + final TimeOfDay? _selectedTime = await showMaterialTimePicker(context, initialDateTime, initialEntryMode: initialTimePickerEntryMode); if (_selectedTime != null) { @@ -186,8 +181,7 @@ class DateTimeField extends StatelessWidget { /// Launches the Material time picker by invoking [showTimePicker]. /// Can be @[override]n to allow further customization of the picker options - Future showMaterialTimePicker( - BuildContext context, DateTime initialDateTime, + Future showMaterialTimePicker(BuildContext context, DateTime initialDateTime, {TimePickerEntryMode initialEntryMode = TimePickerEntryMode.dial}) async { return showTimePicker( initialTime: TimeOfDay.fromDateTime(initialDateTime), @@ -274,8 +268,7 @@ enum DateTimeFieldPickerMode { time, date, dateAndTime } /// Returns the [CupertinoDatePickerMode] corresponding to the selected /// [DateTimeFieldPickerMode]. This exists to prevent redundancy in the [DateTimeField] /// widget parameters. -CupertinoDatePickerMode cupertinoModeFromPickerMode( - DateTimeFieldPickerMode mode) { +CupertinoDatePickerMode cupertinoModeFromPickerMode(DateTimeFieldPickerMode mode) { switch (mode) { case DateTimeFieldPickerMode.time: return CupertinoDatePickerMode.time; diff --git a/lib/src/form_field.dart b/lib/src/form_field.dart index 93770d8..71168cc 100644 --- a/lib/src/form_field.dart +++ b/lib/src/form_field.dart @@ -31,27 +31,37 @@ class DateTimeFormField extends FormField { DatePickerMode initialDatePickerMode = DatePickerMode.day, DateTimeFieldPickerMode mode = DateTimeFieldPickerMode.dateAndTime, TimePickerEntryMode initialTimePickerEntryMode = TimePickerEntryMode.dial, + DateTimeFormFieldController? controller, DateTimeFieldCreator fieldCreator = DateTimeField.new, }) : super( key: key, - initialValue: initialValue, + initialValue: + initialValue == null && controller != null ? controller.selectedDate : initialValue, onSaved: onSaved, validator: validator, autovalidateMode: autovalidateMode, enabled: enabled, builder: (FormFieldState field) { + if (controller != null) { + controller.addListener(() { + field.didChange(controller.selectedDate); + }); + } + // Theme defaults are applied inside the _InputDropdown widget final InputDecoration _decorationWithThemeDefaults = decoration ?? const InputDecoration(); final InputDecoration effectiveDecoration = - _decorationWithThemeDefaults.copyWith( - errorText: field.errorText); + _decorationWithThemeDefaults.copyWith(errorText: field.errorText); void onChangedHandler(DateTime value) { if (onDateSelected != null) { onDateSelected(value); } + if (controller != null) { + controller.selectedDate = value; + } field.didChange(value); } @@ -77,3 +87,12 @@ class DateTimeFormField extends FormField { @override FormFieldState createState() => FormFieldState(); } + +class DateTimeFormFieldController extends ChangeNotifier { + DateTime? _selectedDate; + DateTime? get selectedDate => _selectedDate; + set selectedDate(DateTime? value) { + _selectedDate = value; + notifyListeners(); + } +}