Create better Forms in Flutter using flutter_form_builder
Forms are essential for gathering information from users in mobile applications. In this post, we will learn how to create better forms in Flutter using the flutter_form_builder package. We will start by installing the necessary components and understanding how to use different form fields like checkboxes, dropdowns, and date pickers to collect user input. Then, we will look into validation using the form_builder_validators package, which helps ensure users provide accurate information. Finally, we will cover all the available fields from the flutter_form_builder package.
Installing
To get started, we need to install the flutter_form_builder and form_builder_validators packages into our project. The installation process is simple. Just execute the following command: flutter pub add flutter_form_builder form_builder_validators
.
Once the command is executed, make sure to check your pubspec.yaml
file for the added dependencies. You should see the flutter_form_builder and form_builder_validators packages included in the dependencies section, like this:
dependencies:
flutter:
sdk: flutter
flutter_form_builder: ^9.1.0
form_builder_validators: ^9.0.0
Implementation
With these packages integrated into our project, we can start by creating our first form, see the following code:
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FormPage(),
);
}
}
class FormPage extends StatelessWidget {
final GlobalKey<FormBuilderState> _formKey = GlobalKey<FormBuilderState>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Form Builder Demo'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: FormBuilder(
key: _formKey,
child: Column(
children: [
FormBuilderTextField(
name: 'email',
decoration: InputDecoration(labelText: 'Email'),
),
SizedBox(height: 10),
FormBuilderDropdown(
name: 'gender',
decoration: InputDecoration(labelText: 'Gender'),
items: ['Male', 'Female', 'Other']
.map((gender) => DropdownMenuItem(
value: gender,
child: Text(gender),
))
.toList(),
),
SizedBox(height: 10),
FormBuilderDateTimePicker(
name: 'birthdate',
decoration: InputDecoration(labelText: 'Birthdate'),
inputType: InputType.date,
initialDate: DateTime.now(),
initialValue: DateTime.now(),
firstDate: DateTime(1900),
lastDate: DateTime.now(),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.saveAndValidate()) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Form data'),
content: Text(
_formKey.currentState!.value.entries
.map((entry) => '${entry.key}: ${entry.value}')
.join('\n'),
style: TextStyle(fontSize: 18),
),
actions: [
ElevatedButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('OK', style: TextStyle(fontSize: 20)),
),
],
),
);
}
},
child: Text('Submit'),
),
],
),
),
),
);
}
}
In this code snippet, we created a simple application that has a MaterialApp
that has the FormPage
widget set as the home
property. The FormPage
widget has a private _formKey
variable that is set to GlobalKey<FormBuilderState>()
. This variable is needed inside the FormBuilder
widget.
The FormBuilder
widget is used to wrap the form fields and provide the form state management. The form fields are created using FormBuilderTextField
, FormBuilderDropdown
, and FormBuilderDateTimePicker
. Each form field has a name
, which will be used to identify the field and retrieve its value later.
When the user clicks the "Submit" button, the form data is saved and validated using the _formKey.currentState!.saveAndValidate()
method. If the data is valid, an AlertDialog
is shown, displaying the form data. The form data is accessed from the _formKey.currentState!.value
map.

Validation
Data validation is important when creating forms because it ensures that users provide the right information that is needed. The form_builder_validators package helps us set up rules for validation. For example, we can make sure certain fields are filled, check that email addresses are in the correct format, and set limits on numbers. These rules help users know if they have entered the data correctly, and it stops them from sending wrong or incomplete information.
FormBuilderTextField(
name: 'email',
decoration: InputDecoration(labelText: 'Email'),
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
FormBuilderValidators.email(),
]),
),
In this code snippet, we added the validator
property and used the FormBuilderValidators.compose
function to set validations. The function takes a list of FormBuilderValidators
:
FormBuilderValidators.required
: The field cannot be left empty.FormBuilderValidators.email
: The entered text should be in a valid email format.
When the form is submitted, the FormBuilder
widget automatically validates this field based on these rules. If the validation passes, the entered email is considered valid and can be accessed from the form state using the identifier "email" _formKey.currentState!.value['email']
.

