Adding support for time
This commit is contained in:
parent
97da6f5955
commit
c836bc8329
3 changed files with 380 additions and 59 deletions
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -32,3 +32,17 @@
|
||||||
## 0.2.2
|
## 0.2.2
|
||||||
|
|
||||||
* Auto-formatting with dart-fm to meet pub.dev requirements
|
* Auto-formatting with dart-fm to meet pub.dev requirements
|
||||||
|
|
||||||
|
## 0.3.0
|
||||||
|
|
||||||
|
Breaking changes:
|
||||||
|
* No more const constructor.
|
||||||
|
|
||||||
|
Deprecated:
|
||||||
|
* DateField and DateFormField are now deprecated and will be removed in the next version, please consider switching to
|
||||||
|
DateTimeField and DateTimeFormField.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
|
@ -29,7 +29,7 @@ class _HomeWidgetState extends State<HomeWidget> {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Column(
|
Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
DateField(
|
DateTimeField(
|
||||||
|
|
||||||
selectedDate: selectedDate,
|
selectedDate: selectedDate,
|
||||||
onDateSelected: (DateTime date) {
|
onDateSelected: (DateTime date) {
|
||||||
|
|
|
@ -2,18 +2,18 @@ import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
/// A [FormField] that contains a [DateField].
|
/// A [FormField] that contains a [DateTimeField].
|
||||||
///
|
///
|
||||||
/// This is a convenience widget that wraps a [DateField] widget in a
|
/// This is a convenience widget that wraps a [DateTimeField] widget in a
|
||||||
/// [FormField].
|
/// [FormField].
|
||||||
///
|
///
|
||||||
/// A [Form] ancestor is not required. The [Form] simply makes it easier to
|
/// A [Form] ancestor is not required. The [Form] simply makes it easier to
|
||||||
/// save, reset, or validate multiple fields at once. To use without a [Form],
|
/// save, reset, or validate multiple fields at once. To use without a [Form],
|
||||||
/// pass a [GlobalKey] to the constructor and use [GlobalKey.currentState] to
|
/// pass a [GlobalKey] to the constructor and use [GlobalKey.currentState] to
|
||||||
/// save or reset the form field.
|
/// save or reset the form field.
|
||||||
class DateFormField extends FormField<DateTime> {
|
class DateTimeFormField extends FormField<DateTime> {
|
||||||
DateFormField(
|
DateTimeFormField({
|
||||||
{Key key,
|
Key key,
|
||||||
FormFieldSetter<DateTime> onSaved,
|
FormFieldSetter<DateTime> onSaved,
|
||||||
FormFieldValidator<DateTime> validator,
|
FormFieldValidator<DateTime> validator,
|
||||||
DateTime initialValue,
|
DateTime initialValue,
|
||||||
|
@ -25,8 +25,9 @@ class DateFormField extends FormField<DateTime> {
|
||||||
this.label = 'Select date',
|
this.label = 'Select date',
|
||||||
this.dateFormat,
|
this.dateFormat,
|
||||||
this.decoration,
|
this.decoration,
|
||||||
this.initialDatePickerMode = DatePickerMode.day})
|
this.initialDatePickerMode = DatePickerMode.day,
|
||||||
: super(
|
this.mode = DateFieldPickerMode.date,
|
||||||
|
}) : super(
|
||||||
key: key,
|
key: key,
|
||||||
initialValue: initialValue,
|
initialValue: initialValue,
|
||||||
onSaved: onSaved,
|
onSaved: onSaved,
|
||||||
|
@ -43,7 +44,7 @@ class DateFormField extends FormField<DateTime> {
|
||||||
field.didChange(value);
|
field.didChange(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DateField(
|
return DateTimeField(
|
||||||
label: label,
|
label: label,
|
||||||
firstDate: firstDate,
|
firstDate: firstDate,
|
||||||
lastDate: lastDate,
|
lastDate: lastDate,
|
||||||
|
@ -54,7 +55,7 @@ class DateFormField extends FormField<DateTime> {
|
||||||
onDateSelected: onChangedHandler,
|
onDateSelected: onChangedHandler,
|
||||||
selectedDate: state.value,
|
selectedDate: state.value,
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
);
|
mode: mode);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -80,30 +81,55 @@ class DateFormField extends FormField<DateTime> {
|
||||||
/// (optional) Let you choose the [DatePickerMode] for the date picker! (default is [DatePickerMode.day]
|
/// (optional) Let you choose the [DatePickerMode] for the date picker! (default is [DatePickerMode.day]
|
||||||
final DatePickerMode initialDatePickerMode;
|
final DatePickerMode initialDatePickerMode;
|
||||||
|
|
||||||
|
/// Whether to ask the user to pick only the date, the time or both.
|
||||||
|
final DateFieldPickerMode mode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_DateFormFieldState createState() => _DateFormFieldState();
|
_DateFormFieldState createState() => _DateFormFieldState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DateFormFieldState extends FormFieldState<DateTime> {}
|
class _DateFormFieldState extends FormFieldState<DateTime> {}
|
||||||
|
|
||||||
/// [DateField]
|
/// [DateTimeField]
|
||||||
///
|
///
|
||||||
/// Shows an [_InputDropdown] that'll trigger [DateField._selectDate] whenever the user
|
/// Shows an [_InputDropdown] that'll trigger [DateTimeField._selectDate] whenever the user
|
||||||
/// clicks on it ! The date picker is **platform responsive** (ios date picker style for ios, ...)
|
/// clicks on it ! The date picker is **platform responsive** (ios date picker style for ios, ...)
|
||||||
class DateField extends StatelessWidget {
|
class DateTimeField extends StatelessWidget {
|
||||||
/// Default constructor
|
/// Default constructor
|
||||||
const DateField({
|
DateTimeField({
|
||||||
|
Key key,
|
||||||
@required this.onDateSelected,
|
@required this.onDateSelected,
|
||||||
@required this.selectedDate,
|
@required this.selectedDate,
|
||||||
this.firstDate,
|
|
||||||
this.lastDate,
|
|
||||||
this.initialDatePickerMode = DatePickerMode.day,
|
this.initialDatePickerMode = DatePickerMode.day,
|
||||||
this.decoration,
|
this.decoration,
|
||||||
this.errorText,
|
this.errorText,
|
||||||
this.dateFormat,
|
|
||||||
this.label = 'Select date',
|
this.label = 'Select date',
|
||||||
this.enabled = true,
|
this.enabled = true,
|
||||||
});
|
this.mode = DateFieldPickerMode.dateAndTime,
|
||||||
|
DateTime firstDate,
|
||||||
|
DateTime lastDate,
|
||||||
|
DateFormat dateFormat,
|
||||||
|
}) : dateFormat = dateFormat ?? getDateFormatFromDateFieldPickerMode(mode),
|
||||||
|
firstDate = firstDate ?? DateTime(1900),
|
||||||
|
lastDate = lastDate ?? DateTime(2100),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
DateTimeField.time({
|
||||||
|
Key key,
|
||||||
|
this.onDateSelected,
|
||||||
|
this.selectedDate,
|
||||||
|
this.label,
|
||||||
|
this.errorText,
|
||||||
|
this.decoration,
|
||||||
|
this.enabled,
|
||||||
|
DateTime firstDate,
|
||||||
|
DateTime lastDate,
|
||||||
|
}) : initialDatePickerMode = null,
|
||||||
|
mode = DateFieldPickerMode.time,
|
||||||
|
dateFormat = DateFormat.jm(),
|
||||||
|
firstDate = firstDate ?? DateTime(2000),
|
||||||
|
lastDate = lastDate ?? DateTime(2001),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
/// Callback for whenever the user selects a [DateTime]
|
/// Callback for whenever the user selects a [DateTime]
|
||||||
final ValueChanged<DateTime> onDateSelected;
|
final ValueChanged<DateTime> onDateSelected;
|
||||||
|
@ -135,18 +161,23 @@ class DateField extends StatelessWidget {
|
||||||
/// (optional) Whether the field is usable. If false the user won't be able to select any date
|
/// (optional) Whether the field is usable. If false the user won't be able to select any date
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
|
|
||||||
|
/// Whether to ask the user to pick only the date, the time or both.
|
||||||
|
final DateFieldPickerMode mode;
|
||||||
|
|
||||||
/// Shows a dialog asking the user to pick a date !
|
/// Shows a dialog asking the user to pick a date !
|
||||||
Future<void> _selectDate(BuildContext context) async {
|
Future<void> _selectDate(BuildContext context) async {
|
||||||
|
final DateTime initialDateTime = selectedDate ?? lastDate ?? DateTime.now();
|
||||||
|
|
||||||
if (Theme.of(context).platform == TargetPlatform.iOS) {
|
if (Theme.of(context).platform == TargetPlatform.iOS) {
|
||||||
showModalBottomSheet<void>(
|
showModalBottomSheet<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext builder) {
|
builder: (BuildContext builder) {
|
||||||
return Container(
|
return Container(
|
||||||
height: MediaQuery.of(context).size.height / 4,
|
height: 216,
|
||||||
child: CupertinoDatePicker(
|
child: CupertinoDatePicker(
|
||||||
mode: CupertinoDatePickerMode.date,
|
mode: _cupertinoModeFromPickerMode(mode),
|
||||||
onDateTimeChanged: onDateSelected,
|
onDateTimeChanged: onDateSelected,
|
||||||
initialDateTime: selectedDate ?? lastDate ?? DateTime.now(),
|
initialDateTime: initialDateTime,
|
||||||
minimumDate: firstDate,
|
minimumDate: firstDate,
|
||||||
maximumDate: lastDate,
|
maximumDate: lastDate,
|
||||||
),
|
),
|
||||||
|
@ -154,47 +185,96 @@ class DateField extends StatelessWidget {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
DateTime _selectedDateTime = initialDateTime;
|
||||||
|
|
||||||
|
if ([DateFieldPickerMode.dateAndTime, DateFieldPickerMode.date]
|
||||||
|
.contains(mode)) {
|
||||||
final DateTime _selectedDate = await showDatePicker(
|
final DateTime _selectedDate = await showDatePicker(
|
||||||
context: context,
|
context: context,
|
||||||
initialDatePickerMode: initialDatePickerMode,
|
initialDatePickerMode: initialDatePickerMode,
|
||||||
initialDate: selectedDate ?? lastDate ?? DateTime.now(),
|
initialDate: initialDateTime,
|
||||||
firstDate: firstDate ?? DateTime(1900),
|
firstDate: firstDate,
|
||||||
lastDate: lastDate ?? DateTime(2100));
|
lastDate: lastDate);
|
||||||
|
|
||||||
if (_selectedDate != null) {
|
if (_selectedDate != null) {
|
||||||
onDateSelected(_selectedDate);
|
_selectedDateTime = _selectedDate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ([DateFieldPickerMode.dateAndTime, DateFieldPickerMode.time]
|
||||||
|
.contains(mode)) {
|
||||||
|
final TimeOfDay _selectedTime = await showTimePicker(
|
||||||
|
initialTime: TimeOfDay.fromDateTime(initialDateTime),
|
||||||
|
context: context,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (_selectedTime != null) {
|
||||||
|
_selectedDateTime = DateTime(
|
||||||
|
_selectedDateTime.year,
|
||||||
|
_selectedDateTime.month,
|
||||||
|
_selectedDateTime.day,
|
||||||
|
_selectedTime.hour,
|
||||||
|
_selectedTime.minute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDateSelected(_selectedDateTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
String text;
|
String text;
|
||||||
|
|
||||||
if (selectedDate != null)
|
if (selectedDate != null) text = dateFormat.format(selectedDate);
|
||||||
text = (dateFormat ?? DateFormat.yMMMd()).format(selectedDate);
|
|
||||||
|
|
||||||
return _InputDropdown(
|
return _InputDropdown(
|
||||||
text: text ?? label,
|
text: text ?? label,
|
||||||
label: text == null ? null : label,
|
label: text == null ? null : label,
|
||||||
errorText: errorText,
|
errorText: errorText,
|
||||||
decoration: decoration,
|
decoration: decoration,
|
||||||
onPressed: enabled
|
onPressed: enabled ? () => _selectDate(context) : null,
|
||||||
? () {
|
|
||||||
_selectDate(context);
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Those values are used by the [DateTimeField] widget to determine whether to ask
|
||||||
|
/// the user for the time, the date or both.
|
||||||
|
enum DateFieldPickerMode { time, date, dateAndTime }
|
||||||
|
|
||||||
|
/// Returns the [CupertinoDatePickerMode] corresponding to the selected
|
||||||
|
/// [DateFieldPickerMode]. This exists to prevent redundancy in the [DateTimeField]
|
||||||
|
/// widget parameters.
|
||||||
|
CupertinoDatePickerMode _cupertinoModeFromPickerMode(DateFieldPickerMode mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case DateFieldPickerMode.time:
|
||||||
|
return CupertinoDatePickerMode.time;
|
||||||
|
case DateFieldPickerMode.date:
|
||||||
|
return CupertinoDatePickerMode.date;
|
||||||
|
default:
|
||||||
|
return CupertinoDatePickerMode.dateAndTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the corresponding default [DateFormat] for the selected [DateFieldPickerMode]
|
||||||
|
DateFormat getDateFormatFromDateFieldPickerMode(DateFieldPickerMode mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case DateFieldPickerMode.time:
|
||||||
|
return DateFormat.jm();
|
||||||
|
case DateFieldPickerMode.date:
|
||||||
|
return DateFormat.yMMMMd();
|
||||||
|
default:
|
||||||
|
return DateFormat.yMd().add_jm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// [_InputDropdown]
|
/// [_InputDropdown]
|
||||||
///
|
///
|
||||||
/// Shows a field with a dropdown arrow !
|
/// Shows a field with a dropdown arrow !
|
||||||
/// It does not show any popup menu, it'll just trigger onPressed whenever the
|
/// It does not show any popup menu, it'll just trigger onPressed whenever the
|
||||||
/// user does click on it !
|
/// user does click on it !
|
||||||
class _InputDropdown extends StatelessWidget {
|
class _InputDropdown extends StatelessWidget {
|
||||||
const _InputDropdown({
|
const _InputDropdown({
|
||||||
Key key,
|
Key key,
|
||||||
@required this.text,
|
@required this.text,
|
||||||
|
@ -254,3 +334,230 @@ class _InputDropdown extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Deprecated! Use [DateTimeFormField] instead
|
||||||
|
@Deprecated('This widget will be removed in the next version of the date_field package, consider switching to DateTimeFormField')
|
||||||
|
class DateFormField extends FormField<DateTime> {
|
||||||
|
DateFormField({
|
||||||
|
Key key,
|
||||||
|
FormFieldSetter<DateTime> onSaved,
|
||||||
|
FormFieldValidator<DateTime> validator,
|
||||||
|
DateTime initialValue,
|
||||||
|
bool autovalidate = false,
|
||||||
|
bool enabled = true,
|
||||||
|
this.onDateSelected,
|
||||||
|
this.firstDate,
|
||||||
|
this.lastDate,
|
||||||
|
this.label = 'Select date',
|
||||||
|
this.dateFormat,
|
||||||
|
this.decoration,
|
||||||
|
this.initialDatePickerMode = DatePickerMode.day,
|
||||||
|
this.mode = DateFieldPickerMode.date,
|
||||||
|
}) : super(
|
||||||
|
key: key,
|
||||||
|
initialValue: initialValue,
|
||||||
|
onSaved: onSaved,
|
||||||
|
validator: validator,
|
||||||
|
autovalidate: autovalidate,
|
||||||
|
enabled: enabled,
|
||||||
|
builder: (FormFieldState<DateTime> field) {
|
||||||
|
final _DateFormFieldState state = field;
|
||||||
|
|
||||||
|
void onChangedHandler(DateTime value) {
|
||||||
|
if (onDateSelected != null) {
|
||||||
|
onDateSelected(value);
|
||||||
|
}
|
||||||
|
field.didChange(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return DateTimeField(
|
||||||
|
label: label,
|
||||||
|
firstDate: firstDate,
|
||||||
|
lastDate: lastDate,
|
||||||
|
decoration: decoration,
|
||||||
|
initialDatePickerMode: initialDatePickerMode,
|
||||||
|
dateFormat: dateFormat,
|
||||||
|
errorText: state.errorText,
|
||||||
|
onDateSelected: onChangedHandler,
|
||||||
|
selectedDate: state.value,
|
||||||
|
enabled: enabled,
|
||||||
|
mode: mode);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
/// (optional) A callback that will be triggered whenever a new
|
||||||
|
/// DateTime is selected
|
||||||
|
final ValueChanged<DateTime> onDateSelected;
|
||||||
|
|
||||||
|
/// (optional) The first date that the user can select (default is 1900)
|
||||||
|
final DateTime firstDate;
|
||||||
|
|
||||||
|
/// (optional) The last date that the user can select (default is 2100)
|
||||||
|
final DateTime lastDate;
|
||||||
|
|
||||||
|
/// (optional) The label to display for the field (default is 'Select date')
|
||||||
|
final String label;
|
||||||
|
|
||||||
|
/// (optional) Custom [InputDecoration] for the [InputDecorator] widget
|
||||||
|
final InputDecoration decoration;
|
||||||
|
|
||||||
|
/// (optional) How to display the [DateTime] for the user (default is [DateFormat.yMMMD])
|
||||||
|
final DateFormat dateFormat;
|
||||||
|
|
||||||
|
/// (optional) Let you choose the [DatePickerMode] for the date picker! (default is [DatePickerMode.day]
|
||||||
|
final DatePickerMode initialDatePickerMode;
|
||||||
|
|
||||||
|
/// Whether to ask the user to pick only the date, the time or both.
|
||||||
|
final DateFieldPickerMode mode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
_DateFormFieldState createState() => _DateFormFieldState();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deprecated! Use [DateField] instead
|
||||||
|
@Deprecated('This widget will be removed in the next version of the date_field package, consider switching to DateTimeField')
|
||||||
|
class DateField extends StatelessWidget {
|
||||||
|
/// Default constructor
|
||||||
|
DateField({
|
||||||
|
Key key,
|
||||||
|
@required this.onDateSelected,
|
||||||
|
@required this.selectedDate,
|
||||||
|
this.initialDatePickerMode = DatePickerMode.day,
|
||||||
|
this.decoration,
|
||||||
|
this.errorText,
|
||||||
|
this.label = 'Select date',
|
||||||
|
this.enabled = true,
|
||||||
|
this.mode = DateFieldPickerMode.dateAndTime,
|
||||||
|
DateTime firstDate,
|
||||||
|
DateTime lastDate,
|
||||||
|
DateFormat dateFormat,
|
||||||
|
}) : dateFormat = dateFormat ?? getDateFormatFromDateFieldPickerMode(mode),
|
||||||
|
firstDate = firstDate ?? DateTime(1900),
|
||||||
|
lastDate = lastDate ?? DateTime(2100),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
DateField.time({
|
||||||
|
Key key,
|
||||||
|
this.onDateSelected,
|
||||||
|
this.selectedDate,
|
||||||
|
this.label,
|
||||||
|
this.errorText,
|
||||||
|
this.decoration,
|
||||||
|
this.enabled,
|
||||||
|
DateTime firstDate,
|
||||||
|
DateTime lastDate,
|
||||||
|
}) : initialDatePickerMode = null,
|
||||||
|
mode = DateFieldPickerMode.time,
|
||||||
|
dateFormat = DateFormat.jm(),
|
||||||
|
firstDate = firstDate ?? DateTime(2000),
|
||||||
|
lastDate = lastDate ?? DateTime(2001),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
/// Callback for whenever the user selects a [DateTime]
|
||||||
|
final ValueChanged<DateTime> onDateSelected;
|
||||||
|
|
||||||
|
/// The current selected date to display inside the field
|
||||||
|
final DateTime selectedDate;
|
||||||
|
|
||||||
|
/// (optional) The first date that the user can select (default is 1900)
|
||||||
|
final DateTime firstDate;
|
||||||
|
|
||||||
|
/// (optional) The last date that the user can select (default is 2100)
|
||||||
|
final DateTime lastDate;
|
||||||
|
|
||||||
|
/// Let you choose the [DatePickerMode] for the date picker! (default is [DatePickerMode.day]
|
||||||
|
final DatePickerMode initialDatePickerMode;
|
||||||
|
|
||||||
|
/// The label to display for the field (default is 'Select date')
|
||||||
|
final String label;
|
||||||
|
|
||||||
|
/// (optional) The error text that should be displayed under the field
|
||||||
|
final String errorText;
|
||||||
|
|
||||||
|
/// (optional) Custom [InputDecoration] for the [InputDecorator] widget
|
||||||
|
final InputDecoration decoration;
|
||||||
|
|
||||||
|
/// (optional) How to display the [DateTime] for the user (default is [DateFormat.yMMMD])
|
||||||
|
final DateFormat dateFormat;
|
||||||
|
|
||||||
|
/// (optional) Whether the field is usable. If false the user won't be able to select any date
|
||||||
|
final bool enabled;
|
||||||
|
|
||||||
|
/// Whether to ask the user to pick only the date, the time or both.
|
||||||
|
final DateFieldPickerMode mode;
|
||||||
|
|
||||||
|
/// Shows a dialog asking the user to pick a date !
|
||||||
|
Future<void> _selectDate(BuildContext context) async {
|
||||||
|
final DateTime initialDateTime = selectedDate ?? lastDate ?? DateTime.now();
|
||||||
|
|
||||||
|
if (Theme.of(context).platform == TargetPlatform.iOS) {
|
||||||
|
showModalBottomSheet<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext builder) {
|
||||||
|
return Container(
|
||||||
|
height: 216,
|
||||||
|
child: CupertinoDatePicker(
|
||||||
|
mode: _cupertinoModeFromPickerMode(mode),
|
||||||
|
onDateTimeChanged: onDateSelected,
|
||||||
|
initialDateTime: initialDateTime,
|
||||||
|
minimumDate: firstDate,
|
||||||
|
maximumDate: lastDate,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
DateTime _selectedDateTime = initialDateTime;
|
||||||
|
|
||||||
|
if ([DateFieldPickerMode.dateAndTime, DateFieldPickerMode.date]
|
||||||
|
.contains(mode)) {
|
||||||
|
final DateTime _selectedDate = await showDatePicker(
|
||||||
|
context: context,
|
||||||
|
initialDatePickerMode: initialDatePickerMode,
|
||||||
|
initialDate: initialDateTime,
|
||||||
|
firstDate: firstDate,
|
||||||
|
lastDate: lastDate);
|
||||||
|
|
||||||
|
if (_selectedDate != null) {
|
||||||
|
_selectedDateTime = _selectedDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([DateFieldPickerMode.dateAndTime, DateFieldPickerMode.time]
|
||||||
|
.contains(mode)) {
|
||||||
|
final TimeOfDay _selectedTime = await showTimePicker(
|
||||||
|
initialTime: TimeOfDay.fromDateTime(initialDateTime),
|
||||||
|
context: context,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (_selectedTime != null) {
|
||||||
|
_selectedDateTime = DateTime(
|
||||||
|
_selectedDateTime.year,
|
||||||
|
_selectedDateTime.month,
|
||||||
|
_selectedDateTime.day,
|
||||||
|
_selectedTime.hour,
|
||||||
|
_selectedTime.minute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDateSelected(_selectedDateTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
String text;
|
||||||
|
|
||||||
|
if (selectedDate != null) text = dateFormat.format(selectedDate);
|
||||||
|
|
||||||
|
return _InputDropdown(
|
||||||
|
text: text ?? label,
|
||||||
|
label: text == null ? null : label,
|
||||||
|
errorText: errorText,
|
||||||
|
decoration: decoration,
|
||||||
|
onPressed: enabled ? () => _selectDate(context) : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue