Easy Form State Management using BLoC pattern

Overview

form_bloc

Package Pub
form_bloc pub package
flutter_form_bloc pub package

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

๐Ÿ”ฅ ๐Ÿ‘‰ Documentation and Tutorials ๐Ÿ‘ˆ ๐Ÿ”ฅ

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

Examples

Maintainers

Comments
  • Validators are not fired when field is empty.

    Validators are not fired when field is empty.

    From 0.11.0 there is isRequired flag. But if I do not need the built in required validation? What if I want custom message for required case?

    In case if I do not pass the isRequired the validators are not fired if the input value is empty.

    The previous solution with validators array way clear and usable. The updated one is not so flexible...

    Is there a possibility to revert error handling to previous version?

    opened by vasilich6107 36
  • Listen to changes

    Listen to changes

    @GiancarloCode How can I listen to changes , not only a specific field , All changes in every fields in the form,

    I want to implement auto save, when fields changes

    I tried to use BlocListener but I don't know how can I be sure something changed

    opened by sm2017 14
  • Theme of context shadowThemeOnly

    Theme of context shadowThemeOnly

    ../../.pub-cache/hosted/pub.dartlang.org/flutter_form_bloc-0.19.0/lib/src/dropdown.dart:844:34: Error: No named parameter with the name 'shadowThemeOnly'.
            theme: Theme.of(context, shadowThemeOnly: true),
    

    Flutter version 1.24.0-10.2.pre

    seems shadowThemeOnly removed

    opened by aideric 13
  • Is this project not maintained anymore?

    Is this project not maintained anymore?

    Do anyone know anything about future of this repo? As far as it has decent amount of bugs and not actively maintained I'm moving to https://github.com/joanpablo/reactive_forms

    opened by vasilich6107 13
  • how to use this repo from Git in flutter?

    how to use this repo from Git in flutter?

    i see some things in issues that are resolved but not yet updated in pub.dev so i tried to use this git repo instead without success can someone help me? this is how i tried it form_bloc: git: url: git://github.com/GiancarloCode/form_bloc/

    opened by fredwilliam 12
  • [question] example to access API backend using form_block 0.12.0

    [question] example to access API backend using form_block 0.12.0

    Can somebody give me an example how to access a backend API using the latest 0.12.0 version of form_bloc? It needs already be defined in main.dart...and then implemented in the bloc I have it working in the bloc, but want it already started in main.dart so it does not restart with every screen. Thanks in advance! Hans

    opened by hansbak 11
  • I am looking for collaborators to help me maintain the project

    I am looking for collaborators to help me maintain the project

    Hello, first of all I apologize for not having updated the project these months, but for personal reasons I could not and in the near future I will not be able to do it either.

    Therefore, if one or more of you are interested in maintaining the project or even improving it, for now it would be very helpful for the community that is currently making use of it.

    So if you are interested, you can apply here by commenting: I want to be a collaborator And answering these questions:

    1. How much experience do you have programming and how much experience do you have programming in dart / flutter?

    2. what do you do for a living? or what do you study?

    3. Have you already made an update? If so, put the link of your fork, or pull request, so that I can review the code slightly (I say slightly because currently I cannot compile anything, but I can give me a good idea of โ€‹โ€‹your knowledge of the framework and good practices)

    4. What do you plan to do?

    5. What vision do you have for the package? in case you have in mind to make groundbreaking changes that may be beneficial

    6. Whatever you want.

    I will be reviewing this thread these days, and if someone has suggestions to choose the collaborators you can tell me and I will update.

    And in the same way, if a person applying has votes from other developers, it will also be taken into account.

    If you are interested and you are chosen we can speak for discord to resolve or clarify any doubts about the code and of course to become a collaborator in the github project and also give you permission in pub.dev so that you can publish


    I apologize again, and I really want to support and implement some things that I had in mind, but it will not be possible in the near future.

    So for now, thank you very much if you want to help

    help wanted 
    opened by GiancarloCode 10
  • Unhandled Exception when calling submit

    Unhandled Exception when calling submit

    Hello,

    I just upgraded flutter_form_bloc from version 0.10.0 to 0.12.2 and getting exceptions when calling submit. I noticed that this only happens when I have 3 or more TextFieldBlocBuilders on screen and updating their initial values. Then when I call submit, the app hangs for a few seconds and I see exceptions in the debug console:

    E/flutter (15380): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Stack Overflow
    E/flutter (15380): #0      new DiagnosticsProperty 
    package:flutter/โ€ฆ/foundation/diagnostics.dart:2545
    E/flutter (15380): #1      new _ErrorDiagnostic 
    package:flutter/โ€ฆ/foundation/assertions.dart:31
    E/flutter (15380): #2      new ErrorDescription 
    package:flutter/โ€ฆ/foundation/assertions.dart:111
    E/flutter (15380): #3      ChangeNotifier.notifyListeners 
    package:flutter/โ€ฆ/foundation/change_notifier.dart:212
    E/flutter (15380): #4      TextEditingController.selection= 
    package:flutter/โ€ฆ/widgets/editable_text.dart:275
    E/flutter (15380): #5      _TextFieldBlocBuilderState._fixControllerTextValue 
    package:flutter_form_bloc/src/text_field_bloc_builder.dart:730
    E/flutter (15380): #6      _TextFieldBlocBuilderState._fixControllerTextValue (package:flutter_form_bloc/src/text_field_bloc_builder.dart)
    E/flutter (15380): #7      _TextFieldBlocBuilderState._textControllerListener 
    package:flutter_form_bloc/src/text_field_bloc_builder.dart:713
    E/flutter (15380): #8      ChangeNotifier.notifyListeners 
    package:flutter/โ€ฆ/foundation/change_notifier.dart:206
    E/flutter (15380): #9      _TextFieldBlocBuilderState._fixControllerTextValue 
    package:flutter_form_bloc/src/text_field_bloc_builder.dart:267
    E/flutter (15380): #10     _TextFieldBlocBuilderState._fixControllerTextValue (package:flutter_form_bloc/src/text_field_bloc_builder.dart)
    E/flutter (15380): #11     _TextFieldBlocBuilderState._textControllerListener 
    package:flutter_form_bloc/src/text_field_bloc_builder.dart:713
    E/flutter (15380): #12     ChangeNotifier.notifyListeners 
    package:flutter/โ€ฆ/foundation/change_notifier.dart:206
    E/flutter (15380): #13     TextEditingController.selection= 
    package:flutter/โ€ฆ/widgets/editable_text.dart:275
    E/flutter (15380): #14     _TextFieldBlocBuilderState._fixControllerTextValue 
    package:flutter_form_bloc/src/text_field_bloc_builder.dart:730
    E/flutter (15380): #15     _TextFieldBlocBuilderState._fixControllerTextValue (package:flutter_form_bloc/src/text_field_bloc_builder.dart)
    

    Here's my Bloc:

    class ClientFormBloc extends FormBloc<String, String> {
      final ClientsRepository clientsRepository;
      final Client client;
    
      final name = TextFieldBloc(
        validators: [CustomValidator.name],
      );
      final email = TextFieldBloc(
        validators: [CustomValidator.emailOptional],
      );
      final phone = TextFieldBloc();
      final website = TextFieldBloc();
      final notes = TextFieldBloc();
    
      ClientFormBloc({@required this.clientsRepository, @required this.client})
          : super(autoValidate: false) {
        if (client != null) {
          name.updateInitialValue(client.name);
          email.updateInitialValue(client.email);
          phone.updateInitialValue(client.phone);
          website.updateInitialValue(client.website);
          notes.updateInitialValue(client.notes);
        }
    
        addFieldBlocs(fieldBlocs: [
          name,
          email,
          country,
          phone,
          website,
          notes,
        ]);
      }
      
      @override
      void onSubmitting() async {
        final clientUid = client != null ? client.uid : Uuid().v4();
        final nameValue = name.value.parse();
        final emailValue = email.value.parse();
        final phoneValue = phone.value.parse();
        final websiteValue = website.value.parse();
        final notesValue = notes.value.parse();
    
        final updatedClient = Client(
            uid: clientUid,
            name: nameValue,
            email: emailValue,
            phone: phoneValue,
            website: websiteValue,
            notes: notesValue);
        clientsRepository.saveClient(updatedClient);
        emitSuccess();
      }
    }
    

    And the screen widget:

    class ClientFormScreen extends StatefulWidget {
      ClientFormScreen({key}) : super(key: key);
    
      @override
      _ClientFormScreenState createState() => _ClientFormScreenState();
    }
    
    class _ClientFormScreenState extends State<ClientFormScreen> {
      @override
      Widget build(BuildContext context) {
        final Client client = ModalRoute.of(context).settings.arguments;
    
        return BlocProvider<ClientFormBloc>(
          create: (context) => ClientFormBloc(
            clientsRepository: RepositoryProvider.of<ClientsRepository>(context),
            client: client,
          ),
          child: Builder(
            builder: (context) {
              final formBloc = context.bloc<ClientFormBloc>();
    
              return Scaffold(
                appBar: AppBar(
                  leading: IconButton(
                    icon: Icon(
                      Icons.close,
                    ),
                    onPressed: Navigator.of(context).pop,
                  ),
                  title: Text(
                    client == null
                        ? tr('general.new_client')
                        : tr('general.edit_client'),
                  ),
                  actions: <Widget>[
                    FlatButton(
                      onPressed: context.bloc<ClientFormBloc>().submit,
                      child: Text(
                        tr('general.save'),
                        style: TextStyle(
                            color: Theme.of(context).colorScheme.onPrimary),
                      ),
                    ),
                  ],
                ),
                body: FormBlocListener<ClientFormBloc, String, String>(
                  onSuccess: (context, state) {
                    Navigator.of(context).pop();
                  },
                  child: ListView(
                    children: <Widget>[
                      TextFieldBlocBuilder(
                        textFieldBloc: formBloc.name,
                        keyboardType: TextInputType.text,
                        decoration: InputDecoration(
                          border: OutlineInputBorder(),
                          icon: Icon(MaterialIcons.person_outline),
                          labelText: tr('general.name'),
                        ),
                      ),
                      TextFieldBlocBuilder(
                        textFieldBloc: formBloc.email,
                        keyboardType: TextInputType.emailAddress,
                        decoration: InputDecoration(
                          border: OutlineInputBorder(),
                          icon: Icon(MaterialIcons.mail_outline),
                          labelText: tr('general.email'),
                        ),
                      ),
                      TextFieldBlocBuilder(
                        textFieldBloc: formBloc.phone,
                        keyboardType: TextInputType.phone,
                        decoration: InputDecoration(
                          border: OutlineInputBorder(),
                          icon: Icon(MaterialIcons.phone),
                          labelText: tr('general.phone'),
                        ),
                      ),
                      TextFieldBlocBuilder(
                        textFieldBloc: formBloc.website,
                        keyboardType: TextInputType.url,
                        decoration: InputDecoration(
                          border: OutlineInputBorder(),
                          icon: Icon(MaterialIcons.public),
                          labelText: tr('general.website'),
                        ),
                      ),
                      TextFieldBlocBuilder(
                        textFieldBloc: formBloc.notes,
                        keyboardType: TextInputType.multiline,
                        decoration: InputDecoration(
                          border: OutlineInputBorder(),
                          icon: Icon(MaterialIcons.subject),
                          labelText: tr('general.notes'),
                        ),
                      ),
                    ],
                  ),
                ),
              );
            },
          ),
        );
      }
    }
    

    Is there anything I'm doing wrong? I didn't have any issues with the previous version.

    Thanks

    opened by peterstojanowski 9
  • Dependency on intl package

    Dependency on intl package

    I am not able to update other packages that depend on intl ^0.17.0 due to version incompatibility with flutter_form_bloc.

    Because flutter_form_bloc 0.19.0 depends on intl >=0.15.1 <0.17.0 and no versions of flutter_form_bloc 
    match >0.19.0 <0.20.0, flutter_form_bloc ^0.19.0 requires intl >=0.15.1 <0.17.0.
    So, because App_Name depends on both intl ^0.17.0 and flutter_form_bloc ^0.19.0, version solving failed.
    

    I think its time flutter_form_bloc was updated.

    opened by ebot64 8
  • removeFieldBlocs is not working in Flutter

    removeFieldBlocs is not working in Flutter

    Description In Flutter, when i am trying to call removeFieldBlocs function is not removing filed but its adding field i am not sure it is bug or is something missing in my code

    I have checked here : https://giancarlocode.github.io/form_bloc/#/ got to Conditional Field Example this is also not working

    Steps To Reproduce

    class ConditionalFieldsFormBloc extends FormBloc<String, String> { final doYouLikeFormBloc = SelectFieldBloc( validators: [FieldBlocValidators.required], items: ['No', 'Yes'], );

    final whyNotYouLikeFormBloc = TextFieldBloc( validators: [FieldBlocValidators.required], );

    final showSecretField = BooleanFieldBloc();

    final secretField = TextFieldBloc( validators: [FieldBlocValidators.required], );

    ConditionalFieldsFormBloc() { addFieldBlocs( fieldBlocs: [ doYouLikeFormBloc, ], );

    showSecretField.onValueChanges(
      onData: (previous, current) async* {
        if (current.value) {
          addFieldBlocs(fieldBlocs: [secretField]);
        } else {
          removeFieldBlocs(fieldBlocs: [secretField]);
        }
      },
    );
    
    doYouLikeFormBloc.onValueChanges(
      onData: (previous, current) async* {
        removeFieldBlocs(
          fieldBlocs: [
            whyNotYouLikeFormBloc,
            showSecretField,
            secretField,
          ],
        );
    
        if (current.value == 'No') {
          addFieldBlocs(fieldBlocs: [
            whyNotYouLikeFormBloc,
          ]);
        } else if (current.value == 'Yes') {
          addFieldBlocs(fieldBlocs: [
            showSecretField,
            if (showSecretField.value) secretField,
          ]);
        }
      },
    );
    

    }

    @override Future close() { whyNotYouLikeFormBloc.close(); showSecretField.close(); secretField.close();

    return super.close();
    

    } }

    opened by nilesh2211 7
  • Mark form as invalid by default

    Mark form as invalid by default

    Hi,

    I'm using a form with autoValidate = true together with isValid() to trigger the state of my submit button. The problem I'm facing is that when loading the form, it is marked as valid for a split second, which causes the button to be active, before the fields are actually validated for the first time.

    As I know that the form will be invalid by default (I have required fields) it would be really helpful to be able to mark the form as invalid by default.

    I'm not sure if this would work correctly (I'm not familiar with the multistep forms) but my proposal would be to:

    • Add an isInitiallyValid parameter to FormBloc (default with true to not break anything)
    • Depending on the value set isValidByStep of FormBlocState to {0: false} initially
    opened by Almighty-Alpaca 7
  • By Introducing new widgets in between your forms, there seems no way to handle the states

    By Introducing new widgets in between your forms, there seems no way to handle the states

    For e.g, I added a image picker widget, so on picking the image file, I want to hide the image pick widget and place the actual image picked on top of that, but I think that is not getting possible as there is no generic bloc builder for that

    opened by sreyans01 0
  • addFieldBlocs and removeFieldBlocs issue

    addFieldBlocs and removeFieldBlocs issue

    I'm using addFieldBlocs and removeFieldBlocs based on SelectFieldBloc changes. The problem is when I use declare: static final EmployerLogo = InputFieldBloc<ElevatedButton?, dynamic>( initialValue: null, validators: [FieldBlocValidators.required], ); and included in widget build in: BlocBuilder<InputFieldBloc, InputFieldBlocState>( bloc: ConditionalFieldsForm.EmployerLogo, builder: (context, state) { return ElevatedButton( onPressed: () async { logo = await ImagePickerServices .getImageAsFile(); if (logo == null) return;

                                    logoUrl = await FirebaseStorageServices
                                        .uploadToStorageAsHTMLFile(
                                            file: logo!,
                                            folderName: StorageFolderNames
                                                .employerFolder);
    
                                    setState(() {});
                                  },
                                  child: Text('     Upload Employer Logo     '),
                                );
                              },
                            ),
    

    the changes on SelectFieldBloc doesn't add or remove the button. it is stuck like in the next image: image

    opened by nawaf-na1807684 0
  • How to submitting form_bloc into API using model & params?

    How to submitting form_bloc into API using model & params?

    I have a model and I want to submit data input from form_bloc into it, the data should be submitted into params and the data is placed inside List<dynamic>? response; how to submit it with using form_bloc?

    class FormModel {
      bool? status;
      String? message;
      List<dynamic>? response;
      double? generated;
      int? tokenExpire;
      int? serverTime;
    
      FormModel({
        this.status,
        this.message,
        this.response,
        this.generated,
        this.tokenExpire,
        this.serverTime,
      });
    
      FormModel.fromJson(Map<String, dynamic> json) {
        status = json['status'] as bool?;
        message = json['message'] as String?;
        response = json['response'] as List?;
        generated = json['generated'] as double?;
        tokenExpire = json['tokenExpire'] as int?;
        serverTime = json['serverTime'] as int?;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> json = <String, dynamic>{};
        json['status'] = status;
        json['message'] = message;
        json['response'] = response;
        json['generated'] = generated;
        json['tokenExpire'] = tokenExpire;
        json['serverTime'] = serverTime;
        return json;
      }
    }
    
    opened by nameaisy 0
  • Making Switch adaptive.

    Making Switch adaptive.

    I changed the Switch implementation in SwitchFieldBlocBuilder to be adaptive and support the Cupertino design to provide a better experience for IOS users.

    opened by Abdullah104 1
