flutter_form_builder 3.0.0-beta.10

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 95

Flutter FormBuilder - flutter_form_builder #

This package helps in generation of forms in Flutter by providing the syntactic sugar for creating a Form Widget and reduce the boilerplate needed to build a form, validate fields, react to changes, and collect the value of the Form in the form of a map.

The package also comes with common validation functions that can be easily composable to enforce the DRY Principle in code-base.

Simple Usage #

To use this plugin, add flutter_form_builder as a dependency in your pubspec.yaml file.

Example #

final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();

Note: Avoid defining the GlobalKey inside your build method because this will create a new GlobalKey on every build cycle bringing about some erratic behavior.

Column(
  children: <Widget>[
    FormBuilder(
      context,
      key: _fbKey,
      autovalidate: true,
      child: Column(
        children: <Widget>[
          FormBuilderDateTimePicker(
            attribute: "date",
            inputType: InputType.date,
            format: DateFormat("yyyy-MM-dd"),
            decoration:
                InputDecoration(labelText: "Appointment Time"),
          ),
          FormBuilderSlider(
            attribute: "slider",
            validators: [FormBuilderValidators.min(6)],
            min: 0.0,
            max: 10.0,
            initialValue: 1.0,
            divisions: 20,
            decoration:
                InputDecoration(labelText: "Number of somethings"),
          ),
          FormBuilderCheckbox(
            attribute: 'accept_terms',
            initialValue: false,
            label: Text(
                "I have read and agree to the terms and conditions"),
            validators: [
              FormBuilderValidators.requiredTrue(
                errorMessage:
                    "You must accept terms and conditions to continue",
              ),
            ],
          ),
          FormBuilderDropdown(
            attribute: "gender",
            decoration: InputDecoration(labelText: "Gender"),
            // initialValue: 'Male',
            hint: Text('Select Gender'),
            validators: [FormBuilderValidators.required()],
            items: ['Male', 'Female', 'Other']
              .map((gender) => DropdownMenuItem(
                 value: gender,
                 child: Text("$gender")
            )).toList(),
          ),
          FormBuilderTextField(
            attribute: "age",
            decoration: InputDecoration(labelText: "Age"),
            validators: [
              FormBuilderValidators.numeric(),
              FormBuilderValidators.max(70),
            ],
          ),
          FormBuilderRadio(
            decoration:
                InputDecoration(labelText: 'My chosen language'),
            attribute: "best_language",
            validators: [FormBuilderValidators.required()],
            options: [
              "Dart",
              "Kotlin",
              "Java",
              "Swift",
              "Objective-C"
            ]
                .map((lang) => FormBuilderFieldOption(value: lang))
                .toList(growable: false),
          ),
          FormBuilderSegmentedControl(
            decoration:
                InputDecoration(labelText: "Movie Rating (Archer)"),
            attribute: "movie_rating",
            options: List.generate(5, (i) => i + 1)
                .map(
                    (number) => FormBuilderFieldOption(value: number))
                .toList(),
          ),
          FormBuilderSwitch(
            label: Text('I Accept the tems and conditions'),
            attribute: "accept_terms_switch",
            initialValue: true,
          ),
          FormBuilderStepper(
            decoration: InputDecoration(labelText: "Stepper"),
            attribute: "stepper",
            initialValue: 10,
            step: 1,
          ),
          FormBuilderRate(
            decoration: InputDecoration(labelText: "Rate this form"),
            attribute: "rate",
            iconSize: 32.0,
            initialValue: 1,
            max: 5,
          ),
          FormBuilderCheckboxList(
            decoration:
            InputDecoration(labelText: "The language of my people"),
            attribute: "languages",
            initialValue: ["Dart"],
            options: [
              FormBuilderFieldOption(value: "Dart"),
              FormBuilderFieldOption(value: "Kotlin"),
              FormBuilderFieldOption(value: "Java"),
              FormBuilderFieldOption(value: "Swift"),
              FormBuilderFieldOption(value: "Objective-C"),
            ],
          ),
          FormBuilderSignaturePad(
            decoration: InputDecoration(labelText: "Signature"),
            attribute: "signature",
            height: 100,
          ),
        ],
      ),
    ),
    Row(
      children: <Widget>[
        MaterialButton(
          child: Text("Submit"),
          onPressed: () {
            _fbKey.currentState.save();
            if (_fbKey.currentState.validate()) {
              print(_fbKey.currentState.value);
            }
          },
        ),
        MaterialButton(
          child: Text("Reset"),
          onPressed: () {
            _fbKey.currentState.reset();
          },
        ),
      ],
    )
  ],
)

Input widgets #

