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 validation rules. 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:

  1. FormBuilderValidators.required: The field cannot be left empty.
  2. 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'].

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.

Tijn van den Eijnde
Tijn van den Eijnde
Articles: 86

Leave a Reply

Your email address will not be published. Required fields are marked *