flutter_fast_forms 4.0.0 flutter_fast_forms: ^4.0.0 copied to clipboard
Enhances the Flutter SDK with form field wrappers, adaptive form field widgets and validation states to speed up form development.
Flutter Fast Forms #
Flutter Fast Forms is a Dart package for building Flutter forms fast.
It adds these missing pieces to the Flutter SDK to make Flutter form development a breeze:
FormField<T>
wrappers for all Material / Cupertino input widgets according to the already built-in TextFormField / DropdownButtonFormField- adaptive and highly customizable
FastFormControl<T>
widgets with support of validation states. FastForm
widget that passes current form field values toonChanged
FastInputChips
widget that converts text input into chips as defined by Material Design- common
FormFieldValidator<T>
functions
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: [],
),
),
),
);
}
}
2. Add FastFormControl<T>
children to build up your form:
child: FastForm(
formKey: formKey,
children: [
FastTextField(
name: 'field_destination',
label: 'Destination',
placeholder: 'Where are you going?',
),
FastDateRangePicker(
name: 'field_check_in_out',
label: 'Check-in - Check-out',
firstDate: DateTime.now(),
lastDate: DateTime.now().add(const Duration(days: 365)),
),
FastCheckbox(
name: 'field_travel_purpose',
label: 'Travel purpose',
title: 'I am travelling for work',
),
],
)
3. Wrap children with FastFormSection
for grouping and consistent padding:
child: FastForm(
formKey: formKey,
children: [
FastFormSection(
header: const Text('My Form'),
padding: EdgeInsets.all(16.0),
children: [
FastTextField(
name: 'field_destination',
label: 'Destination',
placeholder: 'Where are you going?',
),
// ...
],
),
]
)
Widget Catalog #
adaptiveFastFormControl<T> |
adopts Material |
adopts Cupertino |
requires Material Widget ancestor when adaptive: true |
---|---|---|---|
FastAutocomplete |
Autocomplete |
no | yes |
FastCheckbox |
CheckboxListTile |
no | yes |
FastChoiceChips |
ChoiceChip |
no | yes |
FastCalendar |
CalendarDatePicker |
no | yes |
FastDatePicker |
showDatePicker |
CupertinoDatePicker |
no |
FastDateRangePicker |
showDateRangePicker |
no | yes |
FastDropdown |
DropdownButtonFormField <String> |
no | yes |
FastInputChips |
Autocomplete + InputChip |
no | yes |
FastRadioGroup |
RadioListTile |
no | yes |
FastRangeSlider |
RangeSlider |
no | yes |
FastSegmentedControl |
no | SlidingSegmenteControl <String> |
no |
FastSlider |
Slider.adaptive |
CupertinoSlider |
no |
FastSwitch |
SwitchListTile |
CupertinoSwitch |
no |
FastTextField |
TextFormField |
CupertinoTextFormFieldRow |
no |
FastTimePicker |
showTimePicker |
no / use FastDatePicker with CupertinoDatePickerMode.time |
yes |
Custom Form Field Widgets #
With Flutter Fast Forms transforming any custom widget into a form field goes smoothly.
Let's assume a simple form field that provides a random integer whenever a button is pressed.
- Create a minimal
FastFormField<T>
and a correspondingFastFormFieldState<T>
:
class MyCustomField extends FastFormField<int> {
const MyCustomField({
Key? key,
required String name,
}) : super(
builder: _myCustomFormFieldBuilder,
key: key,
name: name,
);
@override
MyCustomFieldState createState() => MyCustomFieldState();
}
class MyCustomFieldState extends FastFormFieldState<int> {
@override
FastSimpleCustomField get widget => super.widget as FastSimpleCustomField;
}
- Add optional parameters and pass them as you like:
class MyCustomField extends FastFormField<int> {
const MyCustomField({
InputDecoration? decoration,
String? helperText,
int? initialValue,
Key? key,
String? label,
required String name,
ValueChanged<int>? onChanged,
VoidCallback? onReset,
FormFieldSetter<int>? onSaved,
FormFieldValidator<int>? validator,
}) : super(
builder: _myCustomFormFieldBuilder,
helperText: helperText,
initialValue: initialValue,
key: key,
label: label,
name: name,
onChanged: onChanged,
onReset: onReset,
onSaved: onSaved,
validator: validator,
);
@override
MyCustomFieldState createState() => MyCustomFieldState();
}
class MyCustomFieldState extends FastFormFieldState<int> {
@override
FastSimpleCustomField get widget => super.widget as FastSimpleCustomField;
}
- Implement the required
FormFieldBuilder<T>
:
Widget _myCustomFormFieldBuilder(FormFieldState<int> field) {
final decoration = (field as FastSimpleCustomFieldState)
.decoration
.copyWith(errorText: field.errorText);
return InputDecorator(
decoration: decoration,
child: Row(
children: [
ElevatedButton(
child: const Text('Create random number'),
onPressed: () => field.didChange(Random().nextInt(1 << 32)),
),
if (field.value is int)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Text(field.value!.toString()),
)
],
),
);
}