diff --git a/example/lib/example_pages/date_page.dart b/example/lib/example_pages/date_page.dart index ee3a498..169e946 100644 --- a/example/lib/example_pages/date_page.dart +++ b/example/lib/example_pages/date_page.dart @@ -30,8 +30,10 @@ class _DatePageState extends State { flutterFormWidgets: [ Padding( padding: const EdgeInsets.fromLTRB(40, 0, 40, 40), - child: FlutterFormInputDate( + child: FlutterFormInputDateTime( + inputType: FlutterFormDateTimeType.dateTime, dateFormat: DateFormat.yMd(), + firstDate: DateTime.now(), label: const Text("Date"), controller: widget.dateController, ), 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 index b3b3686..f651353 100644 --- 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 @@ -1,56 +1,122 @@ +import 'dart:async'; + 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( +/// Generates a [DateTimeInputField] for DateTimes/Dates/Times/DateRanges. +/// It requires a [FlutterFormInputController], [inputType], [dateFormat], [firstDate], and [lastDate] +class DateTimeInputField extends ConsumerStatefulWidget { + const DateTimeInputField({ + Key? key, + required this.inputType, + required this.controller, + this.label, + this.showIcon = true, + this.icon = Icons.calendar_today, + required this.dateFormat, + required this.firstDate, + required this.lastDate, + }) : super( key: key, ); + final FlutterFormDateTimeType inputType; final FlutterFormInputController controller; final DateFormat dateFormat; final bool showIcon; + final DateTime? firstDate; + final DateTime? lastDate; final IconData icon; final Widget? label; @override - ConsumerState createState() => _DateInputFieldState(); + ConsumerState createState() => _DateInputFieldState(); } -class _DateInputFieldState extends ConsumerState { +class _DateInputFieldState extends ConsumerState { + late final DateTime firstDate; + late final DateTime lastDate; + + @override + void initState() { + firstDate = widget.firstDate ?? + DateTime.now().subtract( + const Duration(days: 1000), + ); + lastDate = widget.lastDate ?? + DateTime.now().add( + const Duration(days: 1000), + ); + + super.initState(); + } + @override Widget build(BuildContext context) { String Function(String, {List? params}) _ = getTranslator(context, ref); + Future getInputFromUser(FlutterFormDateTimeType inputType) async { + String userInput = ''; + switch (inputType) { + case FlutterFormDateTimeType.date: + DateTime? unformatted = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: firstDate, + lastDate: lastDate, + ); + userInput = unformatted != null + ? widget.dateFormat.format(unformatted) + : userInput; + break; + case FlutterFormDateTimeType.dateTime: + await getInputFromUser(FlutterFormDateTimeType.date) + .then((value) async { + if (value != '') { + String secondInput = + await getInputFromUser(FlutterFormDateTimeType.time); + if (secondInput != '') { + userInput = '$value $secondInput'; + } + } + }); + break; + case FlutterFormDateTimeType.range: + userInput = (await showDateRangePicker( + context: context, + firstDate: firstDate, + lastDate: lastDate, + ).then((value) { + return value != null + ? '${widget.dateFormat.format(value.start)} - ${widget.dateFormat.format(value.end)}' + : ''; + })) + .toString(); + break; + case FlutterFormDateTimeType.time: + userInput = await showTimePicker( + context: context, initialTime: TimeOfDay.now()) + .then((value) => value == null ? '' : value.format(context)); + } + return userInput; + } + return TextFormField( + keyboardType: TextInputType.none, + readOnly: true, 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(() {}); - } + String userInput = await getInputFromUser(widget.inputType); + setState(() { + widget.controller.value = + userInput != '' ? userInput : widget.controller.value; + }); }, validator: (value) => widget.controller.onValidate(value, _), decoration: InputDecoration( 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 index 80d6416..02d7203 100644 --- 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 @@ -6,24 +6,38 @@ import 'package:intl/intl.dart'; import '../../../../../flutter_form.dart'; -/// Input for a date used in a [FlutterForm]. +/// Select Input Types in a [FlutterFormInputDateTime] +enum FlutterFormDateTimeType { + date, + time, + dateTime, + range, +} + +/// Input for a dateTime 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( +class FlutterFormInputDateTime extends FlutterFormInputWidget { + const FlutterFormInputDateTime({ + Key? key, + required FlutterFormInputController controller, + Widget? label, + this.showIcon = true, + required this.inputType, + required this.dateFormat, + this.firstDate, + this.lastDate, + this.icon = Icons.calendar_today, + }) : super( key: key, controller: controller, label: label, ); - final DateFormat dateFormat; final bool showIcon; + final FlutterFormDateTimeType inputType; + final DateFormat dateFormat; + final DateTime? firstDate; + final DateTime? lastDate; final IconData icon; @override @@ -32,23 +46,34 @@ class FlutterFormInputDate extends FlutterFormInputWidget { getTranslator(context, ref); super.registerController(context); - return DateInputField(controller: controller, dateFormat: dateFormat); + return DateTimeInputField( + firstDate: firstDate, + lastDate: lastDate, + inputType: inputType, + controller: controller, + dateFormat: dateFormat, + ); } } /// Controller for dates used by a [FlutterFormInputWidget] used in a [FlutterForm]. /// -/// Mainly used by [FlutterFormInputDate]. -class FlutterFormInputDateController +/// Mainly used by [FlutterFormInputDateTime]. +class FlutterFormInputDateTimeController implements FlutterFormInputController { - FlutterFormInputDateController({ + FlutterFormInputDateTimeController({ required this.id, this.mandatory = true, this.value, this.checkPageTitle, this.checkPageDescription, + required this.dateTimeType, + required this.dateFormat, }); + final DateFormat dateFormat; + final FlutterFormDateTimeType dateTimeType; + @override String? id;