Skip to content

Commit a46f995

Browse files
committed
Restore DateRangePicker
1 parent 146c48f commit a46f995

File tree

3 files changed

+765
-0
lines changed

3 files changed

+765
-0
lines changed

lib/flutter_form_builder.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ export './localization/form_builder_localizations.dart';
44
export './src/fields/form_builder_checkbox.dart';
55
export './src/fields/form_builder_checkbox_group.dart';
66
export './src/fields/form_builder_choice_chips.dart';
7+
export './src/fields/form_builder_date_range_picker.dart';
8+
export './src/fields/form_builder_date_time_picker.dart';
79
export './src/fields/form_builder_dropdown.dart';
810
export './src/fields/form_builder_filter_chips.dart';
911
export './src/fields/form_builder_radio_group.dart';
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
import 'dart:async';
2+
import 'dart:core';
3+
4+
import 'package:flutter/material.dart';
5+
import 'package:flutter/services.dart';
6+
import 'package:flutter/widgets.dart';
7+
import 'package:flutter_form_builder/flutter_form_builder.dart';
8+
import 'package:intl/intl.dart' as intl;
9+
10+
/// Field for selecting a range of dates
11+
class FormBuilderDateRangePicker extends FormBuilderField<DateTimeRange> {
12+
//TODO: Add documentation
13+
final int maxLines;
14+
final TextInputType? keyboardType;
15+
final bool obscureText;
16+
final TextStyle? style;
17+
final TextEditingController? controller;
18+
final TextCapitalization textCapitalization;
19+
final TextInputAction? textInputAction;
20+
final StrutStyle? strutStyle;
21+
final TextDirection? textDirection;
22+
final TextAlign textAlign;
23+
final bool autofocus;
24+
final bool autocorrect;
25+
final MaxLengthEnforcement? maxLengthEnforcement;
26+
final int? maxLength;
27+
final VoidCallback? onEditingComplete;
28+
final ValueChanged<List<DateTime>>? onFieldSubmitted;
29+
final List<TextInputFormatter>? inputFormatters;
30+
final double cursorWidth;
31+
final Radius? cursorRadius;
32+
final Color ?cursorColor;
33+
final Brightness? keyboardAppearance;
34+
final EdgeInsets scrollPadding;
35+
final bool enableInteractiveSelection;
36+
final InputCounterWidgetBuilder? buildCounter;
37+
final bool expands;
38+
final int? minLines;
39+
final bool showCursor;
40+
final DateTime firstDate;
41+
final DateTime lastDate;
42+
final Locale? locale;
43+
final intl.DateFormat? format;
44+
final String? cancelText; // widget.cancelText,
45+
final String? confirmText; // widget.confirmText,
46+
final DateTime? currentDate; // widget.currentDate,
47+
final String? errorFormatText; // widget.erroerrorFormatText,
48+
final Widget Function(BuildContext, Widget?)? pickerBuilder; // widget.builder,
49+
final String? errorInvalidRangeText; // widget.errorInvalidRangeText,
50+
final String? errorInvalidText; // widget.errorInvalidText,
51+
final String? fieldEndHintText; // widget.fieldEndHintText,
52+
final String? fieldEndLabelText; // widget.fieldEndLabelText,
53+
final String? fieldStartHintText; // widget.fieldStartHintText,
54+
final String? fieldStartLabelText; // widget.fieldStartLabelText,
55+
final String? helpText; // widget.helpText,
56+
// final DateTimeRange initialDateRange; // widget.initialDateRange,
57+
final DatePickerEntryMode initialEntryMode; // widget.initialEntryMode,
58+
final RouteSettings? routeSettings; // widget.routeSettings,
59+
final String? saveText; // widget.saveText,
60+
final bool useRootNavigator; // widget.useRootNavigator,
61+
62+
/// Creates field for selecting a range of dates
63+
FormBuilderDateRangePicker({
64+
Key? key,
65+
//From Super
66+
required String name,
67+
FormFieldValidator<DateTimeRange>? validator,
68+
DateTimeRange? initialValue,
69+
InputDecoration decoration = const InputDecoration(),
70+
ValueChanged<DateTimeRange>? onChanged,
71+
ValueTransformer<DateTimeRange>? valueTransformer,
72+
bool enabled = true,
73+
FormFieldSetter<DateTimeRange>? onSaved,
74+
AutovalidateMode autovalidateMode = AutovalidateMode.disabled,
75+
VoidCallback? onReset,
76+
FocusNode? focusNode,
77+
required this.firstDate,
78+
required this.lastDate,
79+
this.format,
80+
this.maxLines = 1,
81+
this.obscureText = false,
82+
this.textCapitalization = TextCapitalization.none,
83+
this.scrollPadding = const EdgeInsets.all(20.0),
84+
this.enableInteractiveSelection = true,
85+
this.maxLengthEnforcement,
86+
this.textAlign = TextAlign.start,
87+
this.autofocus = false,
88+
this.autocorrect = true,
89+
this.cursorWidth = 2.0,
90+
this.keyboardType,
91+
this.style,
92+
this.controller,
93+
this.textInputAction,
94+
this.strutStyle,
95+
this.textDirection,
96+
this.maxLength,
97+
this.onEditingComplete,
98+
this.onFieldSubmitted,
99+
this.inputFormatters,
100+
this.cursorRadius,
101+
this.cursorColor,
102+
this.keyboardAppearance,
103+
this.buildCounter,
104+
this.expands = false,
105+
this.minLines,
106+
this.showCursor = false,
107+
this.locale,
108+
this.cancelText,
109+
this.confirmText,
110+
this.currentDate,
111+
this.errorFormatText,
112+
this.pickerBuilder,
113+
this.errorInvalidRangeText,
114+
this.errorInvalidText,
115+
this.fieldEndHintText,
116+
this.fieldEndLabelText,
117+
this.fieldStartHintText,
118+
this.fieldStartLabelText,
119+
this.helpText,
120+
// this.initialDateRange,
121+
this.initialEntryMode = DatePickerEntryMode.calendar,
122+
this.routeSettings,
123+
this.saveText,
124+
this.useRootNavigator = true,
125+
}) : super(
126+
key: key,
127+
initialValue: initialValue,
128+
name: name,
129+
validator: validator,
130+
valueTransformer: valueTransformer,
131+
onChanged: onChanged,
132+
autovalidateMode: autovalidateMode,
133+
onSaved: onSaved,
134+
enabled: enabled,
135+
onReset: onReset,
136+
decoration: decoration,
137+
focusNode: focusNode,
138+
builder: (FormFieldState<DateTimeRange?> field) {
139+
final state = field as FormBuilderDateRangePickerState;
140+
141+
return TextField(
142+
enabled: state.enabled,
143+
style: style,
144+
focusNode: state.effectiveFocusNode,
145+
decoration: state.decoration(),
146+
// initialValue: "${_initialValue ?? ''}",
147+
maxLines: maxLines,
148+
keyboardType: keyboardType,
149+
obscureText: obscureText,
150+
onEditingComplete: onEditingComplete,
151+
controller: state._effectiveController,
152+
autocorrect: autocorrect,
153+
autofocus: autofocus,
154+
buildCounter: buildCounter,
155+
cursorColor: cursorColor,
156+
cursorRadius: cursorRadius,
157+
cursorWidth: cursorWidth,
158+
enableInteractiveSelection: enableInteractiveSelection,
159+
maxLength: maxLength,
160+
inputFormatters: inputFormatters,
161+
keyboardAppearance: keyboardAppearance,
162+
maxLengthEnforcement: maxLengthEnforcement,
163+
scrollPadding: scrollPadding,
164+
textAlign: textAlign,
165+
textCapitalization: textCapitalization,
166+
textDirection: textDirection,
167+
textInputAction: textInputAction,
168+
strutStyle: strutStyle,
169+
readOnly: true,
170+
expands: expands,
171+
minLines: minLines,
172+
showCursor: showCursor,
173+
);
174+
},
175+
);
176+
177+
@override
178+
FormBuilderDateRangePickerState createState() =>
179+
FormBuilderDateRangePickerState();
180+
181+
static String tryFormat(DateTime date, intl.DateFormat format) {
182+
if (date != null) {
183+
try {
184+
return format.format(date);
185+
} catch (e) {
186+
// print('Error formatting date: $e');
187+
}
188+
}
189+
return '';
190+
}
191+
}
192+
193+
class FormBuilderDateRangePickerState
194+
extends FormBuilderFieldState<FormBuilderDateRangePicker, DateTimeRange> {
195+
late TextEditingController _effectiveController;
196+
197+
@override
198+
void initState() {
199+
super.initState();
200+
_effectiveController =
201+
widget.controller ?? TextEditingController(text: _valueToText());
202+
effectiveFocusNode!.addListener(_handleFocus);
203+
}
204+
205+
@override
206+
void dispose() {
207+
effectiveFocusNode!.removeListener(_handleFocus);
208+
// Dispose the _effectiveController when initState created it
209+
if (null == widget.controller) {
210+
_effectiveController.dispose();
211+
}
212+
super.dispose();
213+
}
214+
215+
Future<void> _handleFocus() async {
216+
if (effectiveFocusNode!.hasFocus && enabled) {
217+
effectiveFocusNode!.unfocus();
218+
/*final initialFirstDate = value?.isEmpty ?? true
219+
? (widget.initialFirstDate ?? DateTime.now())
220+
: value[0];
221+
final initialLastDate = value?.isEmpty ?? true
222+
? (widget.initialLastDate ?? initialFirstDate)
223+
: (value.length < 2 ? initialFirstDate : value[1]);*/
224+
final picked = await showDateRangePicker(
225+
context: context,
226+
firstDate: widget.firstDate,
227+
lastDate: widget.lastDate,
228+
locale: widget.locale,
229+
textDirection: widget.textDirection,
230+
cancelText: widget.cancelText,
231+
confirmText: widget.confirmText,
232+
currentDate: widget.currentDate,
233+
errorFormatText: widget.errorFormatText,
234+
builder: widget.pickerBuilder,
235+
errorInvalidRangeText: widget.errorInvalidRangeText,
236+
errorInvalidText: widget.errorInvalidText,
237+
fieldEndHintText: widget.fieldEndHintText,
238+
fieldEndLabelText: widget.fieldEndLabelText,
239+
fieldStartHintText: widget.fieldStartHintText,
240+
fieldStartLabelText: widget.fieldStartLabelText,
241+
helpText: widget.helpText,
242+
initialDateRange: value,
243+
initialEntryMode: widget.initialEntryMode,
244+
routeSettings: widget.routeSettings,
245+
saveText: widget.saveText,
246+
useRootNavigator: widget.useRootNavigator,
247+
);
248+
if (picked != null) {
249+
didChange(picked);
250+
}
251+
}
252+
}
253+
254+
String _valueToText() {
255+
if (value == null) {
256+
return '';
257+
}
258+
259+
return '${format(value!.start)} - ${format(value!.end)}';
260+
}
261+
262+
String format(DateTime date) => FormBuilderDateRangePicker.tryFormat(
263+
date, widget.format ?? intl.DateFormat.yMd());
264+
265+
void _setTextFieldString() {
266+
setState(() {
267+
_effectiveController.text = _valueToText();
268+
});
269+
}
270+
271+
@override
272+
void didChange(DateTimeRange? value) {
273+
super.didChange(value);
274+
_setTextFieldString();
275+
}
276+
277+
@override
278+
void reset() {
279+
super.reset();
280+
_setTextFieldString();
281+
}
282+
}

0 commit comments

Comments
 (0)