form_validation 1.0.0+1

  • Readme
  • Changelog
  • Example
  • Installing
  • new69

form_validation #

Form validators that can be used directly via code or constructed from JSON to provide more dynamic validation.

Using the library #

Add the repo to your Flutter pubspec.yaml file.

dependencies:
  form_validation: <<version>> 

Then run...

flutter packages get

Validators #

The library provides a set of built-in validators while also providing a mechanism for applications to provide their own validators. All the built-in validators are able to be deserialized via JSON. They all expect an attribute of type to match a specific value when being desearialized.

Note: With the sole exception of RequiredValidator, all built in validators will pass on null or empty values.

ClassTypeDescription
CurrencyValidatorcurrencyEnsures the value is a valid currency
EmailValidatoremailEnsures the value is a validly formatted email address
MaxLengthValidatormax_lengthEnsures the value contains no more than a set number of characters
MaxNumberValidatormax_numberEnsures the value is no larger than a given number
MinLengthValidatormin_lengthEnsures the value contains no fewer than a set number of characters
MinNumberValidatormin_numberEnsures the value is no smaller than a given number
NumberValidatornumberEnsures the value is a valid number
PhoneNumberValidatorphone_numberEnsures the value is a validly formatted phone number
RequiredValidatorrequiredEnsures the value is not null, empty, nor white space only

Validation Messages / Translations #

The library provides a default set of English error messages for each validator's error message. This library uses the static_translations library for the string and language management, see it for details on how to override the defaults or provide values for other languages.

KeyParametersDescription
form_validation_currencylabelUsed when an invalid currency value is detected
form_validation_currency_positivelabelUsed when a valid, but negative, currency value is detected
form_validation_emaillabelUsed when an invalid email is detected
form_validation_max_lengthlabel, lengthUsed when a value contains more characters than length
form_validation_max_numberlabel, numberUsed when a value is larger than number
form_validation_min_lengthlabel, lengthUsed when a value contains fewer characters than length
form_validation_min_numberlabel, numberUsed when a value is smaller than number
form_validation_numberlabelUsed when a number is expected but not detected
form_validation_number_decimallabelUsed when a number is detected, but not allowed to be a decimal
form_validation_phone_numberlabelUsed when an invalid phone number is detected
form_validation_requiredlabelUsed when a value is required, but detected as null, empty, or all white space

JSON Support #

The Validator class can be used to decode a list of child ValueValidator entries. Each of the built-in validators can be deserialized via JSON. In addition to being able to deserialize from JSON, each of the built-in validators supports serializing to a JSON compatible map via toJson or an actual JSON encoded string via toJsonString.

The overall struction needs to be:

{
  "validators": [
    // One or more of the JSON objects shown below
  ]
}

CurrencyValidator #

{
  "allowNegative": <bool>, // Default: true; states whether negative values are allowed or not
  "type": "currency"
}

EmailValidator #

{
  "type": "email"
}

MaxLengthValidator #

{
  "length": <int>, // The maximum length the value may be
  "type": "max_length"
}

MaxNumberValidator #

{
  "length": <int>, // The maximum number the value may be
  "type": "max_number"
}

MinLengthValidator #

{
  "length": <int>, // The minimum length the value may be
  "type": "min_length"
}

MinNumberValidator #

{
  "length": <int>, // The minimum number the value may be
  "type": "min_number"
}

NumberValidator #

{
  "type": "number"
}

PhoneNumberValidator #

{
  "type": "phone_number"
}

RequiredValidator #

{
  "type": "required"
}

Custom Validators #

The Validator supports custom validators being added either directly through classes extending the ValueValidator abstract class and passing them in via the constructor. Alternatively, an application may register a validator type with Validator using the registerCustomValidatorBuilder function.

Example #

class MyCustomValidator extends ValueValidator {
  static const type = 'my_custom_validator';

  static MyCustomValidator fromDynamic(dynamic map) {
    MyCustomValidator({
      // initialization args go here
    });

    MyCustomValidator result;

    if (map != null) {
      assert(map['type'] == type);

      result = MyCustomValidator(
        // Do additional JSON conversion here
      )
    })

