feat(form): add helpers

This commit is contained in:
Hugo Pointcheval 2022-07-10 22:10:12 +02:00
parent 89f94cf1ff
commit 8909274543
Signed by: hugo
GPG Key ID: A9E8E9615379254F
3 changed files with 69 additions and 33 deletions

View File

@ -18,8 +18,13 @@ part of 'form_data_cubit.dart';
@immutable @immutable
class FormDataState extends Equatable { class FormDataState extends Equatable {
/// Global status of a form.
final FormStatus status; final FormStatus status;
/// FormData with all inputs, and associated metadata.
final FormData data; final FormData data;
/// Optional error message.
final String? errorMessage; final String? errorMessage;
const FormDataState({ const FormDataState({

View File

@ -76,11 +76,21 @@ enum FormStatus {
/// Indicates whether the form submission has been canceled. /// Indicates whether the form submission has been canceled.
bool get isSubmissionCanceled => this == FormStatus.submissionCanceled; bool get isSubmissionCanceled => this == FormStatus.submissionCanceled;
/// Validate a list of inputs /// Validate a list of inputs by processing them in `validate` as validators.
static FormStatus validate(List<FormInput> inputs) { static FormStatus validateInputs(List<FormInput> inputs) {
return inputs.every((FormInput input) => input.validator.pure) return validate(
inputs
.map<FormInputValidator>((FormInput input) => input.validator)
.toList(),
);
}
/// Validate a list of validators.
static FormStatus validate(List<FormInputValidator> validators) {
return validators.every((FormInputValidator validator) => validator.pure)
? FormStatus.pure ? FormStatus.pure
: inputs.any((FormInput input) => input.validator.valid == false) : validators
.any((FormInputValidator validator) => validator.valid == false)
? FormStatus.invalid ? FormStatus.invalid
: FormStatus.valid; : FormStatus.valid;
} }

View File

@ -23,8 +23,11 @@ class FormData extends Equatable {
const FormData(this._inputs); const FormData(this._inputs);
const FormData.empty() : this(const <FormInput>[]); const FormData.empty() : this(const <FormInput>[]);
/// Returns all inputs as a list
List<FormInput> inputs() => _inputs;
/// Returns the input for the associated key /// Returns the input for the associated key
FormInput inputByKey(String key) { FormInput inputOf(String key) {
if (contains(key)) { if (contains(key)) {
return _inputs.firstWhere((FormInput input) => input.key == key); return _inputs.firstWhere((FormInput input) => input.key == key);
} else { } else {
@ -36,65 +39,83 @@ class FormData extends Equatable {
void updateInput(String key, FormInput input) { void updateInput(String key, FormInput input) {
if (contains(key)) { if (contains(key)) {
final index = _inputs.indexOf( final index = _inputs.indexOf(
inputByKey(key), inputOf(key),
); );
_inputs[index] = input; _inputs[index] = input;
} }
} }
/// Updates validator of a given input. (perform copyWith) /// Returns all associated validators as a list
void updateValidator(String key, FormInputValidator dirtyValue) { List<FormInputValidator<V, E>> validators<V, E>() {
if (contains(key)) { return _inputs
final index = _inputs.indexOf( .map<FormInputValidator<V, E>>(
inputByKey(key), (FormInput input) => input.validator as FormInputValidator<V, E>,
); )
_inputs[index] = _inputs[index].copyWith(validator: dirtyValue); .toList();
}
}
/// Updates metadata of a given input. (perform copyWith)
void updateMetadata(String key, FormInputMetadata meta) {
if (contains(key)) {
final index = _inputs.indexOf(
inputByKey(key),
);
_inputs[index] = _inputs[index].copyWith(metadata: meta);
}
} }
/// A [FormInputValidator] represents the value of a single form input field. /// A [FormInputValidator] represents the value of a single form input field.
/// It contains information about the [FormInputStatus], value, as well /// It contains information about the [FormInputStatus], value, as well
/// as validation status. /// as validation status.
T validatorOf<T>(String key) { T validatorOf<T>(String key) {
return inputByKey(key).validator as T; return inputOf(key).validator as T;
}
/// Updates validator of a given input. (perform copyWith)
void updateValidator(String key, FormInputValidator dirtyValue) {
if (contains(key)) {
final index = _inputs.indexOf(
inputOf(key),
);
_inputs[index] = _inputs[index].copyWith(validator: dirtyValue);
}
} }
/// Returns a validation error if the [FormInputValidator] is invalid. /// Returns a validation error if the [FormInputValidator] is invalid.
/// Returns null if the [FormInputValidator] is valid. /// Returns null if the [FormInputValidator] is valid.
E? errorOf<V, E>(String key) { E? errorOf<V, E>(String key) {
return (inputByKey(key).validator as FormInputValidator<V, E>).error; return (inputOf(key).validator as FormInputValidator<V, E>).error;
} }
/// The value of the associated [FormInputValidator]. For example, /// The value of the associated [FormInputValidator]. For example,
/// if you have a FormInputValidator for FirstName, the value could be 'Joe'. /// if you have a FormInputValidator for FirstName, the value could be 'Joe'.
V valueOf<V, E>(String key) { V valueOf<V, E>(String key) {
return (inputByKey(key).validator as FormInputValidator<V, E>).value; return (inputOf(key).validator as FormInputValidator<V, E>).value;
} }
/// Returns `true` if the [FormInputValidator] is not valid. /// Returns `true` if the [FormInputValidator] is not valid.
/// Same as `E? errorOf<V, E>(String key) != null` /// Same as `E? errorOf<V, E>(String key) != null`
bool isNotValid(String key) { bool isNotValid(String key) {
return !inputByKey(key).validator.valid; return !inputOf(key).validator.valid;
}
/// Returns all associated metadata as a list
List<FormInputMetadata<M>> metadata<M>() {
return _inputs
.map<FormInputMetadata<M>>(
(FormInput input) => input.metadata as FormInputMetadata<M>,
)
.toList();
} }
/// Returns the metadata associated. With `M` the type of extra data. /// Returns the metadata associated. With `M` the type of extra data.
FormInputMetadata<M> metadataOf<M>(String key) { FormInputMetadata<M> metadataOf<M>(String key) {
return inputByKey(key).metadata as FormInputMetadata<M>; return inputOf(key).metadata as FormInputMetadata<M>;
}
/// Updates metadata of a given input. (perform copyWith)
void updateMetadata(String key, FormInputMetadata meta) {
if (contains(key)) {
final index = _inputs.indexOf(
inputOf(key),
);
_inputs[index] = _inputs[index].copyWith(metadata: meta);
}
} }
/// Validate self inputs. /// Validate self inputs.
FormStatus validate() { FormStatus validate() {
return FormStatus.validate(_inputs); return FormStatus.validateInputs(_inputs);
} }
/// Check if this contains an input with the given key. /// Check if this contains an input with the given key.