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 _) => FDateField(
3 label: const Text('Appointment Date'),
4 description: const 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 Modes

Split Grid Calendar

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

Wheel Calendar

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

Calendar Only

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

Input Only

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

Clearable

1@override
2Widget build(BuildContext _) => FDateField(
3 selectionControl: .managedSingle(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 calendar: FDateFieldGridCalendarProperties(
12 popoverBuilder: (context, controller, popoverController, content) =>
13 Padding(
14 padding: const .all(1.0),
15 child: Column(
16 mainAxisSize: .min,
17 children: [
18 content,
19 Padding(
20 padding: const .all(8.0),
21 child: Row(
22 mainAxisSize: .min,
23 spacing: 6,
24 children: [
25 for (final label in ['Today', 'Tomorrow', 'In a week'])
26 FButton(
27 variant: .outline,
28 size: .sm,
29 child: Text(label),
30 onPress: () {},
31 ),
32 ],
33 ),
34 ),
35 ],
36 ),
37 ),
38 ),
39);
40

Custom Validation

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

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

On this page