The currently supported fields include:

  • FormBuilderCheckbox - Single Checkbox field
  • FormBuilderCheckboxList - List of Checkboxes for multiple selection
  • FormBuilderChipsInput - Takes a list of Chips as input
  • FormBuilderDateTimePicker - For Date, Time and DateTime input
  • FormBuilderDropdown - Allow selection of one value from a list as a Dropdown
  • FormBuilderRadio - Allow selection of one value from a list of Radio Widgets
  • FormBuilderRate - For selection of a numerical value as a rating
  • FormBuilderSegmentedControl - For selection of a value from the CupertinoSegmentedControl as an input
  • FormBuilderSignaturePad - Presents a drawing pad on which user can doodle
  • FormBuilderSlider - For selection of a numerical value on a slider
  • FormBuilderStepper - Selection of a number by tapping on a plus or minus symbol
  • FormBuilderSwitch - On/Off switch
  • FormBuilderTextField - For text input. Allows input of single-line text, multi-line text, password, email, urls etc by using different configurations and validators
  • FormBuilderTypeAhead - Auto-completes user input from a list of items

In order to create an input field in the form, along with the label, and any applicable validation, there are several attributes that are supported by all types of inputs namely:

AttributeTypeDefaultRequiredDescription
attributeStringnulltrueThis will form the key in the form value Map
initialValuedynamicnullfalseThe initial value of the input field
readonlyboolfalsefalseDetermines whether the field widget will accept user input. This value will be ignored if the readonly attribute of FormBuilder widget is set to true
decorationInputDecorationInputDecoration()false
validatorsList<FormFieldValidator>[]falseList of FormFieldValidators that will check the validity of value candidate in the FormField
onChangedValueChanged<T>nullfalseThis event function will fire immediately the the field value changes
valueTransformerValueTransformer<T>nullfalseFunction that transforms field value before saving to form value. e.g. transform TextField value for numeric field from String to num
The rest of the attributes will be determined by the type of Widget being used.

Building your own custom FormField

FormBuilderCustomField(
  attribute: "name",
  validators: [
    FormBuilderValidators.required(),
  ],
  formField: FormField(
    enabled: true,
    builder: (FormFieldState<dynamic> field) {
      return InputDecorator(
        decoration: InputDecoration(
          labelText: "Select option",
          contentPadding:
              EdgeInsets.only(top: 10.0, bottom: 0.0),
          border: InputBorder.none,
        ),
        child: DropdownButton(
          isExpanded: true,
          items: ["One", "Two"].map((option) {
            return DropdownMenuItem(
              child: Text("$option"),
              value: option,
            );
          }).toList(),
          value: field.value,
          onChanged: (value) {
            field.didChange(value);
          },
        ),
      );
    },
  ),
),

Validation #

The validators attribute in fields take in any number of FormFieldValidator allowing composability of validation functions as well as allow reusability of already defined validator methods.

Built-in Validators #

The package comes with several most common FormFieldValidators such as required, numeric, mail, URL, min, max, minLength, maxLength, IP, credit card etc. with default errorText in English but with ability to include you own error message that will display whenever validation fails. Validation example:

FormBuilderTextField(
  attribute: "age",
  decoration: InputDecoration(labelText: "Age"),
  validators: [
    FormBuilderValidators.numeric(),
    FormBuilderValidators.max(70),
  ],
),

Custom validator function #

As well as the built-in validators any function of type FormFieldValidator will be accepted into the list of validators.

FormBuilderTextField(
    attribute: "over_18",
    decoration: InputDecoration(labelText: "Are you over 18?"),
    validators: [
        FormBuilderValidators.required(),
        (val){
            if(val.toLowerCase() != "yes")
                return "The answer must be Yes";
        },
    ],
),

Conditional validation #

You can now validate a field based on the value of another field

FormBuilderRadio(
  decoration: InputDecoration(labelText: 'My best language'),
  attribute: "best_language",
  validators: [FormBuilderValidators.required()],
  options: [
    "Dart",
    "Kotlin",
    "Java",
    "Swift",
    "Objective-C",
    "Other"
  ]
      .map((lang) => FormBuilderFieldOption(value: lang))
      .toList(growable: false),
),
FormBuilderTextField(
    attribute: "specify",
    decoration: InputDecoration(labelText: "If Other, please specify"),
    validators: [
        (val){
            if(_fbKey.currentState.fields['best_language'].currentState.value == "Other" && (val == null || val.isEmpty))
                return "Kindly specify your language";
        },
    ],
),

CREDITS #

This package is dependent on the following packages and plugins:

TODO: #