Flutter bloc example - An app for State management using BLoC pattern in Flutter

Flutter BLoC My first app for State management using BLoC pattern in Flutter Col

Harshil Patel 1 Jun 16, 2022
An extension to the bloc state management library which lets you create State Machine using a declarative API

An extension to the bloc state management library which lets you create State Machine using a declarative API

null 25 Nov 28, 2022
An extension to the bloc state management library which automatically persists and restores bloc states.

โš ๏ธ Attention: This repository has been moved to https://github.com/felangel/bloc and is now read-only! An extension to the bloc state management libra

Felix Angelov 189 Nov 17, 2022
Practice building basic animations in apps along with managing app state by BLoC State Management, Flutter Slider.

Practice building basic animations in apps along with managing app state by BLoC State Management including: Cubit & Animation Widget, Flutter Slider.

TAD 1 Jun 8, 2022
Minimalist and Easy State Management for Bloc Inspired from Dart Generics.

Velocity Bloc Getting started In the pubspec.yaml of your flutter project, add the following dependency: dependencies: ... velocity_bloc: <latest_

Sangam Singh 18 Aug 1, 2023
A Flutter package that provides a dropdown form field using a dropdown button inside a form field.

Dropdown form field A dropdown form field using a dropdown button inside a form field. Demo Features Can be used as regular form field. Simple to impl

