Line data Source code
1 : part of apptive_grid_form_widgets;
2 :
3 : /// FormComponent Widget to display a [DateTimeFormComponent]
4 : class DateTimeFormWidget extends StatefulWidget {
5 : /// Creates a Widget to display and select a Date and a Time contained in [component]
6 : ///
7 : /// Clicking on the Date part will show a DatePicker using [showDatePicker]
8 : /// Clicking on the Time part will show a TimePicker using [showTimePicker]
9 3 : const DateTimeFormWidget({
10 : Key? key,
11 : required this.component,
12 3 : }) : super(key: key);
13 :
14 : /// Component this Widget should reflect
15 : final DateTimeFormComponent component;
16 :
17 2 : @override
18 2 : State<StatefulWidget> createState() => _DateTimeFormWidgetState();
19 : }
20 :
21 : class _DateTimeFormWidgetState extends State<DateTimeFormWidget> {
22 : final TextEditingController _dateController = TextEditingController();
23 : final TextEditingController _timeController = TextEditingController();
24 :
25 2 : @override
26 : Widget build(
27 : BuildContext context,
28 : ) {
29 8 : if (widget.component.data.value != null) {
30 1 : final dateFormat = DateFormat.yMd();
31 5 : final dateString = dateFormat.format(widget.component.data.value!);
32 2 : _dateController.text = dateString;
33 1 : final timeFormat = DateFormat.jm();
34 5 : final timeString = timeFormat.format(widget.component.data.value!);
35 2 : _timeController.text = timeString;
36 : }
37 2 : return FormField<DateTime>(
38 1 : validator: (input) {
39 3 : if (widget.component.required && input == null) {
40 1 : return ApptiveGridLocalization.of(context)!
41 4 : .fieldIsRequired(widget.component.property);
42 : } else {
43 : return null;
44 : }
45 : },
46 : autovalidateMode: AutovalidateMode.onUserInteraction,
47 2 : builder: (state) {
48 2 : return InputDecorator(
49 2 : decoration: InputDecoration(
50 8 : helperText: widget.component.options.description,
51 : helperMaxLines: 100,
52 : labelText:
53 14 : widget.component.options.label ?? widget.component.property,
54 2 : errorText: state.errorText,
55 : ),
56 2 : child: Row(
57 : crossAxisAlignment: CrossAxisAlignment.start,
58 2 : children: [
59 2 : Flexible(
60 2 : child: InkWell(
61 1 : onTap: () {
62 : final initialDate =
63 5 : widget.component.data.value ?? DateTime.now();
64 1 : showDatePicker(
65 : context: context,
66 : initialDate: initialDate,
67 1 : firstDate: DateTime.fromMillisecondsSinceEpoch(0),
68 1 : lastDate: DateTime.fromMillisecondsSinceEpoch(
69 1 : const Duration(days: 100000000).inMilliseconds,
70 : ),
71 2 : ).then((value) {
72 : if (value != null) {
73 1 : state.didChange(value);
74 2 : setState(() {
75 4 : widget.component.data.value = value;
76 : });
77 : }
78 : });
79 : },
80 2 : child: AbsorbPointer(
81 2 : child: TextField(
82 2 : controller: _dateController,
83 : decoration: const InputDecoration(
84 : hintText: 'Date',
85 : border: InputBorder.none,
86 : isDense: true,
87 : filled: false,
88 : contentPadding: EdgeInsets.zero,
89 : ),
90 : ),
91 : ),
92 : ),
93 : ),
94 2 : Flexible(
95 2 : child: InkWell(
96 1 : onTap: () {
97 : final initialDate =
98 5 : widget.component.data.value ?? DateTime.now();
99 1 : showTimePicker(
100 : context: context,
101 1 : initialTime: TimeOfDay.fromDateTime(initialDate),
102 2 : ).then((value) {
103 : if (value != null) {
104 2 : setState(() {
105 1 : final newDate = DateTime(
106 1 : initialDate.year,
107 1 : initialDate.month,
108 1 : initialDate.day,
109 1 : value.hour,
110 1 : value.minute,
111 1 : initialDate.second,
112 1 : initialDate.millisecond,
113 1 : initialDate.microsecond,
114 : );
115 4 : widget.component.data.value = newDate;
116 1 : state.didChange(newDate);
117 : });
118 : }
119 : });
120 : },
121 2 : child: AbsorbPointer(
122 2 : child: TextField(
123 2 : controller: _timeController,
124 : decoration: const InputDecoration(
125 : hintText: 'Time',
126 : isDense: true,
127 : filled: false,
128 : border: InputBorder.none,
129 : contentPadding: EdgeInsets.zero,
130 : ),
131 : ),
132 : ),
133 : ),
134 : ),
135 : ],
136 : ),
137 : );
138 : },
139 : );
140 : }
141 :
142 2 : @override
143 : void dispose() {
144 4 : _dateController.dispose();
145 2 : super.dispose();
146 : }
147 : }
|