Improvements #

  • [X] Allow addition of custom input types
  • [X] Improve documentation by showing complete list of input types and their usage and options
  • [X] Create a transformer function option that will convert field value when field id saved - can be used to convert string to number, change to uppercase etc.
  • [X] Assert no duplicates in FormBuilderInputs attribute names
  • [ ] Allow options for Checkboxes and Radios to appear left or right

New FormBuilder inputs #

KNOWN ISSUES #

Form's reset() doesn't clear SignaturePad - You'll be forced to clear manually

[3.0.0-beta.10] - 20-April-2019

  • Unregister field from Formbuilder when its dispose method is called. Avoids assertion fail when re-added back to the widget tree

[3.0.0-beta.9] - 15-April-2019

  • Added property fields to FormBuilder, gives access to the current state of each field through a Map of GlobalKey<FormFieldState<dynamic>>s. This gives us access to the underlying FormField which in turn allows us:
    • Do conditional validation based on other fields (check readme)
    • Dynamically update field values

[3.0.0-beta.8] - 10-April-2019

  • Fixed unhandled exception when valueTransformer tries to convert value from predefined FormField type

[3.0.0-beta.7] - 09-April-2019

  • Check if value candidate is of type String, Iterable or Map before checking length to determine empty in FormValidators.required

[3.0.0-beta.6] - 09-April-2019

  • Properly hooked up SignaturePad to form, added onChanged to it
  • SignaturePad now returns Uint8List object from png image

[3.0.0-beta.5] - 08-April-2019

  • Minor documentation improvements - hint for GlobalKey definition, table rendering issue in README

[3.0.0-beta.4] - 08-April-2019

  • Breaking changes:
    • FormBuilderInputOption becomes FormBuilderFieldOption
    • FormBuilderField becomes FormBuilderCustomField
  • Improved documentation
  • added valueTransformer - transforms field value before saving to form value

[3.0.0-beta.3] - 07-April-2019

  • Bumped up flutter_typeahead dependency from ^1.2.1 to ^1.4.0
  • Fixed URL validator works correctly - tested
  • Added more validators:
    • IP
    • Credit Card
    • Date
  • Added requested onChanged value notifier event on fields. Closes #45

[3.0.0-beta.2] - 04-April-2019

  • Disabled TextFormField.strutStyle from FormBuilderTextField breaks in v1.2.1 of Flutter - current stable at release

[3.0.0-beta.1] - 04-April-2019

  • Complete rewrite of the package - stateful
  • Contains FormBuilderField for creation of custom FormFields
  • New attribute validators allows composability and reusability of different FormFieldValidator functions that do different validations
  • New Feature FormBuilderValidators comes with common validation functionality options such as: required, min, max,

[2.0.3] - 26-March-2019

  • Allow nulls in FormBuilder controls attribute

[2.0.2] - 26-March-2019

  • Minor fix in documentation

[2.0.1] - 26-March-2019

  • Fixed bug where fields keep losing focus

[2.0.0] - 25-March-2019

New Features and fixes #

  • New attribute decoration for FormBuilderInput. Enables one to customize InputDecoration like icons, labelStyles etc
  • Added ability to add GlobalKey of type FormBuilderState to FormBuilder that will be the handle to the state of the form enabling saving and resetting. Similar to using Flutter's Form.
  • Added new input type FormBuilder.signaturePad which provides a drawing pad for user signature
  • Added max attribute to chipsInput to limit the number of chips users can add
  • Added new attribute maxLines to be used with textFields with multiple lines
  • Fixed bug where readonly not working to Date, Time and DateTime Pickers

Breaking Changes #

  • Removed reset/submit buttons and corresponding attributes: showResetButton, resetButtonContent Access form state using a GlobalKey<FormBilderState>
  • Removed label and hint attributes to be replaced by decoration

[1.5.1] - 21-March-2019

  • Fixed bugs originating from upgrading flutter_typeahead from v0.5.1 to v1.2.1

[1.5.0] - 20-March-2019

  • Now using datetime_picker_formfield plugin from pub for DatePicker and TimePicker. Should close #33
  • Added new FormBuilderInput - DateTimePicker
  • Breaking change: DatePicker, TimePicker & DateTimePicker now return an object of type DateTime instead of String
  • Upgraded flutter_typeahead from v0.5.1 to v1.2.1 - comes with more widgets options

[1.4.0] - 29-Jan-2019

  • The entire form or individual controls can now be made readonly by making readonly property to true. Default value is false. Closes #11 and #16

[1.3.5] - 28-Jan-2019

  • Fixed bug on Slider where current value not updated on slider & label

[1.3.4] - 19-Jan-2019