Carlos Eugenio Torres 72 Jan 1, 2023
Simple yet powerful form state management

formini Working with forms shouldn't be so hard in Flutter. Please note that the schemani/formini packages are under development. There are still some

Vantage Oy 1 Dec 12, 2019
MVC pattern for flutter. Works as state management, dependency injection and service locator.

MVC pattern for flutter. Works as state management, dependency injection and service locator. Model View Controller Here's a diagram describing the fl

xamantra 115 Dec 12, 2022
Flutter form fields designed to take much of the burden of form-related coding off the programmer's back โ€” masks, validations, keyboard type, etc.

well_formed Contents Overview Getting Started Demo application References Overview Well-Formed Widget Fields - Well-Formed - is a collection of Flutte

Dartoos 7 Nov 2, 2022
User auth form - Signup and signin user auth form with ability to stay signed in and have an option to signout.

user_auth_form SIgnup and signin user authentification form Getting Started This project is a starting point for a Flutter application. A few resource

null 0 Jan 6, 2022
Form builder image picker - Form builder image picker for flutter

form_builder_image_picker Field for picking image(s) from Gallery or Camera for

Ferri Sutanto 0 Jan 28, 2022
Jannis 0 Jan 29, 2022
A simple to-do list built using flutter based on BLoC state management to manage your daily tasks .

