formx 0.15.0  formx: ^0.15.0 copied to clipboard
formx: ^0.15.0 copied to clipboard
Access, build, validate, sanitize and fill forms easily with Formx.
Formx #
   
   
Acessing the state #
BuildContext.formx([String? key]) automatically retrieves the appropriate FormState for you, though you can specify a key if necessary.
final state = context.formx();
final addressState = context.formx('address');
final email = context.field('email').value;
Alternatively, use Formx.of(context) for a traditional approach without visitors.
⚠️ Be careful, as using it will also rebuild the widget tree on any field change, just as
Form.of(context).
FormState extensions #
- .value<T>(String key), gets the [FormFieldState.value] of a specific field.
- .rawValues, a structured- Mapwith all raw [FormField.value] of the form.
- .values, same as- rawValues, but with global [FormxOptions] applied.
- .customValues(), same as- rawValues, but with explicit options applied.
- .initialValues, a structured- Mapwith all the initial values of the form.
- .hasInteractedByUser, whether any nested [FormFieldState.hasInteractedByUser].
- .hasError, whether any nested [FormFieldState.hasError].
- .isValid, whether all nested [FormFieldState.isValid].
- .invalids, a list with all invalid field keys, regardless if validated.
- .errorTexts, a flat- Mapwith all nested [FormFieldState.errorText].
- operator [key], operator to get a specific [FormFieldState] by it's key value.
- operator [key] = value, operator to set any nested form/field value(s) directly.
FormxState extension type #
FormxState is an inline-class that redeclares some of the FormState methods:
- .validate([List<String>? keys])
- .save([List<String>? keys])
- .reset([List<String>? keys])
These methods function identically to their original counterparts but extend their effects to nested forms. Using FormState.validate only validates the top-level form, whereas FormxState.validate also validates any nested forms.
You have the option to specify a list of keys with these methods to target specific forms or fields for validation, saving, or resetting.
You can redeclare any FormState to a FormxState by using FormxState(formState) type extension.
FormFieldState extensions #
- .setErrorText(String? errorText), sets the field errorText programmatically. Requires- Validator.
FormxOptions #
You can use Formx.options to modify FormState.values output.
- trimremoves leading and trailing whitespaces.
- unmaskremoves all [MaskTextInputFormatter] masks.
- nonNullremoves all- nullvalues.
- nonEmptyMapsremoves all empty maps.
- nonEmptyStringsremoves all empty strings.
- nonEmptyIterablesremoves all empty iterables.
By default, all options are enabled, except for [nonEmptyIterables].
To get the unmodified values, use
FormState.rawValues.
To understand how masks are applied, see mask_text_input_formatter library, also exported by this package.
Validator class #
Looking for a way to create validators declaratively? The Validator class provides a readable and declarative approach to defining validation rules for your Dart applications.
TextFormField(
  validator: Validator<String>(
    isRequired: true,
    test: (value) => value.isEmail,
  ),
),
For the one-liners, the modifiers allows you to chain your validators.
TextFormField(
  validator: Validator().required().email(),
),
You can also easily create custom validators:
extension CustomValidators on Validator<T> {
  Validator<T> myValidator([String? requiredText]) {
    return test((value) => /* your logic here */, requiredText);
  }
}
Customizing #
// You can set a default `requiredText`/`invalidText` for all validators:
Validator.defaultRequiredText = 'This field is required';
Validator.defaultInvalidText = 'This field is invalid';
// You can also modify the errorText of a validator:
Validator.translator = (key, errorText) => errorText; // good for translations
// And disable them all:
Validator.disableOnDebug = true; // only works on debug mode
Modifiers #
- .test(bool Function(T value) test)
- .number(bool Function(num value) test)
- .datetime(bool Function(DateTime value) test)
- .required
- .email
- .url
- .phone
- .creditCard
- .cpf
- .cnpj
- .date
- .alpha
- .numeric
- .alphanumeric
- .hasAlpha
- .hasNumeric
- .hasAlphanumeric
- .hasUppercase
- .hasLowercase
- .hasSpecialCharacter
- .minLength(int length)
- .maxLength(int length)
- .minWords(int words)
- .maxWords(int words)
- .minNumber(num number)
- .maxNumber(num number)
- .isAfter(DateTime date)
- .isBefore(DateTime date)
Validators, Sanitizers & Helpers extensions #
Formx comes bundled with a set of built-in validators and sanitizers, which you can use to validate and sanitize your form fields.
String #
- .isPhone
- .isCpf
- .isCnpj
- .numeric(returns the numbers)
- .alpha(returns the letters)
- .alphanumeric(returns numbers/letters)
- .hasAlpha
- .hasNumeric
- .hasAlphanumeric
- .hasUppercase
- .hasLowercase
- .hasSpecialCharacters
- .equalsIgnoreCase(String)
Additionally exports string_validator library. See it for complete list of extensions.
Map #
- .indentedfor a map view that indents when printed.
- .indentedTextfor getting an indented text.
- .deepMap()for mapping nested maps.
- .clean()for values that are- nullor empty string/iterable/map.
- .cleaned()for a new map with all- nullor empty values removed.
Deeply recases all your map keys:
- .camelCase"camelCase"
- .constantCase"CONSTANT_CASE"
- .sentenceCase"Sentence case"
- .snakeCase"snake_case"
- .dotCase"dot.case"
- .paramCase"param-case"
- .pathCase"path/case"
- .pascalCase"PascalCase"
- .headerCase"Header-Case"
- .titleCase"Title Case"
Additionally exports recase library. See it for complete list of extensions.
List<Widget> #
- .keepAliveusually needed for building forms with [PageView.children].
- .expandedusually needed for building forms with [Column.children] or [Row.children].
Contributing #
Contributions to formx are welcome! Whether it's bug reports, feature requests, or pull requests, all "forms" of collaboration can help make formx better for everyone.