flutter_form_builder 2.1.0

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

Flutter FormBuilder - flutter_form_builder #

This widget helps in generation of forms in Flutter. Wraps common input types with FormField allowing validation, change detection, setting input value etc and have them in a single form

Saves you some common validations such as: required fields, number, email & url validity, min and max values for numbers, min and max character length for string based fields as well as allow you to include your own custom validation

On submission, the form returns a Map<String, dynamic> of form values if the form is valid or null otherwise.

Usage #

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

Example #

GlobalKey<FormBuilderState> _fbKey = GlobalKey();

SingleChildScrollView(
  Column(
    children: <Widget>[
        FormBuilder(
          context,
          key: _fbKey,
          autovalidate: true,
          readonly: false,
          /*onChanged: (formValue) {
            print(formValue);
          },*/
          controls: [
            FormBuilderInput.typeAhead(
              decoration: InputDecoration(labelText: "Country"),
              attribute: 'country',
              // require: true,
              itemBuilder: (context, country) {
                return ListTile(
                  title: Text(country),
                );
              },
              suggestionsCallback: (query) {
                if (query.length != 0) {
                  var lowercaseQuery = query.toLowerCase();
                  return allCountries.where((country) {
                    return country.toLowerCase().contains(lowercaseQuery);
                  }).toList(growable: false)
                    ..sort((a, b) => a
                        .toLowerCase()
                        .indexOf(lowercaseQuery)
                        .compareTo(
                            b.toLowerCase().indexOf(lowercaseQuery)));
                } else {
                  return allCountries;
                }
              },
            ),
            FormBuilderInput.chipsInput(
              decoration: InputDecoration(labelText: "Chils"),
              attribute: 'chips_test',
              // require: true,
              value: [
                Contact('Andrew', 'stock@man.com',
                    'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg'),
              ],
              max: 1,
              suggestionsCallback: (String query) {
                if (query.length != 0) {
                  var lowercaseQuery = query.toLowerCase();
                  return mockResults.where((profile) {
                    return profile.name
                            .toLowerCase()
                            .contains(query.toLowerCase()) ||
                        profile.email
                            .toLowerCase()
                            .contains(query.toLowerCase());
                  }).toList(growable: false)
                    ..sort((a, b) => a.name
                        .toLowerCase()
                        .indexOf(lowercaseQuery)
                        .compareTo(b.name
                            .toLowerCase()
                            .indexOf(lowercaseQuery)));
                } else {
                  return const <Contact>[];
                }
              },
              chipBuilder: (context, state, profile) {
                return InputChip(
                  key: ObjectKey(profile),
                  label: Text(profile.name),
                  avatar: CircleAvatar(
                    backgroundImage: NetworkImage(profile.imageUrl),
                  ),
                  onDeleted: () => state.deleteChip(profile),
                  materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
                );
              },
              suggestionBuilder: (context, state, profile) {
                return ListTile(
                  key: ObjectKey(profile),
                  leading: CircleAvatar(
                    backgroundImage: NetworkImage(profile.imageUrl),
                  ),
                  title: Text(profile.name),
                  subtitle: Text(profile.email),
                  onTap: () => state.selectSuggestion(profile),
                );
              },
            ),
            FormBuilderInput.textField(
                type: FormBuilderInput.TYPE_TEXT,
                attribute: "name",
                decoration: InputDecoration(labelText: "Full Name"),
                value: "John Doe",
                // require: true,
                // readonly: true,
                require: true,
                // readonly: true,
                min: 3,
            FormBuilderInput.dropdown(
              attribute: "dropdown",
              // require: true,
              decoration: InputDecoration(labelText: "Select options"),
              options: [
                FormBuilderInputOption(value: "Option 1"),
                FormBuilderInputOption(value: "Option 2"),
                FormBuilderInputOption(value: "Option 3"),
              ],
            ),
            FormBuilderInput.number(
              attribute: "age",
              decoration: InputDecoration(labelText: "Your Age"),
              // require: true,
              // min: 18,
            ),
            FormBuilderInput.textField(
              type: FormBuilderInput.TYPE_MULTILINE_TEXT,
              attribute: "story",
              decoration: InputDecoration(labelText: "Story"),
              value: "Here's my story",
              require: false,
              min: 25,
              maxLines: 10,
              autovalidate: true,
            ),
            FormBuilderInput.textField(
              type: FormBuilderInput.TYPE_EMAIL,
              attribute: "email",
              decoration: InputDecoration(labelText: "Email"),
              require: true,
            ),
            FormBuilderInput.textField(
              type: FormBuilderInput.TYPE_URL,
              attribute: "url",
              decoration: InputDecoration(labelText: "Website"),
              require: true,
            ),
            FormBuilderInput.textField(
              type: FormBuilderInput.TYPE_PHONE,
              attribute: "phone",
              decoration: InputDecoration(labelText: "Phone Number"),
              //require: true,
            ),
            FormBuilderInput.password(
              attribute: "password",
              decoration: InputDecoration(labelText: "Password"),
              min: 8,
            ),
            FormBuilderInput.datePicker(
              decoration: InputDecoration(labelText: "Date of Birth"),
              readonly: true,
              attribute: "dob",
              firstDate: DateTime(1970),
              value: DateTime.now(),
              lastDate: DateTime.now().add(Duration(days: 1)),
              format: 'dd, MM yyyy',
            ),
            FormBuilderInput.timePicker(
              decoration: InputDecoration(labelText: "Alarm Time"),
              attribute: "alarm",
              require: true,
            ),
            FormBuilderInput.dateTimePicker(
              decoration: InputDecoration(labelText: "Appointment Time"),
              attribute: "appointment_time",
              firstDate: DateTime(1970),
              lastDate: DateTime.now().add(Duration(days: 1)),
              // format: 'dd, MM yyyy hh:mm',
            ),
            FormBuilderInput.checkboxList(
              decoration:
                  InputDecoration(labelText: "The language of my people"),
              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(
              decoration:
                  InputDecoration(labelText: 'My chosen language'),
              attribute: "best_language",
              require: true,
              options: ["Dart", "Kotlin", "Java", "Swift", "Objective-C"]
                  .map((lang) => FormBuilderInputOption(value: lang))
                  .toList(growable: false),
            ),
            FormBuilderInput.checkbox(
                label: Text('I Accept the tems and conditions'),
                attribute: "accept_terms",
                validator: (value) {
                  if (!value) return "Accept terms to continue";
                }),
            FormBuilderInput.switchInput(
                label: Text('I Accept the tems and conditions'),
                attribute: "accept_terms_switch",
                value: true,
                validator: (value) {
                  if (!value) return "Accept terms to continue";
                }),
            FormBuilderInput.slider(
              decoration: InputDecoration(labelText: "Slider"),
              attribute: "slider",
              min: 0.0,
              require: true,
              max: 100.0,
              value: 10.0,
              divisions: 20,
            ),
            FormBuilderInput.stepper(
              decoration: InputDecoration(labelText: "Stepper"),
              attribute: "stepper",
              value: 10,
              step: 1,
            ),
            FormBuilderInput.signaturePad(
              decoration: InputDecoration(labelText: "Signature"),
              attribute: "signature",
              require: true,
            ),
            FormBuilderInput.rate(
              decoration: InputDecoration(labelText: "Rate this form"),
              attribute: "rate",
              iconSize: 32.0,
              value: 1,
              max: 5,
            ),
            FormBuilderInput.segmentedControl(
              decoration:
                  InputDecoration(labelText: "Movie Rating (Archer)"),
              attribute: "movie_rating",
              // value: 2,
              require: true,
              options: List.generate(5, (i) => i + 1)
                  .map((number) => FormBuilderInputOption(value: number))
                  .toList(),
            ),
          ],
      ),
      MaterialButton(
        child: Text('External submit'),
        onPressed: () {
          _fbKey.currentState.save();
          if (_fbKey.currentState.validate()) {
            print('validationSucceded');
            print(_fbKey.currentState.value);
          } else {
            print("External FormValidation failed");
          }
        },
      ),
    ],
  ),
)

TODO: #

Improvements #

  • [ ] Improve documentation by showing complete list of input types and their usage and options
  • [ ] Assert no duplicates in FormBuilderInputs attribute names
  • [ ] Allow options for Checkboxes and Radios to appear left or right
  • [ ] Allow addition of custom input types
  • [ ] Proper validation for URL - does not work without protocol - http(s)

New FormBuilder inputs #

[2.1.0] - 05-April-2019

  • Bumped up flutter_typeahead dependency to ^1.4.0 from ^1.2.0

[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: ^2.1.0

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages 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
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
1.5.0 Mar 20, 2019 Go to the documentation of flutter_form_builder 1.5.0 Download flutter_form_builder 1.5.0 archive
1.4.0 Jan 29, 2019 Go to the documentation of flutter_form_builder 1.4.0 Download flutter_form_builder 1.4.0 archive
1.3.5 Jan 28, 2019 Go to the documentation of flutter_form_builder 1.3.5 Download flutter_form_builder 1.3.5 archive
1.3.4 Jan 19, 2019 Go to the documentation of flutter_form_builder 1.3.4 Download flutter_form_builder 1.3.4 archive

All 30 versions...

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

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

  • Dart: 2.2.0
  • pana: 0.12.14
  • Flutter: 1.4.7

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health issues and suggestions

Document public APIs. (-0.30 points)

164 out of 168 API elements have no dartdoc comment.Providing good documentation for libraries, classes, functions, and other API elements improves code readability and helps developers find and use your API.

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.4.1
intl ^0.15.7 0.15.8
signature ^2.0.0 2.0.0
sy_flutter_widgets ^0.1.4 0.1.4
Transitive dependencies
collection 1.14.11
keyboard_visibility 0.5.2
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