ReactiveDateTimePicker constructor
ReactiveDateTimePicker({
- Key? key,
- String? formControlName,
- FormControl<
DateTime> ? formControl, - ControlValueAccessor<
DateTime, String> ? valueAccessor, - Map<
String, ValidationMessageFunction> ? validationMessages, - ShowErrorsFunction<
DateTime> ? showErrors, - TextStyle? style,
- ReactiveDatePickerFieldType type = ReactiveDatePickerFieldType.date,
- InputDecoration? decoration,
- bool showClearIcon = true,
- Widget clearIcon = const Icon(Icons.clear),
- TransitionBuilder? builder,
- String? cancelText,
- String? confirmText,
- String? helpText,
- GetInitialDate? getInitialDate,
- GetInitialTime? getInitialTime,
- DateFormat? dateFormat,
- double disabledOpacity = 0.5,
- DateTime? firstDate,
- DateTime? lastDate,
- DatePickerEntryMode datePickerEntryMode = DatePickerEntryMode.calendar,
- SelectableDayPredicate? selectableDayPredicate,
- Locale? locale,
- TextDirection? textDirection,
- DatePickerMode initialDatePickerMode = DatePickerMode.day,
- String? errorFormatText,
- String? errorInvalidText,
- String? fieldHintText,
- String? fieldLabelText,
- RouteSettings? datePickerRouteSettings,
- TextInputType? keyboardType,
- Offset? anchorPoint,
- TimePickerEntryMode timePickerEntryMode = TimePickerEntryMode.dial,
- RouteSettings? timePickerRouteSettings,
Creates a ReactiveDatePickerField
that wraps the function showDatePicker.
Can optionally provide a formControl
to bind this widget to a control.
Can optionally provide a formControlName
to bind this ReactiveFormField
to a FormControl
.
Must provide one of the arguments formControl
or a formControlName
,
but not both at the same time.
The parameter transitionBuilder
is the equivalent of builder
parameter in the showTimePicker.
For documentation about the various parameters, see the showTimePicker function parameters.
Implementation
ReactiveDateTimePicker({
super.key,
super.formControlName,
super.formControl,
ControlValueAccessor<DateTime, String>? valueAccessor,
super.validationMessages,
super.showErrors,
////////////////////////////////////////////////////////////////////////////
TextStyle? style,
ReactiveDatePickerFieldType type = ReactiveDatePickerFieldType.date,
InputDecoration? decoration,
bool showClearIcon = true,
Widget clearIcon = const Icon(Icons.clear),
// common params
TransitionBuilder? builder,
bool useRootNavigator = true,
String? cancelText,
String? confirmText,
String? helpText,
GetInitialDate? getInitialDate,
GetInitialTime? getInitialTime,
DateFormat? dateFormat,
double disabledOpacity = 0.5,
// date picker params
DateTime? firstDate,
DateTime? lastDate,
DatePickerEntryMode datePickerEntryMode = DatePickerEntryMode.calendar,
SelectableDayPredicate? selectableDayPredicate,
Locale? locale,
TextDirection? textDirection,
DatePickerMode initialDatePickerMode = DatePickerMode.day,
String? errorFormatText,
String? errorInvalidText,
String? fieldHintText,
String? fieldLabelText,
RouteSettings? datePickerRouteSettings,
TextInputType? keyboardType,
Offset? anchorPoint,
// time picker params
TimePickerEntryMode timePickerEntryMode = TimePickerEntryMode.dial,
RouteSettings? timePickerRouteSettings,
}) : super(
valueAccessor:
valueAccessor ?? _effectiveValueAccessor(type, dateFormat),
builder: (field) {
Widget? suffixIcon = decoration?.suffixIcon;
final isEmptyValue =
field.value == null || field.value?.isEmpty == true;
if (showClearIcon && !isEmptyValue) {
suffixIcon = InkWell(
borderRadius: BorderRadius.circular(25),
child: clearIcon,
onTap: () {
field.control.markAsTouched();
field.didChange(null);
},
);
}
final InputDecoration effectiveDecoration =
(decoration ?? const InputDecoration())
.applyDefaults(Theme.of(field.context).inputDecorationTheme)
.copyWith(suffixIcon: suffixIcon);
final effectiveValueAccessor =
valueAccessor ?? _effectiveValueAccessor(type, dateFormat);
final effectiveLastDate = lastDate ?? DateTime(2100);
return IgnorePointer(
ignoring: !field.control.enabled,
child: Opacity(
opacity: field.control.enabled ? 1 : disabledOpacity,
child: GestureDetector(
onTap: () async {
DateTime? date;
TimeOfDay? time;
field.control.focus();
field.control.updateValueAndValidity();
if (type == ReactiveDatePickerFieldType.date ||
type == ReactiveDatePickerFieldType.dateTime) {
date = await showDatePicker(
context: field.context,
initialDate: (getInitialDate ?? _getInitialDate)(
field.control.value,
effectiveLastDate,
),
firstDate: firstDate ?? DateTime(1900),
lastDate: effectiveLastDate,
initialEntryMode: datePickerEntryMode,
selectableDayPredicate: selectableDayPredicate,
helpText: helpText,
cancelText: cancelText,
confirmText: confirmText,
locale: locale,
useRootNavigator: useRootNavigator,
routeSettings: datePickerRouteSettings,
textDirection: textDirection,
builder: builder,
initialDatePickerMode: initialDatePickerMode,
errorFormatText: errorFormatText,
errorInvalidText: errorInvalidText,
fieldHintText: fieldHintText,
fieldLabelText: fieldLabelText,
keyboardType: keyboardType,
anchorPoint: anchorPoint,
);
}
if (type == ReactiveDatePickerFieldType.time ||
(type == ReactiveDatePickerFieldType.dateTime &&
// there is no need to show timepicker if cancel was pressed on datepicker
date != null)) {
time = await showTimePicker(
context: field.context,
initialTime: (getInitialTime ??
_getInitialTime)(field.control.value),
builder: builder,
useRootNavigator: useRootNavigator,
initialEntryMode: timePickerEntryMode,
cancelText: cancelText,
confirmText: confirmText,
helpText: helpText,
routeSettings: timePickerRouteSettings,
);
}
if (
// if `date` and `time` in `dateTime` mode is not empty...
(type == ReactiveDatePickerFieldType.dateTime &&
(date != null && time != null)) ||
// ... or if `date` in `date` mode is not empty ...
(type == ReactiveDatePickerFieldType.date &&
date != null) ||
// ... or if `time` in `time` mode is not empty ...
(type == ReactiveDatePickerFieldType.time &&
time != null)) {
final dateTime = _combine(date, time);
final value = field.control.value;
// ... and new value is not the same as was before...
if (value == null || dateTime.compareTo(value) != 0) {
// ... this means that cancel was not pressed at any moment
// so we can update the field
field.didChange(
effectiveValueAccessor.modelToViewValue(
_combine(date, time),
),
);
}
}
field.control.unfocus();
field.control.updateValueAndValidity();
field.control.markAsTouched();
},
child: InputDecorator(
decoration: effectiveDecoration.copyWith(
errorText: field.errorText,
enabled: field.control.enabled,
),
isFocused: field.control.hasFocus,
isEmpty: isEmptyValue,
child: Text(
field.value ?? '',
style: Theme.of(field.context)
.textTheme
.titleMedium
?.merge(style),
),
),
),
),
);
},
);