flutter_formx 2.1.0 copy "flutter_formx: ^2.1.0" to clipboard
flutter_formx: ^2.1.0 copied to clipboard

Flutter FormX provides an easy way of dealing with forms and their states without creating a lot of boilerplate code.

Flutter FormX #

pub package

Flutter FormX Logo

Flutter FormX is a package to make it easy to build, react to and validate forms using MobX.

Features #

Working form gif

  • Responsive state and form answer caching on current instance.
  • Form validation.
  • Abstract ValidationResult and Validator classes to help you integrate with form builder and make your own validations.

Requirements #

This library is designed to work with MobX and MobX Code generation as its state management provider. It does not support BLoC, Provider or GetX as of yet.

Make sure to include both dependencies on your project and run build runner once everything is set:

dependencies:
  mobx: <version>
  mobx_codegen: <version>

Running build runner:

flutter pub run build_runner build

Usage #

  1. Add the flutter_formx package to your pubspec dependencies.

  2. Import flutter_formx.

    import 'package:flutter_formx/flutter_formx.dart';
    
  3. Apply the mixin to your mobx store, specifying the type of the keys that will be used to retrieve each form field.

    class ExamplePageViewModel extends _ExamplePageViewModelBase with _$ExamplePageViewModel {
      ExamplePageViewModel();
    }
    
    abstract class _ExamplePageViewModelBase with Store, FormX<String> {
      _ExamplePageViewModelBase();
    }
    
  4. As soon as the view is ready, make sure to call setupForm with a map of FormXFields (an entry for each of the inputs):

    • The keys of this map will be used to access each specific field and must be of the same type used on FormX<Type> such as String, enum, int etc.
    • Create FormXFields with the type of the input inside the <> and use the FormXField.from constructor.
    • When creating FormXFields you should pass its initial value, its validators and onValidationError (if needed) to log any errors when validating.

    Example:

    setupForm({
      'firstName': FormXField<String?>.from(
        value: null,
        validators: [
          RequiredFieldValidator(...),
        ],
        onValidationError: _logValidationError,
      ),
      'lastName': FormXField<String?>.from(
        value: null,
        validators: [
          RequiredFieldValidator(...),
        ],
        onValidationError: _logValidationError,
      ),
      'email': FormXField<String?>.from(
        value: null,
        validators: const [],
      ),
    });
    
  5. Access the fields values and errors in the UI using getFieldValue<T>(key) and getFieldErrorMessage<T>(key), either with computed mobx getters or using the FormX's getters directly in the UI.

    /// using computed mobx getters on the store
    @computed
    String? get firstName => getFieldValue<String?>('firstName');
    
    @computed
    String? get firstNameError => getFieldErrorMessage('firstName');
    
    /// using directly in your Widget (make sure to wrap it in an Observer if you want to observe to the changes)
    Text(
      'First Name: ${getFieldValue<String?>('email')}',
    ),
    
  6. Update any field in the form using the inbuilt updateAndValidateField and updateField methods when the input is updated on your Widget.

    Future<void> updateFirstName(String? newValue) async {
      await updateAndValidateField(newValue, 'firstName');
    }
    
  7. Quick tip: always validate your entire form before submitting information to the server.

    @action
    Future<void> submitForm() async {
      if (await validateForm()) {
        // submit form
      }
    }
    

Validators #

You can create any kind of validator needed specifically for your needs and according to the field type you have. We've included the RequiredFieldValidator, but feel free to create more in your project as you need.

Create your own validators #

You can do that by creating a class that extends the Validator class. See example below:

Example:

class EmailValidator extends Validator<String?> {
  final String errorMessage;

  EmailValidator(
    this.errorMessage,
  );

  @override
  Future<ValidatorResult> validate(value) {
    if (value == null || value.isEmpty) {
      return result(isValid: true);
    }

    final isEmailValid = _validateEmail(value);

    return result(
      isValid: isEmailValid,
      errorMessage: errorMessage,
    );
  }

  bool _validateEmail(String email) {
    final regex = RegExp(r'^[^@,\s]+@[^@,\s]+\.[^@,.\s]+$');

    return regex.hasMatch(email);
  }
}

Note
We recommend avoiding implementing more than one validation in each validator. If the field must be required and a valid email, add two validators, such as [RequiredValidator(), EmailValidator()]. This way you can reuse the email validator if this field ever becomes optional.

Testing #

See example/test for testing examples.

14
likes
150
pub points
47%
popularity

Publisher

verified publisherrevelo.com

Flutter FormX provides an easy way of dealing with forms and their states without creating a lot of boilerplate code.

Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter, mobx

More

Packages that depend on flutter_formx