Last updated:
0 purchases
flutter fast forms
Flutter Fast Forms #
Flutter Fast Forms is the only Dart package you need to build Flutter forms fast.
It adds these missing features to the Flutter SDK:
FastFormControl<T> convenience widgets that wrap Material / Cupertino form controls in a FormField<T> according to the already built-in TextFormField / DropdownButtonFormField
FastForm widget that wraps the built-in Form widget for providing the current form field values in onChanged callback
FastFormArray widget that aggregates a flexible number of homogeneous controls in a single FormField<T>
FastChipsInput widget that converts text input into chips as defined by Material Design
Conditional form fields
touched validation state
Common FormFieldValidator<T> functions
Table of Contents #
Getting Started
Widget Catalog
Adaptive Form Fields
Conditional Form Fields
Custom Form Fields
Getting Started #
1. Add a FastForm to your widget tree:
class MyFormPage extends StatelessWidget {
MyFormPage({Key? key, required this.title}) : super(key: key);
final formKey = GlobalKey<FormState>();
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: SafeArea(
child: SingleChildScrollView(
child: FastForm(
formKey: formKey,
children: [],
),
),
),
);
}
}
copied to clipboard
2. Add FastFormControl<T> children to the FastForm:
FastForm(
formKey: formKey,
children: [
const FastTextField(
name: 'field_destination',
labelText: 'Destination',
placeholder: 'Where are you going?',
),
FastDateRangePicker(
name: 'field_check_in_out',
labelText: 'Check-in - Check-out',
firstDate: DateTime.now(),
lastDate: DateTime.now().add(const Duration(days: 365)),
),
const FastCheckbox(
name: 'field_travel_purpose',
labelText: 'Travel purpose',
titleText: 'I am travelling for work',
),
],
),
copied to clipboard
3. Wrap the children in a FastFormSection for visual grouping and consistent padding:
FastForm(
formKey: formKey,
children: [
FastFormSection(
header: const Text('My Form'),
padding: EdgeInsets.all(16.0),
children: [
const FastTextField(
name: 'field_destination',
labelText: 'Destination',
placeholder: 'Where are you going?',
),
// ...
],
),
]
),
copied to clipboard
Widget Catalog #
FastFormControl<T>
field value type
wraps Material widget
wraps Cupertino widget when adaptive: true
FastAutocomplete<O>
String
Autocomplete<O>
no
FastCheckbox
bool
CheckboxListTile
CupertinoCheckbox
FastChoiceChips<T>
Set<T>
ChoiceChip
no
FastCalendar
DateTime
CalendarDatePicker
no
FastChipsInput
List<String>
RawAutocomplete<String> + InputChip
no
FastDatePicker
DateTime
showDatePicker
CupertinoDatePicker
FastDateRangePicker
DateTimeRange
showDateRangePicker
no
FastDropdown<T>
T
DropdownButtonFormField<T>
no
FastRadioGroup<T>
T
RadioListTile<T>
no
FastRangeSlider
RangeValues
RangeSlider
no
FastSegmentedButton<T>
Set<T>
SegmentedButton<T>
no
FastSegmentedControl<T>
T
no
CupertinoSlidingSegmentedControl<T>
FastSlider
double
Slider.adaptive
CupertinoSlider
FastSwitch
bool
SwitchListTile
CupertinoSwitch
FastTextField
String
TextFormField
CupertinoTextFormFieldRow
FastTimePicker
TimeOfDay
showTimePicker
no use FastDatePicker with CupertinoDatePickerMode.time
Adaptive Form Fields #
While some form controls are unique to a certain platform, various others are present in multiple design languages.
By default, Flutter Fast Forms uses Material widgets on any platform.
This behavior is adjustable so that platform-specific Cupertino widgets are automatically rendered on iOS.
Tip
The widget catalog tells you which FastFormControl is adaptive.
📓 Example: Always use Cupertino widgets on iOS in a FastForm.
FastForm(
formKey: formKey,
adaptive: true,
children: [
const FastSwitch(
name: 'switch',
titleText: 'Disable text field',
),
FastTextField(
name: 'text_field',
labelText: 'Just some sample text field',
),
]
),
copied to clipboard
Note
When adaptive is set to true any built-in FormFieldBuilder returns a corresponding Cupertino widget on iOS, if it exists.
📓 Example: Only use the Cupertino widget on iOS for a dedicated FastSwitch.
FastForm(
formKey: formKey,
children: [
const FastSwitch(
name: 'switch',
adaptive: true,
titleText: 'Disable text field',
),
]
),
copied to clipboard
Conditional Form Fields #
Not all controls in a form are autonomous and act independent of each other.
Occasionally, the state of a form field might be directly related to the state of some other form field as well.
Flutter Fast Forms allows you to define such conditions declaratively.
📓 Example: A FastTextField that is disabled when a FastSwitch is selected.
1. Add the conditions property to the conditional form field and assign an empty Map:
const FastSwitch(
name: 'switch',
titleText: 'Disable text field',
),
FastTextField(
name: 'text_field',
labelText: 'Just some sample text field',
conditions: {},
),
copied to clipboard
2. Choose a suitable FastConditionHandler as Map key and assign a FastConditionList:
const FastSwitch(
name: 'switch',
titleText: 'Disable text field when selected',
),
FastTextField(
name: 'text_field',
labelText: 'Just some sample text field',
conditions: {
FastCondition.disabled: FastConditionList([]),
},
)
copied to clipboard
Note
A FastConditionHandler is a function that runs whenever a FastConditionList is checked and determines what happens when the condition is either met or not.
3. Add a FastCondition relating the field to another field:
const FastSwitch(
name: 'switch',
titleText: 'Disable text field when selected',
),
FastTextField(
name: 'text_field',
labelText: 'Just some sample text field',
conditions: {
FastCondition.disabled: FastConditionList([
FastCondition(
target: 'switch',
test: (value, field) => value is bool && value,
),
]),
},
),
copied to clipboard
Note
target is the name of the FastFormField that the form field depends on.
📓 Example: A FastTextField that is enabled when a FastSwitch or a FastCheckbox is selected.
const FastCheckbox(
name: 'checkbox',
titleText: 'Enable text field when selected',
),
const FastSwitch(
name: 'switch',
titleText: 'Enable text field when selected',
),
FastTextField(
name: 'text_field',
enabled: false,
labelText: 'Just some sample text field',
conditions: {
FastCondition.enabled: FastConditionList([
FastCondition(
target: 'switch',
test: (value, field) => value is bool && value,
),
FastCondition(
target: 'checkbox',
test: (value, field) => value is bool && value,
),
]),
},
),
copied to clipboard
📓 Example: A FastTextField that is disabled when both a FastSwitch and a FastCheckbox are selected.
const FastCheckbox(
name: 'checkbox',
titleText: 'Disable text field when selected',
),
const FastSwitch(
name: 'switch',
titleText: 'Disable text field when selected',
),
FastTextField(
name: 'text_field',
labelText: 'Just some sample text field',
conditions: {
FastCondition.enabled: FastConditionList(
[
FastCondition(
target: 'switch',
test: (value, field) => value is bool && value,
),
FastCondition(
target: 'checkbox',
test: (value, field) => value is bool && value,
),
],
match: FastConditionMatch.every,
),
},
),
copied to clipboard
Note
match specifies how all individual test results in the list are evaluated to determine whether the condition is met.
Custom Form Fields #
There are use cases where the widget catalog does not fully satisfy your individual requirements.
As a consequence you have to add non-standard controls to your form.
With Flutter Fast Forms you're free to wrap any custom widget into a form field.
📓 Example: A simple widget that provides a random integer whenever a button is pressed.
1. Create a stateful widget class extending FastFormField<T> with a corresponding FastFormFieldState<T>:
class MyCustomField extends FastFormField<int> {
const MyCustomField({
super.builder = myCustomFormFieldBuilder,
super.key,
required super.name,
});
@override
MyCustomFieldState createState() => MyCustomFieldState();
}
class MyCustomFieldState extends FastFormFieldState<int> {
@override
MyCustomField get widget => super.widget as MyCustomField;
}
copied to clipboard
Note
builder and name are required constructor parameters of FastFormField.
builder is a standard Flutter FormFieldBuilder<T>.
2. Implement the FormFieldBuilder<T> returning your custom widget:
Widget myCustomFormFieldBuilder(FormFieldState<int> field) {
field as MyCustomFieldState;
final MyCustomFieldState(:decoration, :didChange, :value) = field;
return InputDecorator(
decoration: decoration,
child: Row(
children: [
ElevatedButton(
child: const Text('Create random number'),
onPressed: () => didChange(Random().nextInt(1 << 32)),
),
if (value is int)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Text(value.toString()),
)
],
),
);
}
copied to clipboard
Note
Casting field is mandatory to access FastFormField properties and functions.
Always call field.didChange() to update the value of the form field.
3. Add all super-initializer parameters that the form field should support:
class MyCustomField extends FastFormField<int> {
const MyCustomField({
super.builder = myCustomFormFieldBuilder,
super.decoration,
super.enabled,
super.helperText,
super.initialValue,
super.key,
super.labelText,
required super.name,
super.onChanged,
super.onReset,
super.onSaved,
super.onTouched,
super.validator,
});
@override
MyCustomFieldState createState() => MyCustomFieldState();
}
copied to clipboard
Note
Always make sure that you apply certain super-initializer parameters like decoration or enabled in your builder functions.
Otherwise assigning those arguments when invoking the constructor won't have any effect.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.