Form

Date Field

A date field allows a date to be selected from a calendar or input field.

It is recommended to use FDateField.calendar on touch devices and FDateField.new/FDateField.input on non-primarily touch devices.

The input field supports both arrow key navigation:

  • Up/Down arrows: Increment/decrement values
  • Left/Right arrows: Move between date segments

The input field does not support the following locales that use non-western numerals, it will default to English:

  • Arabic
  • Assamese
  • Bengali
  • Persian/Farsi
  • Marathi
  • Burmese
  • Nepali
  • Pashto
  • Tamil
1@override
2Widget build(BuildContext _) => const FDateField(
3 label: Text('Appointment Date'),
4 description: Text('Select a date for your appointment'),
5);
6

CLI

To generate a specific style for customization:

dart run forui style create date-field

Usage

FDateField(...)

1FDateField(
2 size: .md,
3 style: .delta(fieldStyles: .delta([])),
4 enabled: true,
5)

FDateField.calendar(...)

1FDateField.calendar(
2 size: .md,
3 style: .delta(fieldStyles: .delta([])),
4 enabled: true,
5)

FDateField.input(...)

1FDateField.input(
2 size: .md,
3 style: .delta(fieldStyles: .delta([])),
4 enabled: true,
5)

Examples

Calendar Only

1@override
2Widget build(BuildContext _) => const FDateField.calendar(
3 label: Text('Appointment Date'),
4 description: Text('Select a date for your appointment'),
5);
6

Input Only

1@override
2Widget build(BuildContext _) => const FDateField.input(
3 label: Text('Appointment Date'),
4 description: Text('Select a date for your appointment'),
5);
6

Clearable

1@override
2Widget build(BuildContext _) => FDateField(
3 control: .managed(initial: .now()),
4 label: const Text('Appointment Date'),
5 description: const Text('Select a date for your appointment'),
6 clearable: true,
7);
8

Popover Builder

1@override
2Widget build(BuildContext _) => FDateField.calendar(
3 style: .delta(
4 calendarStyle: .delta(
5 decoration: .boxDelta(border: .fromLTRB()),
6 padding: const .value(.only(left: 11, top: 11, right: 11)),
7 ),
8 ),
9 label: const Text('Appointment Date'),
10 description: const Text('Select a date for your appointment'),
11 popoverBuilder: (context, controller, popoverController, content) => Padding(
12 padding: const .all(1.0),
13 child: Column(
14 mainAxisSize: .min,
15 children: [
16 content,
17 Padding(
18 padding: const .all(8.0),
19 child: Row(
20 mainAxisSize: .min,
21 spacing: 6,
22 children: [
23 for (final label in ['Today', 'Tomorrow', 'In a week'])
24 FButton(
25 variant: .outline,
26 size: .sm,
27 child: Text(label),
28 onPress: () {},
29 ),
30 ],
31 ),
32 ),
33 ],
34 ),
35 ),
36);
37

Custom Validation

1@override
2Widget build(BuildContext _) => FDateField(
3 control: .managed(
4 validator: (date) => date?.weekday == 6 || date?.weekday == 7
5 ? 'Date cannot be a weekend.'
6 : null,
7 ),
8 label: const Text('Appointment Date'),
9 description: const Text('Select a date for your appointment'),
10);
11

Form

1class FormDateFieldExample extends StatefulWidget {
2 @override
3 State<FormDateFieldExample> createState() => _FormDateFieldExampleState();
4}
5
6class _FormDateFieldExampleState extends State<FormDateFieldExample> {
7 final _key = GlobalKey<FormState>();
8 late final _startController = FDateFieldController(
9 validator: (date) => switch (date) {
10 null => 'Please select a start date',
11 final date when date.isBefore(.now()) =>
12 'Start date must be in the future',
13 _ => null,
14 },
15 );
16
17 @override
18 void dispose() {
19 _startController.dispose();
20 super.dispose();
21 }
22
23 @override
24 Widget build(BuildContext _) => Form(
25 key: _key,
26 child: Column(
27 spacing: 16,
28 children: [
29 FDateField(
30 control: .managed(controller: _startController),
31 label: const Text('Start Date'),
32 description: const Text('Select a start date'),
33 autovalidateMode: .disabled,
34 ),
35 const SizedBox(height: 20),
36 FDateField(
37 control: .managed(
38 validator: (date) => switch (date) {
39 null => 'Please select an end date',
40 final date
41 when _startController.value != null &&
42 date.isBefore(_startController.value!) =>
43 'Start date must be in the future',
44 _ => null,
45 },
46 ),
47 label: const Text('End Date'),
48 description: const Text('Select an end date'),
49 autovalidateMode: .disabled,
50 ),
51 Row(
52 mainAxisAlignment: .end,
53 children: [
54 FButton(
55 size: .sm,
56 mainAxisSize: .min,
57 child: const Text('Submit'),
58 onPress: () {
59 if (_key.currentState!.validate()) {
60 // Form is valid, do something.
61 }
62 },
63 ),
64 ],
65 ),
66 ],
67 ),
68 );
69}
70

On this page