flutter_form_bloc 0.12.2

  • Readme
  • Changelog
  • Example
  • Installing
  • 94

flutter_form_bloc #

PackagePub
form_blocpub package
flutter_form_blocpub package

Easy Form State Management using BLoC pattern. Separate the Form State and Business Logic from the User Interface.

🔥👉 Documentation and Tutorials 👈🔥 #

  • [x] Synchronous Field Validation
  • [x] Asynchronous Field Validation
  • [x] Easy Loading and Initializing
  • [x] Wizard / Stepper Forms
  • [x] Submission Progress
  • [x] Success / Failure Response
  • [x] Serializable Form
  • [x] Submission Errors to Fields
  • [x] Dynamic Fields
  • [x] Conditional Fields
  • [x] List Fields
  • [x] Group Fields
  • [x] CRUD Support
  • [x] Beautiful Built-In Widgets

Examples #

Maintainers #

0.12.2 #

  • Fixed Intl version.

0.12.1 #

  • Fixed minor bug in Stepper 54.

0.12.0+1 #

  • Fixed changelog.

0.12.0 #

  • Breaking changes #

    • Updated to form_bloc: ^0.12.0.
  • Added properties to TextFieldBlocBuilder:

    • obscureTextTrueIcon
    • obscureTextFalseIcon
    • clearTextIcon
    • asyncValidatingIcon

0.11.2 #

  • Added clearIcon to:
    • DateTimeFieldBlocBuilder
    • TimeFieldBlocBuilder

0.11.1 #

  • Fixed content padding of decoration in:
    • DropdownFieldBlocBuilder
    • DateTimeFieldBlocBuilder
    • TimeFieldBlocBuilder

0.11.0+1 #

  • Fixed pub health issues

0.11.0 #

Breaking changes #

  • Updated to form_bloc: ^0.11.0.
  • Added StepperFormBlocBuilder.
  • Added DateTimeFieldBlocBuilder.
  • Added TimeFieldBlocBuilder.
  • Added CanShowFieldBlocBuilder.
  • All widgets now are animated by default if the FieldBloc is added or removed from the FormBloc.
  • Documentation Updates.

0.10.6 #

  • Fixed bug of size on first rendered of DropdownFieldBlocBuilder.

0.10.5 #

  • Fixed decoration.hintText property of DropdownFieldBlocBuilder

0.10.4 #

  • Fixed DropdownFieldBlocBuilder focus 28.

0.10.3 #

  • Added SwitchFieldBlocBuilder.
  • Added/Fixed properties of TextFieldBlocBuilder:
    • readOnly
    • buildCounter
    • dragStartBehavior
    • enableInteractiveSelection
    • enableSuggestions
    • expands
    • scrollController
    • strutStyle
    • showCursor
    • scrollPhysics
    • textAlignVertical
    • toolbarOptions
  • Added controlAffinity property to CheckboxFieldBlocBuilder.
  • Documentation Updates.

0.10.2 #

  • Fixed minLines property of TextFieldBlocBuilder.

0.10.1 #

  • Fixed SuffixButton.clearText of TextFieldBlocBuilder.

0.10.0 #

Breaking changes #

  • Updated to form_bloc: ^0.10.0.
  • Documentation Updates.
  • Added more examples.

0.7.0 #

  • Added defaultErrorBuilder property to FieldBlocBuilder.
  • Updated to form_bloc: ^0.8.0.
  • Updated to flutter_bloc: ^3.2.0.
  • Added onDeleting, onDeleteFailed, onDeleteSuccessful callbacks to FormBlocListener.
  • Added more examples.

0.6.1-beta-1 #

  • Added defaultErrorBuilder property to FieldBlocBuilder.

0.6.0 #

  • Updated to bloc: ^3.0.0.
  • Updated to flutter_bloc: ^3.1.0.
  • Updated to form_bloc: ^0.7.0.
  • Fixed bug in onTap method of TextFieldBlocBuilder.
  • Documentation Updates.

0.5.0 #

  • Updated to bloc: ^1.0.0.
  • Updated to flutter_bloc: ^1.0.0.
  • Updated to form_bloc: ^0.6.0.
  • Documentation Updates.

0.4.4 #

  • Dependencies Updates.
  • Fixed bug in suggestions of TextFieldBlocBuilder.
  • Added the next properties to TextFieldBlocBuilder.
    • hideOnLoadingSuggestions = false,
    • hideOnEmptySuggestions = false,
    • hideOnSuggestionsError = false,
    • loadingSuggestionsBuilder,
    • suggestionsNotFoundBuilder,
    • suggestionsErrorBuilder,
    • keepSuggestionsOnLoading = false,
    • showSuggestionsWhenIsEmpty = true,