Bug fix: Imported dart:async for use of Futures to be compatible with Dart <2.1

[1.3.3] - 17-Jan-2019

  • Updated flutter_typeahead version. Closes #15

[1.3.2] - 19-Dec-2018

  • Allow setting of format for DatePicker
  • Fixed bug where lastDate and firstDate for DatePicker don't work

[1.3.1] - 17-Dec-2018

  • Moved ChipsInput into own library on pub.dartlang.org, check it out here
  • Updated example code to include proper use of Form's onChanged function after update. Closes #8

[1.3.0] - 15-Dec-2018

  • Fixed bug where TypeAhead value reset when other fields are updated
  • onChanged function for FormBuilder is now called with current form values (breaking change)
  • Form reset now works as expected
  • Other minor refactorings

[1.2.0] - 23-Nov-2018

  • New FormBuilderInput types:
    • ChipsInput
  • Some bug fixes
  • Minor UI improvements
  • Some bugs introduced, to be fixed later

[1.1.0] - 19-Nov-2018

  • Fixed bug where validation not working for fields outside screen (when using ListView) - Flutter Issue #17385
  • Added InputDecoration for all custom FormFields

[1.0.2] - 7-Nov-2018

  • Fixed bug in (un)selecting checkbox list using by clicking its label

[1.0.1] - 3-Nov-2018

  • Minor improvements to documentation, added known issues section too

[1.0.0] - 3-Nov-2018

Features #

  • New FormBuilderInput types:
    • Phone
    • Stepper
    • Rate
    • SegmentedControl
  • min and max validation added to number field and textField
  • More specialized keyboard types for TextField control types (text, number, url, email, multiline, phone etc)
  • Tapping on Label for radio/checkbox changes the control value
  • Created new constructors for password and textField inputs
  • Added resetButton

Fixes #

  • Fixed bug where TYPE_TEXT validates as TYPE_EMAIL - Closes #1
  • Fixed initial value setting FormBuilderInput.checkboxList()

Breaking Changes #

  • placeholder attribute of class FormBuilderInput renamed to hint
  • Removed default constructor for FormBuilderInput

[0.0.1] - 1-Nov-2018.

  • Initial Release
  • Input Types:
    • Text
    • Number
    • Email
    • MultilineText
    • Password
    • Radio
    • CheckboxList
    • Checkbox
    • Switch
    • Slider
    • Dropdown
    • DatePicker
    • TimePicker
    • Url
    • TypeAhead

example/README.md

example #

A new Flutter project.

Getting Started #

FormBuilder(
  context,
  autovalidate: true,
  controls: [
    FormBuilderInput.textField(
      type: FormBuilderInput.TYPE_TEXT,
      attribute: "name",
      label: "Name",
      require: true,
      min: 3,
    ),
    FormBuilderInput.dropdown(
      attribute: "dropdown",
      require: true,
      label: "Dropdown",
      hint: "Select Option",
      options: [
        FormBuilderInputOption(value: "Option 1"),
        FormBuilderInputOption(value: "Option 2"),
        FormBuilderInputOption(value: "Option 3"),
      ],
    ),
    FormBuilderInput.number(
      attribute: "age",
      label: "Age",
      require: true,
      min: 18,
    ),
    FormBuilderInput.textField(
      type: FormBuilderInput.TYPE_EMAIL,
      attribute: "email",
      label: "Email",
      require: true,
    ),
    FormBuilderInput.textField(
      type: FormBuilderInput.TYPE_URL,
      attribute: "url",
      label: "URL",
      require: true,
    ),
    FormBuilderInput.textField(
      type: FormBuilderInput.TYPE_PHONE,
      attribute: "phone",
      label: "Phone",
      //require: true,
    ),
    FormBuilderInput.password(
      attribute: "password",
      label: "Password",
      //require: true,
    ),
    FormBuilderInput.datePicker(
      label: "Date of Birth",
      attribute: "dob",
    ),
    FormBuilderInput.timePicker(
      label: "Appointment Time",
      attribute: "time",
    ),
    FormBuilderInput.checkboxList(
      label: "My Languages",
      attribute: "languages",
      require: false,
      value: ["Dart"],
      options: [
        FormBuilderInputOption(value: "Dart"),
        FormBuilderInputOption(value: "Kotlin"),
        FormBuilderInputOption(value: "Java"),
        FormBuilderInputOption(value: "Swift"),
        FormBuilderInputOption(value: "Objective-C"),
      ],
    ),
    FormBuilderInput.radio(
      label: "My Best Language",
      attribute: "best_language",
      require: true,
      options: [
        FormBuilderInputOption(value: "Dart"),
        FormBuilderInputOption(value: "Kotlin"),
        FormBuilderInputOption(value: "Java"),
        FormBuilderInputOption(value: "Swift"),
        FormBuilderInputOption(value: "Objective-C"),
      ],
    ),
    FormBuilderInput.checkbox(
      label: "I accept the terms and conditions",
      attribute: "accept_terms",
      hint: "Kindly make sure you've read all the terms and conditions",
      validator: (value){
        if(!value)
          return "Accept terms to continue";
      }
    ),
    FormBuilderInput.slider(
      label: "Slider",
      attribute: "slider",
      hint: "Hint",
      min: 0.0,
      require: true,
      max: 100.0,
      value: 10.0,
      divisions: 20,
    ),
    FormBuilderInput.stepper(
      label: "Stepper",
      attribute: "stepper",
      value: 10,
      step: 1,
      hint: "Hint",
    ),
    FormBuilderInput.rate(
      label: "Rate",
      attribute: "rate",
      iconSize: 48.0,
      value: 1,
      max: 5,
      hint: "Hint",
    ),
    FormBuilderInput.segmentedControl(
        label: "Movie Rating (Archer)",
        attribute: "movie_rating",
        require: true,
        options: [
          FormBuilderInputOption(
            value: 1,
          ),
          FormBuilderInputOption(
            value: 2,
          ),
          FormBuilderInputOption(
            value: 3,
          ),
          FormBuilderInputOption(
            value: 4,
          ),
          FormBuilderInputOption(
            value: 5,
          ),
          FormBuilderInputOption(
            value: 6,
          ),
          FormBuilderInputOption(
            value: 7,
          ),
          FormBuilderInputOption(
            value: 8,
          ),
          FormBuilderInputOption(
            value: 9,
          ),
          FormBuilderInputOption(
            value: 10,
          ),
        ]),
  ],
  onChanged: () {
    print("Form Changed");
  },
  onSubmit: (formValue) {
    if (formValue != null) {
      print(formValue);
    } else {
      print("Form invalid");
    }
  },
),

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  flutter_form_builder: ^3.0.0-beta.10

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_form_builder/flutter_form_builder.dart';
  
