Building a Custom Field with FormBuilder Flutter Package

Danvick Miller
3 min readApr 23, 2022

--

Introduction

flutter_form_builder is a Flutter package that simplifies user input by eliminating most of the boilerplate needed to build a form, validate fields, react to changes, and collect the final form input.

The package provides some of the most common user input fields that you could need — including but not limited to TextField, CheckBox, Switch, Slider, RangeSlider, DropDown, DateTimePicker, etc — out-of-box.

There are, however, so many other widgets you may want to use as input components within your applications’ forms — some provided by Flutter, others by packages on Pub.dev from the Flutter community or even your own custom input widgets.

In this article, we will explore how you could use any user input widget as a custom field within FormBuilder.

Return your widget from FormBuilderField’s builder

First, for you to use any widget as an input field within your FormBuilder, make sure that the input widget has a value-change callback method such as an onChanged, onSelected, etc. Such a method would be helpful to notify the form that the input value for the field has changed.

FormBuilderField — which is the base class of all FormBuilder fields — maintains the current state of the form field and handles the input field’s interaction with the encompassing FormBuilder widget. The FormBuilderField widget provides a builder method within which you will return your widget.

Now, let’s assume we need to use a CupertinoTextField instead of the standard provided FormBuilderTextField widget (based on Material Design’s TextField) and also make a FormBuilder input field out of a CheckboxListTile widget.

In the above code snippet, we returned the widgets we intend to convert to FormBuilder input fields from the builder method of FormBuilderField. Note that we listen to the changes in the CupertinoTextField and CheckBoxListTile then pass the new values along to the FormBuilderField using the didChange() method.

Custom flutter_form_builder fields without styling
Custom flutter_form_builder fields without styling

At this point, everything should be working fine, and FormBuilder should be able to handle the input from the field. The issue now is that our field doesn’t look much like a regular form field — it doesn’t have a label, hints, or helpers, but most importantly — there is no place to display validation errors if form validation fails.

Make the input look more like a field

Flutter’s Material Design provides an InputDecorator widget that displays the visual elements of a Material Design field around its child component.

When using the Cupertino Design system, you can use CupertinoFormRow, which creates an iOS-style split form row with a standard prefix, a child input widget, and space for error and helper widgets that appear underneath.

In the above code, we’ve wrapped the CupertinoTextField with a CupertinoFormRow and the CheckboxListTile with an InputDecorator respectively, both of which allow us to display the field’s errorText and the fields’ label. Note that the FormFieldState, passed into the builder method supplies the errorText to be displayed if validation fails.

As illustrated in the image above the CupertinoTextField and CheckboxListTile are now styled with Cupertino and Material design styles respectively; and if there are errors in the fields, they are displayed on the screen.

--

--

Danvick Miller

Danvick is the Tech Lead for InfinitySoft Tech, an organizer Flutter Nairobi and Droidcon Kenya. He’s also known to practise Open-sourcery on Github.