All possible validation rules
creditCard
: Validates that the field's value is a valid credit card number.date
: Validates that the field's value is a valid date.email
: Validates that the field contains a valid email address format.equal(Object value)
: Validates that the field's value is equal to the value of another field specified byvalue
.equalLength(int length)
: Validates that the field's value is equal to the provided length.integer
: Validates that the field's value is a valid integer.ip
: Validates that the field's value is a valid IP address.match(String pattern)
: Validates that the field's value matches the provided regex pattern.max(num max)
: Validates that the field's value is less than or equal to the provided number.maxLength(int maxLength)
: Validates that the field's value has a maximum length ofmaxLength
.maxWordsCount(int maxCount)
: Validates that the field's value is less than or equal to the provided maximum count.mim(num min)
: Validates that the field's value is greater than or equal to the provided number.minLength(int minLength)
: Validates that the field's value has a minimum length ofminLength
.minWordsCount(int minCount)
: Validates that the field's value is greater than or equal to the provided minimum count.notEqual(Object value)
: Validates that the field's value is not equal to the providedvalue
.numeric
: Validates that the field's value is a valid numeric value.required
: Validates that the field is not empty and has a value.url
: Validates that the field's value is a valid URL.
Available fields
The flutter_form_builder package gives us many ready-to-use form fields for different types of data and ways users interact with them. We have checkboxes, dropdowns, date pickers, and slider inputs, among others. We can easily use these fields in our forms. They are flexible and can be customized to suit our application's requirements, making it simple to create interactive and engaging forms. All the available fields are listed below with an example:
1. FormBuilderCheckbox
Represents a single checkbox field.
FormBuilderCheckbox(
name: 'checkbox_field',
title: Text('Checkbox'),
initialValue: false,
onChanged: (value) {},
),

2. FormBuilderCheckboxGroup
Represents a list of checkboxes for multiple selections.
FormBuilderCheckboxGroup(
name: 'checkbox_group_field',
options: [
FormBuilderFieldOption(value: 'Option 1'),
FormBuilderFieldOption(value: 'Option 2'),
FormBuilderFieldOption(value: 'Option 3'),
],
onChanged: (value) {},
),

3. FormBuilderChoiceChip
Creates a chip that acts like a radio button for selecting one choice from a list.
FormBuilderChoiceChip(
name: 'choice_chip_field',
options: [
FormBuilderChipOption(value: 'Option 1'),
FormBuilderChipOption(value: 'Option 2'),
FormBuilderChipOption(value: 'Option 3'),
],
onChanged: (value) {},
),

4. FormBuilderDateRangePicker
Allows users to select a range of dates.
FormBuilderDateRangePicker(
name: 'date_range_field',
onChanged: (value) {},
firstDate: DateTime.parse('2021-01-01'),
lastDate: DateTime.parse('2023-12-31'),
),

5. FormBuilderDateTimePicker
Allows users to input Date, Time, or DateTime values.
FormBuilderDateTimePicker(
name: 'date_time_field',
inputType: InputType.date,
initialDate: DateTime.now(),
initialValue: DateTime.now(),
firstDate: DateTime(1900),
lastDate: DateTime.now(),
onChanged: (value) {},
),

6. FormBuilderDropdown
Presents a dropdown list for selecting a single value from a list.
FormBuilderDropdown(
name: 'dropdown_field',
items: ['Option 1', 'Option 2', 'Option 3']
.map((option) => DropdownMenuItem(value: option, child: Text(option)))
.toList(),
onChanged: (value) {},
),

7. FormBuilderFilterChip
Creates a chip that acts as a checkbox for filtering purposes.
FormBuilderFilterChip(
name: 'filter_chip_field',
options: [
FormBuilderChipOption(value: 'Option 1'),
FormBuilderChipOption(value: 'Option 2'),
FormBuilderChipOption(value: 'Option 3'),
],
onChanged: (value) {},
),

8. FormBuilderRadioGroup
Allows users to select one value from a list of Radio Widgets.
FormBuilderRadioGroup(
name: 'radio_group_field',
options: [
FormBuilderFieldOption(value: 'Option 1'),
FormBuilderFieldOption(value: 'Option 2'),
FormBuilderFieldOption(value: 'Option 3'),
],
onChanged: (value) {},
),

9. FormBuilderRangeSlider
Allows users to select a range from a range of values using a slider.
FormBuilderRangeSlider(
name: 'range_slider_field',
min: 0,
max: 100,
initialValue: RangeValues(20, 80),
onChanged: (value) {},
),

10. FormBuilderSlider
Represents a slider for selecting a numerical value.
FormBuilderSlider(
name: 'slider_field',
min: 0,
max: 100,
initialValue: 50,
onChanged: (value) {},
),

11. FormBuilderSwitch
Provides an on/off switch field.
FormBuilderSwitch(
name: 'switch_field',
initialValue: false,
title: Text('Switch'),
onChanged: (value) {},
),

12. FormBuilderTextField
Represents a Material Design text field input for various data types.
FormBuilderTextField(
name: 'text_field',
decoration: InputDecoration(labelText: 'Enter Text'),
onChanged: (value) {},
),

Conclusion
The flutter_form_builder package is a helpful tool for creating user-friendly forms with ease. By using form fields like checkboxes, dropdowns, and date pickers, you can easily collect user information. Additionally, with the form_builder_validators, you can make sure users fill in the required fields correctly and enter valid data. These packages make it simple to build advanced and interactive forms in Flutter, improving the overall experience for your users.