0.4.3 #

  • Updated to form_bloc: ^0.5.2.
  • Documentation Updates.

0.4.2 #

  • Updated to form_bloc: ^0.5.1.

0.4.1+1 #

  • Documentation Updates.

0.4.1 #

  • FormBlocListener improved.

0.4.0+1 #

  • Documentation Updates.

0.4.0 #

  • Documentation Updates.
  • Updated to form_bloc: ^0.5.0.
  • Added more examples.

0.3.1 #

  • Documentation Updates.

0.3.0 #

  • Documentation Updates.
  • Updated to form_bloc: ^0.4.1.
  • Added CheckBoxGroupFieldBlocBuilder.
  • Added more examples.

0.2.1 #

  • Updated to form_bloc: ^0.3.1.

0.2.0 #

  • Dependencies and Documentation Updates.
  • Added RadioButtonGroupFieldBlocBuilder (#1).
  • Add Form with progress example.

0.1.0 #

Initial Version of the library.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  const App({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: AllFieldsForm(),
    );
  }
}

class AllFieldsFormBloc extends FormBloc<String, String> {
  final text1 = TextFieldBloc();

  final boolean1 = BooleanFieldBloc();

  final boolean2 = BooleanFieldBloc();

  final select1 = SelectFieldBloc(
    items: ['Option 1', 'Option 2'],
  );

  final select2 = SelectFieldBloc(
    items: ['Option 1', 'Option 2'],
  );

  final multiSelect1 = MultiSelectFieldBloc<String, dynamic>(
    items: [
      'Option 1',
      'Option 2',
    ],
  );

  final date1 = InputFieldBloc<DateTime, Object>();

  final dateAndTime1 = InputFieldBloc<DateTime, Object>();

  final time1 = InputFieldBloc<TimeOfDay, Object>();

  AllFieldsFormBloc() {
    addFieldBlocs(fieldBlocs: [
      text1,
      boolean1,
      boolean2,
      select1,
      select2,
      multiSelect1,
      date1,
      dateAndTime1,
      time1,
    ]);
  }

  void addErrors() {
    text1.addError('Awesome Error!');
    boolean1.addError('Awesome Error!');
    boolean2.addError('Awesome Error!');
    select1.addError('Awesome Error!');
    select2.addError('Awesome Error!');
    multiSelect1.addError('Awesome Error!');
    date1.addError('Awesome Error!');
    dateAndTime1.addError('Awesome Error!');
    time1.addError('Awesome Error!');
  }

  @override
  void onSubmitting() async {
    try {
      await Future<void>.delayed(Duration(milliseconds: 500));

      emitSuccess(canSubmitAgain: true);
    } catch (e) {
      emitFailure();
    }
  }
}

