Skip to content

Commit 44133dc

Browse files
Datepicker Control (#1998)
* date_picker from commit 0402e56 * date_picker.py * fixed control name, datepicker is shown in test * fixed lastdate * Fixed value getter * removed StoreConnector and pass dispatch into constructor instead * changed attr name to 'onChange' as in dart * refactor * refactor * on_dismiss event * current_date * error_format_text, error_invalid_text * refactor * field_hint_text, field_label_text * fixed datePickerEntryMode and datePickerMode * default value to current_date * refactor * commented locale parts * switch calendar and input icons * updated control description * refactor * fixed switchToCalendarEntryModeIcon and switchToInputEntryModeIcon * removed comments * removed DatePickerState * updated enum properties --------- Co-authored-by: Feodor Fitsner <[email protected]>
1 parent c7c53c4 commit 44133dc

File tree

5 files changed

+522
-0
lines changed

5 files changed

+522
-0
lines changed

package/lib/src/controls/create_control.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import 'clipboard.dart';
2727
import 'column.dart';
2828
import 'container.dart';
2929
import 'datatable.dart';
30+
import 'date_picker.dart';
3031
import 'divider.dart';
3132
import 'drag_target.dart';
3233
import 'draggable.dart';
@@ -306,6 +307,14 @@ Widget createWidget(Key? key, ControlViewModel controlView, Control? parent,
306307
control: controlView.control,
307308
children: controlView.children,
308309
parentDisabled: parentDisabled);
310+
case "datepicker":
311+
return DatePickerControl(
312+
parent: parent,
313+
control: controlView.control,
314+
children: controlView.children,
315+
parentDisabled: parentDisabled,
316+
dispatch: controlView.dispatch,
317+
);
309318
case "draggable":
310319
return DraggableControl(
311320
key: key,
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import 'package:flutter/material.dart';
2+
import '../actions.dart';
3+
import '../flet_app_services.dart';
4+
import '../models/control.dart';
5+
import '../protocol/update_control_props_payload.dart';
6+
import 'form_field.dart';
7+
import '../utils/icons.dart';
8+
9+
class DatePickerControl extends StatefulWidget {
10+
final Control? parent;
11+
final Control control;
12+
final List<Control> children;
13+
final bool parentDisabled;
14+
final dynamic dispatch;
15+
16+
const DatePickerControl({
17+
Key? key,
18+
this.parent,
19+
required this.control,
20+
required this.children,
21+
required this.parentDisabled,
22+
required this.dispatch,
23+
}) : super(key: key);
24+
25+
@override
26+
State<DatePickerControl> createState() => _DatePickerControlState();
27+
}
28+
29+
class _DatePickerControlState extends State<DatePickerControl> {
30+
bool _open = false;
31+
32+
@override
33+
Widget build(BuildContext context) {
34+
debugPrint("DatePicker build: ${widget.control.id}");
35+
var open = widget.control.attrBool("open", false)!;
36+
DateTime? value = widget.control.attrDateTime("value");
37+
DateTime? firstDate = widget.control.attrDateTime("firstDate");
38+
DateTime? lastDate = widget.control.attrDateTime("lastDate");
39+
DateTime? currentDate = widget.control.attrDateTime("currentDate");
40+
//String? localeString = widget.control.attrString("locale");
41+
String? helpText = widget.control.attrString("helpText");
42+
String? cancelText = widget.control.attrString("cancelText");
43+
String? confirmText = widget.control.attrString("confirmText");
44+
String? errorFormatText = widget.control.attrString("errorFormatText");
45+
String? errorInvalidText = widget.control.attrString("errorInvalidText");
46+
TextInputType keyboardType =
47+
parseTextInputType(widget.control.attrString("keyboardType", "")!);
48+
DatePickerMode datePickerMode = DatePickerMode.values.firstWhere(
49+
(a) =>
50+
a.name.toLowerCase() ==
51+
widget.control.attrString("datePickerMode", "")!.toLowerCase(),
52+
orElse: () => DatePickerMode.day);
53+
DatePickerEntryMode datePickerEntryMode = DatePickerEntryMode.values
54+
.firstWhere(
55+
(a) =>
56+
a.name.toLowerCase() ==
57+
widget.control
58+
.attrString("datePickerEntryMode", "")!
59+
.toLowerCase(),
60+
orElse: () => DatePickerEntryMode.calendar);
61+
String? fieldHintText = widget.control.attrString("fieldHintText");
62+
String? fieldLabelText = widget.control.attrString("fieldLabelText");
63+
IconData? switchToCalendarEntryModeIcon = getMaterialIcon(
64+
widget.control.attrString("switchToCalendarEntryModeIcon", "")!);
65+
IconData? switchToInputEntryModeIcon = getMaterialIcon(
66+
widget.control.attrString("switchToInputEntryModeIcon", "")!);
67+
68+
//Locale locale;
69+
// if (localeString == null) {
70+
// locale = Localizations.localeOf(context);
71+
// } else {
72+
// //locale = Locale(localeString);
73+
// }
74+
75+
void onClosed(DateTime? dateValue) {
76+
String stringValue;
77+
String eventName;
78+
if (dateValue == null) {
79+
stringValue =
80+
value?.toIso8601String() ?? currentDate?.toIso8601String() ?? "";
81+
eventName = "dismiss";
82+
} else {
83+
stringValue = dateValue?.toIso8601String() ?? "";
84+
eventName = "change";
85+
}
86+
List<Map<String, String>> props = [
87+
{"i": widget.control.id, "value": stringValue, "open": "false"}
88+
];
89+
widget.dispatch(
90+
UpdateControlPropsAction(UpdateControlPropsPayload(props: props)));
91+
FletAppServices.of(context).server.updateControlProps(props: props);
92+
93+
FletAppServices.of(context).server.sendPageEvent(
94+
eventTarget: widget.control.id,
95+
eventName: eventName,
96+
eventData: stringValue);
97+
}
98+
99+
Widget createSelectDateDialog() {
100+
Widget dialog = DatePickerDialog(
101+
initialDate: value ?? currentDate ?? DateTime.now(),
102+
firstDate: firstDate ?? DateTime(1900),
103+
lastDate: lastDate ?? DateTime(2050),
104+
currentDate: currentDate ?? DateTime.now(),
105+
helpText: helpText,
106+
cancelText: cancelText,
107+
confirmText: confirmText,
108+
errorFormatText: errorFormatText,
109+
errorInvalidText: errorInvalidText,
110+
keyboardType: keyboardType,
111+
initialCalendarMode: datePickerMode,
112+
initialEntryMode: datePickerEntryMode,
113+
fieldHintText: fieldHintText,
114+
fieldLabelText: fieldLabelText,
115+
switchToCalendarEntryModeIcon: switchToCalendarEntryModeIcon != null
116+
? Icon(switchToCalendarEntryModeIcon)
117+
: null,
118+
switchToInputEntryModeIcon: switchToInputEntryModeIcon != null
119+
? Icon(switchToInputEntryModeIcon)
120+
: null,
121+
);
122+
123+
// dialog = Localizations.override(
124+
// context: context,
125+
// locale: locale,
126+
// child: dialog,
127+
// );
128+
129+
return dialog;
130+
}
131+
132+
if (open && !_open) {
133+
WidgetsBinding.instance.addPostFrameCallback((_) {
134+
showDialog<DateTime>(
135+
context: context,
136+
builder: (context) => createSelectDateDialog()).then((result) {
137+
debugPrint("pickDate() completed");
138+
onClosed(result);
139+
});
140+
});
141+
}
142+
143+
_open = open;
144+
return const SizedBox.shrink();
145+
}
146+
}

package/lib/src/models/control.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ class Control extends Equatable {
8686
return defValue;
8787
}
8888

89+
DateTime? attrDateTime(String name, [DateTime? defValue]) {
90+
var value = attrs[name.toLowerCase()];
91+
if (value == null) {
92+
return defValue;
93+
}
94+
return DateTime.parse(value);
95+
}
96+
8997
Control copyWith(
9098
{String? id,
9199
String? pid,

sdk/python/packages/flet-core/src/flet_core/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
DataRow,
6868
DataTable,
6969
)
70+
from flet_core.date_picker import DatePicker, DatePickerMode, DatePickerEntryMode
7071
from flet_core.divider import Divider
7172
from flet_core.drag_target import DragTarget, DragTargetAcceptEvent
7273
from flet_core.draggable import Draggable

0 commit comments

Comments
 (0)