    return result;
  }

  Map<String, dynamic> toJson() => {
    // add additional attributes here
    "type": type,
  }

  String validate({
    @required BuildContext context,
    @required String label,
    @required String value,
  }) {
    String error;

    // In general, validators should pass if the value is empty.  Combine 
    // validators with the RequiredValidator to ensure a value is non-empty.
    if (value?.isNotEmpty == true) {
      // Do processing to determine if the value is valid or not
    }

    return error;
  }
}

...

void main() {
  Validator.registerCustomValidatorBuilder(
    MyCustomValidator.type,
    MyCustomValidator.fromDynamic,
  );

  // start app
} 

...

var jsonStr = '''
{
  "validators": [{
    "type": "required"
  }, {
    "type": "my_custom_validator"
  }]
}
'''

// This will create a validation chain with the RequiredValidator as well as the
// MyCustomValidator defined above
var validator = Validator.fromDynamic(json.decode(jsonStr));

[1.0.0+1] - June 11th, 2020 #

  • Switched to GH Actions for

[1.0.0] - June 11th, 2020 #

  • Initial release

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:form_validation/form_validation.dart';
import 'package:form_floating_action_button/form_floating_action_button.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Validation Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _loading = false;

  void _onSubmit() async {
    setState(() => _loading = true);
    await Future.delayed(Duration(seconds: 3));
    _loading = false;
    if (mounted == true) {
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      child: Builder(
        builder: (BuildContext context) => Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: SingleChildScrollView(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                TextFormField(
                  decoration: InputDecoration(
                    labelText: 'Required',
                  ),
                  validator: (String value) {
                    var validator = Validator(
                      validators: [RequiredValidator()],
                    );

                    return validator.validate(
                      context: context,
                      label: 'Required',
                      value: value,
                    );
                  },
                ),
                SizedBox(
                  height: 16.0,
                ),
                TextFormField(
                  decoration: InputDecoration(
                    labelText: 'Email',
                  ),
                  validator: (String value) {
                    var validator = Validator(
                      validators: [
                        RequiredValidator(),
                        EmailValidator(),
                      ],
                    );

                    return validator.validate(
                      context: context,
                      label: 'Email',
                      value: value,
                    );
                  },
                ),
                SizedBox(
                  height: 16.0,
                ),
                TextFormField(
                  decoration: InputDecoration(
                    labelText: 'Min 3 / Max 5 Length',
                  ),
                  validator: (String value) {
                    var validator = Validator(
                      validators: [
                        MaxLengthValidator(length: 5),
                        MinLengthValidator(length: 3),
                      ],
                    );

                    return validator.validate(
                      context: context,
                      label: 'Min 3 / Max 5 Length',
                      value: value,
                    );
                  },
                ),
              ],
            ),
          ),
          floatingActionButton: FormFloatingActionButton(
            loading: _loading,
            onSubmit: _onSubmit,
            onValidate: () async {
              var error = Form.of(context).validate();
              return error;
            },
          ),
        ),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

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


dependencies:
  form_validation: ^1.0.0+1

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:form_validation/form_validation.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
39
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
69
Learn more about scoring.

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

  • Dart: 2.8.4
  • pana: 0.13.14
  • Flutter: 1.17.5

Analysis suggestions

Package not compatible with SDK dart

Because:

  • form_validation that is a package requiring null.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.5.0 <3.0.0
flutter 0.0.0
intl ^0.16.1 0.16.1
json_class ^1.0.1 1.0.3
meta ^1.1.8 1.1.8 1.2.2
static_translations ^1.0.0+1 1.0.0+1
Transitive dependencies
charcode 1.1.3
collection 1.14.12 1.14.13
convert 2.1.1
crypto 2.1.5
http 0.12.1
http_parser 3.1.4
logging 0.11.4
nested 0.0.4
path 1.7.0
pedantic 1.9.0 1.9.2
provider 4.3.1
rest_client 1.0.3
sky_engine 0.0.99
source_span 1.7.0
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6 1.2.0
uuid 2.2.0
vector_math 2.0.8 2.1.0-nullsafety
Dev dependencies
flutter_test