Compare commits
3 Commits
89f94cf1ff
...
b21aa04557
Author | SHA1 | Date | |
---|---|---|---|
b21aa04557 | |||
01df7a0dff | |||
8909274543 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -196,3 +196,4 @@ $RECYCLE.BIN/
|
||||
|
||||
.idea/
|
||||
*.iml
|
||||
google-services.json
|
||||
|
@ -31,23 +31,29 @@ class App extends StatelessWidget {
|
||||
|
||||
static FormData getNormalFormData() {
|
||||
return const FormData([
|
||||
FormEntry(formFieldName, Name.pure()),
|
||||
FormEntry(formFieldPhone, Phone.pure()),
|
||||
FormEntry(formFieldPro, Boolean.pure()),
|
||||
FormEntry(formFieldConfirmedPassword, ConfirmedPassword.pure(),
|
||||
export: false),
|
||||
FormInput(formFieldName, Name.pure()),
|
||||
FormInput(formFieldPhone, Phone.pure()),
|
||||
FormInput(formFieldPro, Boolean.pure()),
|
||||
FormInput(
|
||||
formFieldConfirmedPassword,
|
||||
ConfirmedPassword.pure(),
|
||||
metadata: FormInputMetadata(export: false),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
static FormData getProFormData() {
|
||||
return const FormData([
|
||||
FormEntry(formFieldName, Name.pure()),
|
||||
FormEntry(formFieldPhone, Phone.pure()),
|
||||
FormEntry(formFieldPro, Boolean.pure()),
|
||||
FormEntry(formFieldSiren, Siren.pure()),
|
||||
FormEntry(formFieldIban, Iban.pure()),
|
||||
FormEntry(formFieldConfirmedPassword, ConfirmedPassword.pure(),
|
||||
export: false),
|
||||
FormInput(formFieldName, Name.pure()),
|
||||
FormInput(formFieldPhone, Phone.pure()),
|
||||
FormInput(formFieldPro, Boolean.pure()),
|
||||
FormInput(formFieldSiren, Siren.pure()),
|
||||
FormInput(formFieldIban, Iban.pure()),
|
||||
FormInput(
|
||||
formFieldConfirmedPassword,
|
||||
ConfirmedPassword.pure(),
|
||||
metadata: FormInputMetadata(export: false),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -103,42 +109,42 @@ class App extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
AuthenticationRepositoryInterface _authenticationRepository =
|
||||
AuthenticationRepositoryInterface authenticationRepository =
|
||||
AuthenticationRepositoryFirebase();
|
||||
|
||||
AuthenticationCubit _authenticationCubit = AuthenticationCubit(
|
||||
authenticationRepository: _authenticationRepository,
|
||||
AuthenticationCubit authenticationCubit = AuthenticationCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
onAuthSuccess: onAuthSuccess,
|
||||
);
|
||||
|
||||
SignUpCubit _signUpCubit = SignUpCubit(
|
||||
authenticationRepository: _authenticationRepository,
|
||||
authenticationCubit: _authenticationCubit,
|
||||
SignUpCubit signUpCubit = SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: getNormalFormData(),
|
||||
onSignUpSuccess: onSignUpSuccess,
|
||||
);
|
||||
|
||||
SignInCubit _signInCubit = SignInCubit(
|
||||
authenticationRepository: _authenticationRepository,
|
||||
authenticationCubit: _authenticationCubit,
|
||||
SignInCubit signInCubit = SignInCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
);
|
||||
|
||||
return MultiRepositoryProvider(
|
||||
providers: [
|
||||
RepositoryProvider<AuthenticationRepositoryInterface>(
|
||||
create: (context) => _authenticationRepository,
|
||||
create: (context) => authenticationRepository,
|
||||
),
|
||||
],
|
||||
child: MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<AuthenticationCubit>(
|
||||
create: (context) => _authenticationCubit..init(),
|
||||
create: (context) => authenticationCubit..init(),
|
||||
),
|
||||
BlocProvider<SignUpCubit>(
|
||||
create: (context) => _signUpCubit,
|
||||
create: (context) => signUpCubit,
|
||||
),
|
||||
BlocProvider<SignInCubit>(
|
||||
create: (context) => _signInCubit,
|
||||
create: (context) => signInCubit,
|
||||
),
|
||||
],
|
||||
child: const AppView(),
|
||||
|
@ -37,7 +37,7 @@ class _NameInput extends StatelessWidget {
|
||||
labelText: 'name',
|
||||
helperText: '',
|
||||
errorText:
|
||||
state.data.input(formFieldName).invalid ? 'invalid name' : null,
|
||||
state.data.isNotValid(formFieldName) ? 'invalid name' : null,
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -58,7 +58,7 @@ class _PhoneInput extends StatelessWidget {
|
||||
decoration: InputDecoration(
|
||||
labelText: 'phone',
|
||||
helperText: '',
|
||||
errorText: state.data.input(formFieldPhone).invalid
|
||||
errorText: state.data.isNotValid(formFieldPhone)
|
||||
? 'invalid phone'
|
||||
: null,
|
||||
),
|
||||
@ -81,7 +81,7 @@ class _SirenInput extends StatelessWidget {
|
||||
decoration: InputDecoration(
|
||||
labelText: 'siren',
|
||||
helperText: '',
|
||||
errorText: state.data.input(formFieldSiren).invalid
|
||||
errorText: state.data.isNotValid(formFieldSiren)
|
||||
? 'invalid SIREN'
|
||||
: null,
|
||||
),
|
||||
@ -105,7 +105,7 @@ class _IbanInput extends StatelessWidget {
|
||||
labelText: 'iban',
|
||||
helperText: '',
|
||||
errorText:
|
||||
state.data.input(formFieldIban).invalid ? 'invalid IBAN' : null,
|
||||
state.data.isNotValid(formFieldIban) ? 'invalid IBAN' : null,
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -149,8 +149,7 @@ class _PasswordInput extends StatelessWidget {
|
||||
.read<SignUpCubit>()
|
||||
.state
|
||||
.data
|
||||
.input(formFieldConfirmedPassword)
|
||||
.value,
|
||||
.valueOf<String, ValidationError>(formFieldConfirmedPassword),
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -185,7 +184,7 @@ class _ConfirmPasswordInput extends StatelessWidget {
|
||||
decoration: InputDecoration(
|
||||
labelText: 'confirm password',
|
||||
helperText: '',
|
||||
errorText: state.data.input(formFieldConfirmedPassword).invalid
|
||||
errorText: state.data.isNotValid(formFieldConfirmedPassword)
|
||||
? 'passwords do not match'
|
||||
: null,
|
||||
),
|
||||
@ -203,7 +202,7 @@ class _CheckIsProInput extends StatelessWidget {
|
||||
trailing: BlocBuilder<SignUpCubit, SignUpState>(
|
||||
builder: (context, state) {
|
||||
return Checkbox(
|
||||
value: state.data.input<bool>(formFieldPro).value,
|
||||
value: state.data.valueOf<bool, ValidationError>(formFieldPro),
|
||||
onChanged: (isPro) {
|
||||
final value =
|
||||
isPro!; // tristate is false, so value can't be null
|
||||
@ -297,7 +296,7 @@ class SignUpForm extends StatelessWidget {
|
||||
const SizedBox(height: 8),
|
||||
BlocBuilder<SignUpCubit, SignUpState>(
|
||||
builder: (context, state) {
|
||||
if (state.data.input<bool>(formFieldPro).value) {
|
||||
if (state.data.valueOf<bool, ValidationError>(formFieldPro)) {
|
||||
return Column(children: [
|
||||
_SirenInput(),
|
||||
const SizedBox(height: 8),
|
||||
|
@ -33,7 +33,7 @@ class PasswordResetCubit extends Cubit<PasswordResetState> {
|
||||
emit(
|
||||
state.copyWith(
|
||||
email: email,
|
||||
status: FormData.validate([email]),
|
||||
status: FormStatus.validate([email]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class SignInCubit extends Cubit<SignInState> {
|
||||
emit(
|
||||
state.copyWith(
|
||||
email: email,
|
||||
status: FormData.validate([email, state.password]),
|
||||
status: FormStatus.validate([email, state.password]),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -49,7 +49,7 @@ class SignInCubit extends Cubit<SignInState> {
|
||||
emit(
|
||||
state.copyWith(
|
||||
password: password,
|
||||
status: FormData.validate([state.email, password]),
|
||||
status: FormStatus.validate([state.email, password]),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -44,16 +44,16 @@ class SignUpCubit extends Cubit<SignUpState> {
|
||||
void emailChanged(String value) {
|
||||
final Email email = Email.dirty(value);
|
||||
|
||||
final List<FormInput<dynamic, ValidationError>> inputsToValidate = [
|
||||
final List<FormInputValidator<dynamic, ValidationError>> toValidate = [
|
||||
email,
|
||||
state.password,
|
||||
...state.data.inputs<dynamic>(),
|
||||
...state.data.validators<dynamic, ValidationError>(),
|
||||
];
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
email: email,
|
||||
status: FormData.validate(inputsToValidate),
|
||||
status: FormStatus.validate(toValidate),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -61,26 +61,26 @@ class SignUpCubit extends Cubit<SignUpState> {
|
||||
void passwordChanged(String value) {
|
||||
final Password password = Password.dirty(value);
|
||||
|
||||
final List<FormInput<dynamic, ValidationError>> inputsToValidate = [
|
||||
final List<FormInputValidator<dynamic, ValidationError>> toValidate = [
|
||||
state.email,
|
||||
password,
|
||||
...state.data.inputs<dynamic>(),
|
||||
...state.data.validators<dynamic, ValidationError>(),
|
||||
];
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
password: password,
|
||||
status: FormData.validate(inputsToValidate),
|
||||
status: FormStatus.validate(toValidate),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Take from wyatt_form_bloc/wyatt_form_bloc.dart
|
||||
void dataChanged<T>(String field, FormInput dirtyValue) {
|
||||
void dataChanged<T>(String field, FormInputValidator dirtyValue) {
|
||||
final _form = state.data.clone();
|
||||
|
||||
if (_form.contains(field)) {
|
||||
_form.update(field, dirtyValue);
|
||||
_form.updateValidator(field, dirtyValue);
|
||||
} else {
|
||||
throw Exception('Form field $field not found');
|
||||
}
|
||||
@ -88,8 +88,12 @@ class SignUpCubit extends Cubit<SignUpState> {
|
||||
emit(
|
||||
state.copyWith(
|
||||
data: _form,
|
||||
status: FormData.validate(
|
||||
[state.email, state.password, ..._form.inputs<dynamic>()],
|
||||
status: FormStatus.validate(
|
||||
[
|
||||
state.email,
|
||||
state.password,
|
||||
...state.data.validators<dynamic, ValidationError>(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -120,8 +124,12 @@ class SignUpCubit extends Cubit<SignUpState> {
|
||||
emit(
|
||||
state.copyWith(
|
||||
data: _form,
|
||||
status: FormData.validate(
|
||||
[state.email, state.password, ..._form.inputs<dynamic>()],
|
||||
status: FormStatus.validate(
|
||||
[
|
||||
state.email,
|
||||
state.password,
|
||||
...state.data.validators<dynamic, ValidationError>(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -68,9 +68,9 @@ void main() {
|
||||
SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: FormData.empty(),
|
||||
entries: const FormData.empty(),
|
||||
).state,
|
||||
SignUpState(data: FormData.empty()),
|
||||
const SignUpState(data: FormData.empty()),
|
||||
);
|
||||
});
|
||||
|
||||
@ -80,11 +80,11 @@ void main() {
|
||||
build: () => SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: FormData.empty(),
|
||||
entries: const FormData.empty(),
|
||||
),
|
||||
act: (SignUpCubit cubit) => cubit.emailChanged(invalidEmailString),
|
||||
expect: () => <SignUpState>[
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
email: invalidEmail,
|
||||
status: FormStatus.invalid,
|
||||
data: FormData.empty(),
|
||||
@ -97,15 +97,15 @@ void main() {
|
||||
build: () => SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: FormData.empty(),
|
||||
entries: const FormData.empty(),
|
||||
),
|
||||
seed: () => SignUpState(
|
||||
seed: () => const SignUpState(
|
||||
password: validPassword,
|
||||
data: FormData.empty(),
|
||||
),
|
||||
act: (SignUpCubit cubit) => cubit.emailChanged(validEmailString),
|
||||
expect: () => <SignUpState>[
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
email: validEmail,
|
||||
password: validPassword,
|
||||
status: FormStatus.valid,
|
||||
@ -121,12 +121,12 @@ void main() {
|
||||
build: () => SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: FormData.empty(),
|
||||
entries: const FormData.empty(),
|
||||
),
|
||||
act: (SignUpCubit cubit) =>
|
||||
cubit.passwordChanged(invalidPasswordString),
|
||||
expect: () => <SignUpState>[
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
password: invalidPassword,
|
||||
status: FormStatus.invalid,
|
||||
data: FormData.empty(),
|
||||
@ -139,15 +139,15 @@ void main() {
|
||||
build: () => SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: FormData.empty(),
|
||||
entries: const FormData.empty(),
|
||||
),
|
||||
seed: () => SignUpState(
|
||||
seed: () => const SignUpState(
|
||||
email: validEmail,
|
||||
data: FormData.empty(),
|
||||
),
|
||||
act: (SignUpCubit cubit) => cubit.passwordChanged(validPasswordString),
|
||||
expect: () => <SignUpState>[
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
email: validEmail,
|
||||
password: validPassword,
|
||||
status: FormStatus.valid,
|
||||
@ -163,7 +163,7 @@ void main() {
|
||||
build: () => SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: FormData.empty(),
|
||||
entries: const FormData.empty(),
|
||||
),
|
||||
act: (SignUpCubit cubit) => cubit.signUpFormSubmitted(),
|
||||
expect: () => const <SignUpState>[],
|
||||
@ -174,9 +174,9 @@ void main() {
|
||||
build: () => SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: FormData.empty(),
|
||||
entries: const FormData.empty(),
|
||||
),
|
||||
seed: () => SignUpState(
|
||||
seed: () => const SignUpState(
|
||||
status: FormStatus.valid,
|
||||
email: validEmail,
|
||||
password: validPassword,
|
||||
@ -199,9 +199,9 @@ void main() {
|
||||
build: () => SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: FormData.empty(),
|
||||
entries: const FormData.empty(),
|
||||
),
|
||||
seed: () => SignUpState(
|
||||
seed: () => const SignUpState(
|
||||
status: FormStatus.valid,
|
||||
email: validEmail,
|
||||
password: validPassword,
|
||||
@ -209,13 +209,13 @@ void main() {
|
||||
),
|
||||
act: (SignUpCubit cubit) => cubit.signUpFormSubmitted(),
|
||||
expect: () => <SignUpState>[
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
status: FormStatus.submissionInProgress,
|
||||
email: validEmail,
|
||||
password: validPassword,
|
||||
data: FormData.empty(),
|
||||
),
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
status: FormStatus.submissionSuccess,
|
||||
email: validEmail,
|
||||
password: validPassword,
|
||||
@ -238,9 +238,9 @@ void main() {
|
||||
build: () => SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
authenticationCubit: authenticationCubit,
|
||||
entries: FormData.empty(),
|
||||
entries: const FormData.empty(),
|
||||
),
|
||||
seed: () => SignUpState(
|
||||
seed: () => const SignUpState(
|
||||
status: FormStatus.valid,
|
||||
email: validEmail,
|
||||
password: validPassword,
|
||||
@ -248,13 +248,13 @@ void main() {
|
||||
),
|
||||
act: (SignUpCubit cubit) => cubit.signUpFormSubmitted(),
|
||||
expect: () => <SignUpState>[
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
status: FormStatus.submissionInProgress,
|
||||
email: validEmail,
|
||||
password: validPassword,
|
||||
data: FormData.empty(),
|
||||
),
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
status: FormStatus.submissionFailure,
|
||||
email: validEmail,
|
||||
password: validPassword,
|
||||
|
@ -26,10 +26,10 @@ void main() {
|
||||
group('SignUpState', () {
|
||||
test('supports value comparisons', () {
|
||||
expect(
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
data: FormData.empty(),
|
||||
),
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
data: FormData.empty(),
|
||||
),
|
||||
);
|
||||
@ -37,10 +37,10 @@ void main() {
|
||||
|
||||
test('returns same object when no properties are passed', () {
|
||||
expect(
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
data: FormData.empty(),
|
||||
).copyWith(),
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
data: FormData.empty(),
|
||||
),
|
||||
);
|
||||
@ -48,10 +48,10 @@ void main() {
|
||||
|
||||
test('returns object with updated status when status is passed', () {
|
||||
expect(
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
data: FormData.empty(),
|
||||
).copyWith(status: FormStatus.pure),
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
data: FormData.empty(),
|
||||
),
|
||||
);
|
||||
@ -59,10 +59,10 @@ void main() {
|
||||
|
||||
test('returns object with updated email when email is passed', () {
|
||||
expect(
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
data: FormData.empty(),
|
||||
).copyWith(email: email),
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
email: email,
|
||||
data: FormData.empty(),
|
||||
),
|
||||
@ -71,10 +71,10 @@ void main() {
|
||||
|
||||
test('returns object with updated password when password is passed', () {
|
||||
expect(
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
data: FormData.empty(),
|
||||
).copyWith(password: password),
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
password: password,
|
||||
data: FormData.empty(),
|
||||
),
|
||||
@ -85,12 +85,12 @@ void main() {
|
||||
'returns object with updated data'
|
||||
' when data is passed', () {
|
||||
expect(
|
||||
SignUpState(
|
||||
const SignUpState(
|
||||
data: FormData.empty(),
|
||||
).copyWith(
|
||||
data: const FormData(
|
||||
[
|
||||
FormEntry(
|
||||
FormInput(
|
||||
'field',
|
||||
Name.pure(),
|
||||
),
|
||||
@ -100,7 +100,7 @@ void main() {
|
||||
const SignUpState(
|
||||
data: FormData(
|
||||
[
|
||||
FormEntry(
|
||||
FormInput(
|
||||
'field',
|
||||
Name.pure(),
|
||||
),
|
||||
|
@ -18,8 +18,13 @@ part of 'form_data_cubit.dart';
|
||||
|
||||
@immutable
|
||||
class FormDataState extends Equatable {
|
||||
/// Global status of a form.
|
||||
final FormStatus status;
|
||||
|
||||
/// FormData with all inputs, and associated metadata.
|
||||
final FormData data;
|
||||
|
||||
/// Optional error message.
|
||||
final String? errorMessage;
|
||||
|
||||
const FormDataState({
|
||||
|
@ -76,11 +76,21 @@ enum FormStatus {
|
||||
/// Indicates whether the form submission has been canceled.
|
||||
bool get isSubmissionCanceled => this == FormStatus.submissionCanceled;
|
||||
|
||||
/// Validate a list of inputs
|
||||
static FormStatus validate(List<FormInput> inputs) {
|
||||
return inputs.every((FormInput input) => input.validator.pure)
|
||||
/// Validate a list of inputs by processing them in `validate` as validators.
|
||||
static FormStatus validateInputs(List<FormInput> inputs) {
|
||||
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
|
||||
: inputs.any((FormInput input) => input.validator.valid == false)
|
||||
: validators
|
||||
.any((FormInputValidator validator) => validator.valid == false)
|
||||
? FormStatus.invalid
|
||||
: FormStatus.valid;
|
||||
}
|
||||
|
@ -23,8 +23,11 @@ class FormData extends Equatable {
|
||||
const FormData(this._inputs);
|
||||
const FormData.empty() : this(const <FormInput>[]);
|
||||
|
||||
/// Returns all inputs as a list
|
||||
List<FormInput> inputs() => _inputs;
|
||||
|
||||
/// Returns the input for the associated key
|
||||
FormInput inputByKey(String key) {
|
||||
FormInput inputOf(String key) {
|
||||
if (contains(key)) {
|
||||
return _inputs.firstWhere((FormInput input) => input.key == key);
|
||||
} else {
|
||||
@ -36,65 +39,83 @@ class FormData extends Equatable {
|
||||
void updateInput(String key, FormInput input) {
|
||||
if (contains(key)) {
|
||||
final index = _inputs.indexOf(
|
||||
inputByKey(key),
|
||||
inputOf(key),
|
||||
);
|
||||
_inputs[index] = input;
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates validator of a given input. (perform copyWith)
|
||||
void updateValidator(String key, FormInputValidator dirtyValue) {
|
||||
if (contains(key)) {
|
||||
final index = _inputs.indexOf(
|
||||
inputByKey(key),
|
||||
);
|
||||
_inputs[index] = _inputs[index].copyWith(validator: dirtyValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// 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);
|
||||
}
|
||||
/// Returns all associated validators as a list
|
||||
List<FormInputValidator<V, E>> validators<V, E>() {
|
||||
return _inputs
|
||||
.map<FormInputValidator<V, E>>(
|
||||
(FormInput input) => input.validator as FormInputValidator<V, E>,
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// A [FormInputValidator] represents the value of a single form input field.
|
||||
/// It contains information about the [FormInputStatus], value, as well
|
||||
/// as validation status.
|
||||
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 null if the [FormInputValidator] is valid.
|
||||
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,
|
||||
/// if you have a FormInputValidator for FirstName, the value could be 'Joe'.
|
||||
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.
|
||||
/// Same as `E? errorOf<V, E>(String key) != null`
|
||||
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.
|
||||
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.
|
||||
FormStatus validate() {
|
||||
return FormStatus.validate(_inputs);
|
||||
return FormStatus.validateInputs(_inputs);
|
||||
}
|
||||
|
||||
/// Check if this contains an input with the given key.
|
||||
|
Loading…
x
Reference in New Issue
Block a user