formx 0.37.0
formx: ^0.37.0 copied to clipboard
Access, build, format, validate, sanitize and fill forms easily with Form/Field extensions.
Formx #
Acessing the state #
BuildContext.formx(String key) automatically retrieves FormState by key value.
// specify the form key:
final addressState = context.formx('address');
if (addressState.validate()) {
final map = addressState.toMap();
addressState.save();
// do your logic
} else {
throw FormxException(addressState.errorTexts);
}
You can do the same for a specific field
final emailState = context.field('email')
Submit shortcut #
Performs .validate(), .save() and .toMap(). Throws errorTexts if invalid.
// essentially the same as the code above, but in one line
final map = context.submit('address');
final mapOrNull = context.trySubmit('address');
We recommend using it with
flutter_asyncto handle errors effortlessly.
FormState extensions #
.toMap({FormxOptions? options}), a structuredMapwith all the values of the form.- Use
optionsto modify the output. Ifnull, the globalFormx.optionswill be used. - If a
Keyis used, it will apply the associated adapter or unmask to the value.
- Use
.rawValues, a structuredMapwith all [FormFieldState.value]. Unmodified..initialValues, a structuredMapwith all [FormField.initialValue]. Unmodified..isInitial, whether any nested [FormFieldStateExtension.isInitial]..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 flatMapwith all nested [FormFieldState.errorText]..fill(Map<String, dynamic> map), sets each associated field by it's key-value pair.
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. RequiresValidator.
FormxSetup #
You can use Formx.setup to set global options for all formx widgets.
defaultTitleto set the default title for fields that internally useListTile.datePickerto pick a date inFormField<DateTime>fields.image/filePickerto pick a file inFormField<XFile>fields.image/filesPickerto pick a file inFormField<List<XFile>>fields.image/fileUploaderto upload a file inFormField<XFile>fields.image/fileDeleterto delete a file inFormField<XFile>fields.
FormxOptions #
You can use Formx.options to modify FormState.values output.
trimremoves leading and trailing whitespaces.unmaskremoves all [MaskedInputFormatter] masks.nonNullremoves allnullvalues.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.
FieldKey options #
.adapterto format the field value..unmaskto (un)mask the field value, regardless of the form global options.
TextFormField(
key: const Key('age').options(
unmask: true,
adapter: (String value) => value?.toInt(),
),
),
Validator class #
Looking for a way to create validators declaratively? Validator class provides a readable and declarative approach to defining validation rules for your Dart applications.
TextFormField(
validator: Validator<String>(
required: true,
test: (value) => value.isEmail,
),
),
For the one-liners, the modifiers allows you to chain your validators.
TextFormField(
validator: Validator().required().email(),
),
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
// In case you need to temporarily disable all validators:
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)
Iterable #
.castJson()for casting any List as List<Map<String, dynamic>>..mapJson()for mapping any jsonList to List.orderedBy(R selector(T), {bool ascending})for ordering.
Map #
.pairsfor getting a list of key-value pairs..indentedfor a map view that indents when printed..indentedTextfor getting an indented text..deepMap()for mapping nested maps..clean()for values that arenullor empty string/iterable/map..cleaned()for a new map with allnullor 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.