Version Uploaded Documentation Archive
3.1.1 May 16, 2019 Go to the documentation of flutter_form_builder 3.1.1 Download flutter_form_builder 3.1.1 archive
3.1.0 May 15, 2019 Go to the documentation of flutter_form_builder 3.1.0 Download flutter_form_builder 3.1.0 archive
3.0.1 Apr 28, 2019 Go to the documentation of flutter_form_builder 3.0.1 Download flutter_form_builder 3.0.1 archive
3.0.0 Apr 24, 2019 Go to the documentation of flutter_form_builder 3.0.0 Download flutter_form_builder 3.0.0 archive
2.1.0 Apr 5, 2019 Go to the documentation of flutter_form_builder 2.1.0 Download flutter_form_builder 2.1.0 archive
2.0.3 Mar 26, 2019 Go to the documentation of flutter_form_builder 2.0.3 Download flutter_form_builder 2.0.3 archive
2.0.2 Mar 26, 2019 Go to the documentation of flutter_form_builder 2.0.2 Download flutter_form_builder 2.0.2 archive
2.0.1 Mar 26, 2019 Go to the documentation of flutter_form_builder 2.0.1 Download flutter_form_builder 2.0.1 archive
2.0.0 Mar 25, 2019 Go to the documentation of flutter_form_builder 2.0.0 Download flutter_form_builder 2.0.0 archive
1.5.1 Mar 21, 2019 Go to the documentation of flutter_form_builder 1.5.1 Download flutter_form_builder 1.5.1 archive

All 34 versions...

Popularity:
Describes how popular the package is relative to other packages. [more]
92
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
95
Overall:
Weighted score of the above. [more]
95
Learn more about scoring.

We analyzed this package on May 22, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.3.1
  • pana: 0.12.16
  • Flutter: 1.5.4-hotfix.2

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Maintenance suggestions

Package is pre-release. (-5 points)

Pre-release versions should be used with caution; their API can change in breaking ways.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.68.0 <3.0.0
datetime_picker_formfield ^0.1.8 0.1.8
flutter 0.0.0
flutter_chips_input ^1.2.0 1.2.0
flutter_typeahead ^1.4.0 1.6.0
intl ^0.15.7 0.15.8
sy_flutter_widgets ^0.1.4 0.1.4
validators ^2.0.0 2.0.0+1
Transitive dependencies
collection 1.14.11
keyboard_visibility 0.5.6
meta 1.1.6 1.1.7
path 1.6.2
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test
test 1.5.3