class AllFieldsForm extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => AllFieldsFormBloc(),
      child: Builder(
        builder: (context) {
          final formBloc = BlocProvider.of<AllFieldsFormBloc>(context);

          return Theme(
            data: Theme.of(context).copyWith(
              inputDecorationTheme: InputDecorationTheme(
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(20),
                ),
              ),
            ),
            child: Scaffold(
              appBar: AppBar(title: Text('Built-in Widgets')),
              floatingActionButton: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  FloatingActionButton.extended(
                    heroTag: null,
                    onPressed: formBloc.addErrors,
                    icon: Icon(Icons.error_outline),
                    label: Text('ADD ERRORS'),
                  ),
                  SizedBox(height: 12),
                  FloatingActionButton.extended(
                    heroTag: null,
                    onPressed: formBloc.submit,
                    icon: Icon(Icons.send),
                    label: Text('SUBMIT'),
                  ),
                ],
              ),
              body: FormBlocListener<AllFieldsFormBloc, String, String>(
                onSubmitting: (context, state) {
                  LoadingDialog.show(context);
                },
                onSuccess: (context, state) {
                  LoadingDialog.hide(context);

                  Navigator.of(context).pushReplacement(
                      MaterialPageRoute(builder: (_) => SuccessScreen()));
                },
                onFailure: (context, state) {
                  LoadingDialog.hide(context);

                  Scaffold.of(context).showSnackBar(
                      SnackBar(content: Text(state.failureResponse)));
                },
                child: SingleChildScrollView(
                  physics: ClampingScrollPhysics(),
                  child: Padding(
                    padding: const EdgeInsets.all(24.0),
                    child: Column(
                      children: <Widget>[
                        TextFieldBlocBuilder(
                          textFieldBloc: formBloc.text1,
                          decoration: InputDecoration(
                            labelText: 'TextFieldBlocBuilder',
                            prefixIcon: Icon(Icons.text_fields),
                          ),
                        ),
                        DropdownFieldBlocBuilder<String>(
                          selectFieldBloc: formBloc.select1,
                          decoration: InputDecoration(
                            labelText: 'DropdownFieldBlocBuilder',
                            prefixIcon: Icon(Icons.sentiment_satisfied),
                          ),
                          itemBuilder: (context, value) => value,
                        ),
                        RadioButtonGroupFieldBlocBuilder<String>(
                          selectFieldBloc: formBloc.select2,
                          decoration: InputDecoration(
                            labelText: 'RadioButtonGroupFieldBlocBuilder',
                            prefixIcon: SizedBox(),
                          ),
                          itemBuilder: (context, item) => item,
                        ),
                        CheckboxGroupFieldBlocBuilder<String>(
                          multiSelectFieldBloc: formBloc.multiSelect1,
                          itemBuilder: (context, item) => item,
                          decoration: InputDecoration(
                            labelText: 'CheckboxGroupFieldBlocBuilder',
                            prefixIcon: SizedBox(),
                          ),
                        ),
                        DateTimeFieldBlocBuilder(
                          dateTimeFieldBloc: formBloc.date1,
                          format: DateFormat('dd-mm-yyyy'),
                          initialDate: DateTime.now(),
                          firstDate: DateTime(1900),
                          lastDate: DateTime(2100),
                          decoration: InputDecoration(
                            labelText: 'DateTimeFieldBlocBuilder',
                            prefixIcon: Icon(Icons.calendar_today),
                            helperText: 'Date',
                          ),
                        ),
                        DateTimeFieldBlocBuilder(
                          dateTimeFieldBloc: formBloc.dateAndTime1,
                          canSelectTime: true,
                          format: DateFormat('dd-mm-yyyy  hh:mm'),
                          initialDate: DateTime.now(),
                          firstDate: DateTime(1900),
                          lastDate: DateTime(2100),
                          decoration: InputDecoration(
                            labelText: 'DateTimeFieldBlocBuilder',
                            prefixIcon: Icon(Icons.date_range),
                            helperText: 'Date and Time',
                          ),
                        ),
                        TimeFieldBlocBuilder(
                          timeFieldBloc: formBloc.time1,
                          format: DateFormat('hh:mm a'),
                          initialTime: TimeOfDay.now(),
                          decoration: InputDecoration(
                            labelText: 'TimeFieldBlocBuilder',
                            prefixIcon: Icon(Icons.access_time),
                          ),
                        ),
                        SwitchFieldBlocBuilder(
                          booleanFieldBloc: formBloc.boolean2,
                          body: Container(
                            alignment: Alignment.centerLeft,
                            child: Text('CheckboxFieldBlocBuilder'),
                          ),
                        ),
                        CheckboxFieldBlocBuilder(
                          booleanFieldBloc: formBloc.boolean1,
                          body: Container(
                            alignment: Alignment.centerLeft,
                            child: Text('CheckboxFieldBlocBuilder'),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      ),
    );
  }
}

class LoadingDialog extends StatelessWidget {
  static void show(BuildContext context, {Key key}) => showDialog<void>(
        context: context,
        useRootNavigator: false,
        barrierDismissible: false,
        builder: (_) => LoadingDialog(key: key),
      ).then((_) => FocusScope.of(context).requestFocus(FocusNode()));

  static void hide(BuildContext context) => Navigator.pop(context);

  LoadingDialog({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async => false,
      child: Center(
        child: Card(
          child: Container(
            width: 80,
            height: 80,
            padding: EdgeInsets.all(12.0),
            child: CircularProgressIndicator(),
          ),
        ),
      ),
    );
  }
}

class SuccessScreen extends StatelessWidget {
  SuccessScreen({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon(Icons.tag_faces, size: 100),
            SizedBox(height: 10),
            Text(
              'Success',
              style: TextStyle(fontSize: 54, color: Colors.black),
              textAlign: TextAlign.center,
            ),
            SizedBox(height: 10),
            RaisedButton.icon(
              onPressed: () => Navigator.of(context).pushReplacement(
                  MaterialPageRoute(builder: (_) => AllFieldsForm())),
              icon: Icon(Icons.replay),
              label: Text('AGAIN'),
            ),
          ],
        ),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

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


dependencies:
  flutter_form_bloc: ^0.12.2

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_bloc/flutter_form_bloc.dart';
  
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]
90
Overall:
Weighted score of the above. [more]
94
Learn more about scoring.

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

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Maintenance issues and suggestions

Make sure dartdoc successfully runs on your package's source files. (-10 points)

exitCode: 255 stdout: parsing /tmp/pub-dartlang-dartdocXPBTIG/pkg/lib/flutter_form_bloc.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/collection/collection.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/developer/developer.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/internal/internal.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/_interceptors/interceptors.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/io/io.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/isolate/isolate.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/convert/convert.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/async/async.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/typed_data/typed_data.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/_empty.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/js_util/js_util_dart2js.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/html/html_dart2js.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/math/math.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/core/core.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/_http/http.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/ui/ui.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/js/js_dart2js.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/ffi/ffi.dart... parsing /flutter/bin/cache/pkg/sky_engine/lib/wasm/wasm.dart... [...] parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/pretty_print.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/util.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/equals_matcher.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/error_matchers.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/iterable_matchers.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/map_matchers.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/numeric_matchers.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/operator_matchers.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/order_matchers.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/src/string_matchers.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/intl-0.16.1/lib/src/data/dates/locale_list.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/intl-0.16.1/lib/src/file_data_reader.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/intl-0.16.1/lib/src/lazy_locale_data.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/intl-0.16.1/lib/src/locale.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/intl-0.16.1/lib/src/locale/locale_implementation.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/intl-0.16.1/lib/src/locale/locale_deprecations.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/intl-0.16.1/lib/src/locale/locale_extensions.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/intl-0.16.1/lib/src/locale/locale_parser.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/intl-0.16.1/lib/src/http_request_data_reader.dart... parsing /tmp/pub-cache-dirDQSNBG/hosted/pub.dartlang.org/matcher-0.12.6/lib/mirror_matchers.dart... stderr: Documenting flutter_form_bloc... Unhandled exception: NoSuchMethodError: The getter 'inheritanceManager' was called on null. Receiver: null Tried calling: inheritanceManager #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5) #1 Class._inheritedElements (package:dartdoc/src/model/class.dart:418:41) #2 Class.inheritedMethods (package:dartdoc/src/model/class.dart:258:11) #3 Class.allInstanceMethods (package:dartdoc/src/model/class.dart:56:39) #4 Class.allModelElements (package:dartdoc/src/model/class.dart:146:13) #5 Library.modelElementsMap.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
bloc ^3.0.0 3.0.0 4.0.0-dev.1
collection ^1.14.11 1.14.11 1.14.12
flutter 0.0.0
flutter_bloc ^3.2.0 3.2.0 4.0.0-dev.1
form_bloc ^0.12.0 0.12.0
intl >=0.15.1 <0.17.0 0.16.1
keyboard_utils ^1.2.0 1.2.0
rxdart ^0.23.0 0.23.1 0.24.0-dev.1
Transitive dependencies
_fe_analyzer_shared 2.1.0
analyzer 0.39.6
args 1.6.0
async 2.4.1
bloc_test 4.0.0 5.0.0-dev.1
boolean_selector 2.0.0
charcode 1.1.3
convert 2.1.1
coverage 0.13.9
crypto 2.1.4
csslib 0.16.1
equatable 1.1.1
glob 1.2.0
html 0.14.0+3
http 0.12.0+4
http_multi_server 2.2.0
http_parser 3.1.4
io 0.3.4
js 0.6.1+1
logging 0.11.4
matcher 0.12.6
meta 1.1.8
mime 0.9.6+3
mockito 4.1.1
multi_server_socket 1.0.2
nested 0.0.4
node_interop 1.0.3
node_io 1.0.1+2
node_preamble 1.4.8
package_config 1.9.3
path 1.6.4
pool 1.4.0
provider 4.0.4 4.1.0-dev+2
pub_semver 1.4.4
quiver 2.1.3
shelf 0.7.5
shelf_packages_handler 2.0.0
shelf_static 0.2.8
shelf_web_socket 0.2.3
sky_engine 0.0.99
source_map_stack_trace 2.0.0
source_maps 0.10.9
source_span 1.7.0
stack_trace 1.9.3
stream_channel 2.0.0
string_scanner 1.0.5
term_glyph 1.1.0
test 1.14.2
test_api 0.2.15
test_core 0.3.3
typed_data 1.1.6
uuid 2.0.4
vector_math 2.0.8
vm_service 4.0.0
watcher 0.9.7+14
web_socket_channel 1.1.0
webkit_inspection_protocol 0.5.0+1
yaml 2.2.0
Dev dependencies
flutter_test
pedantic ^1.7.0 1.9.0