formini 0.0.1-alpha.1 copy "formini: ^0.0.1-alpha.1" to clipboard
formini: ^0.0.1-alpha.1 copied to clipboard

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 issues to resolve before this has any help for real use cases. #roadmap

Usage #

Formini doesn't care what inputs you use. It however provides a TextEditingController via state.controller out of the box. For inputs other than TextFields you can use state.onChange and state.field.value.

Values are not limited only to Dart built in types. If you want to store a date field as DateTime and display the value formatted you absolutely can.

Login form using formini

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

class LoginForm extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Formini(
      validator: const LoginFormValidator(),
      initialValues: const {'email': 'foo'},
      onSubmit: _authenticate,
      child: Column(children: [
        ForminiStateBuilder(builder: (context, form) {
          return Column(children: [
            Text('Status: ${form.status}'),
            Text('Values: ${form.values}'),
          ]);
        }),
        ForminiField(
          name: 'email',
          builder: (context, state) => TextField(
            controller: state.controller,
            decoration: InputDecoration(
              labelText: 'Email address',
              errorText: state.field.errorText,
            ),
          ),
        ),
        ForminiField(
          name: 'password',
          builder: (context, state) => TextField(
            controller: state.controller,
            obscureText: true,
            decoration: InputDecoration(
              labelText: 'Password',
              errorText: 
                  state.field.touched ? state.field.error?.toString() : null,
            ),
          ),
        ),
        ForminiStateBuilder(builder: (context, form) {
          return RaisedButton(
            onPressed: form.submit,
            child: Text('Login'),
          );
        }),
      ]),
    );
  }

  Future<bool> _authenticate(Map<String, dynamic> credentials) async {
    // Do what ever you need to do here.
    print(credentials);
    
    return true;
  }
}

Validation #

Implement the Validator interface on your validator class.

1. Option - Manually

import 'package:formini/formini.dart';

class LoginFormValidator implements Validator {
  const LoginFormValidator();

  @override
  Map<String, Exception> validate(Map<String, dynamic> values) {
    final errors = <String, Exception>{};

    if (values['email'] == null || values['email'].isEmpty) {
      errors['email'] = Exception('Email is required');
    } else if (!values['email'].contains('@')) {
      errors['email'] = Exception('Email is invalid');
    }

    if (values['password'] == null || values['password'].isEmpty) {
      errors['password'] = Exception('Password is required');
    }

    return errors;
  }
}

Use schemani_formini package for validating values using schemani. Or just copy the one simple file to your project.

import 'package:schemani/schemani.dart';
import 'package:schemani_formini/schemani_formini.dart';

const loginFormValidator = SchemaniForminiValidator(MapSchema({
  'email': [Required(), Email()],
  'password': [Required()],
}));

API reference #

https://pub.dev/documentation/formini

Contributing #

Please open an issue or pull request in GitHub. Any help and feedback is much appreciated.

Licence #

MIT

Roadmap #

  • Support for nested values maps
  • Support for lists
  • Async validation
  • Unit testing after refactoring
    • Separate core out from the Flutter stuff
  • Benchmarking
1
likes
20
pub points
0%
popularity

Publisher

unverified uploader

Simple yet powerful form state management

Homepage

License

MIT (license)

Dependencies

bloc, flutter, flutter_bloc, rxdart

More

Packages that depend on formini