flutter_form_builder 1.3.4

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

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

FormBuilder(
  context,
  autovalidate: true,
  showResetButton: true,
  // resetButtonContent: Text("Clear Form"),
  controls: [
    FormBuilderInput.typeAhead(
      label: '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(
      label: 'Chips',
      attribute: 'chips_test',
      require: true,
      value: [
        AppProfile('Andrew', 'stock@man.com',
            'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg')
      ],
      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 <AppProfile>[];
        }
      },
      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",
      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",
        hint: "Including country code (+254)"
        //require: true,
        ),
    FormBuilderInput.password(
      attribute: "password",
      label: "Password",
      min: 8,
    ),
    FormBuilderInput.datePicker(
      label: "Date of Birth",
      attribute: "dob",
      firstDate: DateTime(1970),
      lastDate: DateTime.now().add(Duration(days: 1)),
      format: 'dd, MM yyyy'
    ),
    FormBuilderInput.timePicker(
      label: "Appointment Time",
      attribute: "time",
    ),
    FormBuilderInput.checkboxList(
      label: "The Languages of my people",
      hint: "The Languages 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(
      label: "My Best Language",
      attribute: "best_language",
      require: true,
      options: ["Dart", "Kotlin", "Java", "Swift", "Objective-C"]
          .map((lang) => FormBuilderInputOption(value: lang))
          .toList(growable: false),
    ),
    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.switchInput(
        label: "I accept the terms and conditions",
        attribute: "accept_terms_switch",
        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: 32.0,
      value: 1,
      max: 5,
      hint: "Hint",
    ),
    FormBuilderInput.segmentedControl(
      label: "Movie Rating (Archer)",
      attribute: "movie_rating",
      require: true,
      options: List.generate(5, (i) => i + 1)
          .map((number) => FormBuilderInputOption(value: number))
          .toList(),
    ),
  ],
  onChanged: (formValue) {
    print(formValue);
  },
  onSubmit: (formValue) {
    if (formValue != null) {
      print(formValue);
    } else {
      print("Form invalid");
    }
  },
),

TODO:

  • Improve documentation by showing complete list of input types and their usage and options
  • Assert no duplicates in FormBuilderInputs attribute names
  • Add more FormBuilderInput types:
    • RangeSlider
    • ColorPicker
    • MaskedText
  • Allow options for Checkboxes and Radios to appear left or right
  • Allow addition of custom input types
  • Fire onChanged() on every control allowing reaction to changes

KNOWN ISSUES - HELP NEEDED (Send help ;-P)

  • Proper validation for URL [doesn't work without http(s)]

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

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
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
1.3.3 Jan 17, 2019 Go to the documentation of flutter_form_builder 1.3.3 Download flutter_form_builder 1.3.3 archive
1.3.2 Dec 19, 2018 Go to the documentation of flutter_form_builder 1.3.2 Download flutter_form_builder 1.3.2 archive
1.3.1 Dec 17, 2018 Go to the documentation of flutter_form_builder 1.3.1 Download flutter_form_builder 1.3.1 archive
1.3.0 Dec 15, 2018 Go to the documentation of flutter_form_builder 1.3.0 Download flutter_form_builder 1.3.0 archive
1.2.0 Nov 23, 2018 Go to the documentation of flutter_form_builder 1.2.0 Download flutter_form_builder 1.2.0 archive
1.1.0 Nov 19, 2018 Go to the documentation of flutter_form_builder 1.1.0 Download flutter_form_builder 1.1.0 archive
1.0.2 Nov 7, 2018 Go to the documentation of flutter_form_builder 1.0.2 Download flutter_form_builder 1.0.2 archive
1.0.1 Nov 3, 2018 Go to the documentation of flutter_form_builder 1.0.1 Download flutter_form_builder 1.0.1 archive
1.0.0 Nov 3, 2018 Go to the documentation of flutter_form_builder 1.0.0 Download flutter_form_builder 1.0.0 archive

All 11 versions...

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

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

  • Dart: 2.1.0
  • pana: 0.12.10
  • Flutter: 1.1.7

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health issues and suggestions

Document public APIs. (-0.70 points)

98 out of 99 API elements (library, class, field or method) have no adequate dartdoc content. Good documentation improves code readability and discoverability through search.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.68.0 <3.0.0
flutter 0.0.0
flutter_chips_input ^1.0.4 1.0.4
flutter_typeahead ^0.5.1 0.5.1
intl ^0.15.7 0.15.7
sy_flutter_widgets ^0.1.4 0.1.4
Transitive dependencies
collection 1.14.11
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