?? Table of Contents About ScreenShots from the app Demo vedio Contributors About A to-do list flutter app to manage your daily tasks. it is built bas

Heba Ashraf 6 Oct 12, 2022
Small calculator made to exemplify state management principles in Flutter using BLoC.

Oop Class Flutter Template Generated by the Very Good CLI ?? A Very Good Project created by Very Good CLI. Getting Started ?? This project contains 3

null 4 Dec 19, 2022
๐Ÿ’ป Flutter clean architecture using the bloc & cubit library for state management

Egymation ?? ยท This application was developed using a well-defined and decoupled architecture, following TDD (test-driven programming) as a working me

Mohaned Zekry 3 Nov 21, 2022
Shopify Tag and Product Management App using Flutter and Riverpod State Management

Myshopify App A Simple Flutter Application project to get List of Tags, Products and Product Details from shopify https://shopicruit.myshopify.com/adm

Idowu Tomiwa 5 Nov 12, 2022
State Persistence - Persist state across app launches. By default this library store state as a local JSON file called `data.json` in the applications data directory. Maintainer: @slightfoot

State Persistence Persist state across app launches. By default this library store state as a local JSON file called data.json in the applications dat

Flutter Community 70 Sep 28, 2022
This project follows the Reso Coder course for flutter test-driven-development with clean architecture and BloC state management for a random trivia simple app.

This project follows the Reso Coder course for flutter test-driven-development with clean architecture and BloC state management for a random trivia simple app.

Tomas B Sarmiento Abella 1 Jan 5, 2022
Building a simple Flutter app for understanding the BLoC State Management including: Cubit, Managing Route & showSnackBar.

Building a simple Flutter app for understanding the BLoC State Management including: Cubit, Managing Route & showSnackBar.

TAD 8 Dec 3, 2022