formx 0.36.0
formx: ^0.36.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_async
to handle errors effortlessly.
FormState extensions #
.toMap({FormxOptions? options})
, a structuredMap
with all the values of the form.- Use
options
to modify the output. Ifnull
, the globalFormx.options
will be used. - If a
Key
is used, it will apply the associated adapter or unmask to the value.
- Use
.rawValues
, a structuredMap
with all [FormFieldState.value]. Unmodified..initialValues
, a structuredMap
with 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 flatMap
with 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.
defaultTitle
to set the default title for fields that internally useListTile
.datePicker
to pick a date inFormField<DateTime>
fields.image/filePicker
to pick a file inFormField<XFile>
fields.image/filesPicker
to pick a file inFormField<List<XFile>>
fields.image/fileUploader
to upload a file inFormField<XFile>
fields.image/fileDeleter
to delete a file inFormField<XFile>
fields.
FormxOptions #
You can use Formx.options
to modify FormState.values
output.
trim
removes leading and trailing whitespaces.unmask
removes all [MaskedInputFormatter] masks.nonNull
removes allnull
values.nonEmptyMaps
removes all empty maps.nonEmptyStrings
removes all empty strings.nonEmptyIterables
removes all empty iterables.
By default, all options are enabled, except for [nonEmptyIterables].
To get the unmodified values, use
FormState.rawValues
.
FieldKey options #
.adapter
to format the field value..unmask
to (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
#
.pairs
for getting a list of key-value pairs..indented
for a map view that indents when printed..indentedText
for getting an indented text..deepMap()
for mapping nested maps..clean()
for values that arenull
or empty string/iterable/map..cleaned()
for a new map with allnull
or 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>
#
.keepAlive
usually needed for building forms with [PageView.children]..expanded
usually 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.