form_bloc
form_bloc copied to clipboard
Turn on autovalidation after submit
I would like to turn on autovalidation after a submit. I also would like to validate the fields when they loose focus.
How can I accomplish this?
I will add a method to enable / disable auto validation in a few days :)
Respect validate when loose focus, I am not sure how it would be, I will try this in a few days and if it works I will add a property that allows to choose which type of validation must have the text field,
- onLossFocus
- onChanges
- other? this is only for text field? If you know any solution it would be good to tell me, I know that this will have its complications on mobile because the focus is not lost automatically when you click outside the fields, unlike flutter web.
__
P.D.
Respect to turn on auto validation
this mean that you set autoValidete
to false in the super constructor, and the use enable auto validation ?
MyFormBloc() : super(autoValidate: false) {
...
}
void onSubmitting(){
enableAutoValidation(); // do you want this method?
}
I can submit a patch, here's what I was thinking:
RaisedButton(
onPressed: () {
loginFormBloc.autoValidate = true;
loginFormBloc.submit();
},
child: Text('LOGIN'),
),
The class FormBloc
would have something like:
bool get autoValidate => _autoValidate;
set autoValidate(bool value) {
_autoValidate = value ?? false;
_setAutoValidateForFields(_allFieldBlocsUsed);
}
where _setAutoValidateForFields()
is
void _setAutoValidateForFields(Iterable<FieldBloc> fieldBlocs) {
FormBlocUtils.getAllFieldBlocs(fieldBlocs).forEach((e) {
if (e is SingleFieldBloc) {
e.add(
AddFormBlocAndAutoValidateToFieldBloc(
formBloc: this, autoValidate: _autoValidate),
);
} else if (e is ListFieldBloc) {
e.add(
AddFormBlocAndAutoValidateToListFieldBloc(
formBloc: this, autoValidate: _autoValidate),
);
} else if (e is GroupFieldBloc) {
e.add(
AddFormBlocAndAutoValidateToGroupFieldBloc(
formBloc: this, autoValidate: _autoValidate),
);
}
});
}
and _onAddFieldBloc()
calls _setAutoValidateForFields()
as well.
Yes, more or less that's the idea,
But it would be creating events for the form bloc and the public methods for this events
EnableAutoValidation()
DisableAutoValidation()
and process them on the mapEventToState
There you can call _setAutoValidateForFields
In this way the pattern is followed and we have a record of these events in the bloc delegate
I'm not sure with the names, I always have doubts about that haha
Gotcha.
re: unfocus, in the login form,
_emailFocusNode = FocusNode()
..addListener(() {
if (!_emailFocusNode.hasFocus) {
setState(() {
bloc.add(
AutoValidateFieldBloc(formBloc: bloc.email, autoValidate: true));
});
}
});
Autovalidation true/false
This a good approach that validators are executed on each field change. This allows to track the form consistency at every moment. But the error display logic is not adjustable(correct if I'm wrong)
If I have an autovalidate: true
and email field(Simple example
from https://giancarlocode.github.io/). Just after I enter the first symbol the form notifies me that the field is badly formatted. But I'm not done with input yet :-) How the form knows that I'm wrong?) The other case is autovalidate: false
- I do not see the errors until I press 'Submit' this is a little bit annoying(from users perspective). It could lead the case that user fills long form and sees the errors far later.
This could be improved with two things - introducing the field meta data, and display error hook(callback).
Example from react-final-form
(pretty proven solution)
isErrorField = (meta: Meta): boolean =>
!!(meta && ((meta.error && meta.touched) || (meta.submitError && meta.submitFailed)));
This function checks if field has errors, if it was touched before or has submit errors and submit was failed. Returns the true/false
and this is a sign whether to display an error.
Here is a link to full list of meta
data of the field
https://github.com/final-form/react-final-form/blob/master/src/types.js.flow#L32
How this will help.
If user hits the field for the first time the meta.touched
is false
.
So we do not disturb the user during possible errors while he entering value for the first time.
After he switches to another field meta.touched
becomes true
and only than we can show an error.
If user gets back to the editing the meta.touched
already true
and now we show the realtime error display based on the assumption that the previous value was correct and if user alters it we notify him immediately that there is an error.
The default error display logic could stay the same. But with this extended meta data and error display hook everyone can alter the logic on his own demands.
Any update on this? I'm also interested in disabling autovalidation until, for example, the user submits the form with some errors. I've tried to handle this use case, but I'm not sure this is the correct/best way to implement it
// MyFormBloc
@override
void onChange(Change<FormBlocState<String, String>> change) {
super.onChange(change);
// catch state change as with FormBlocListener.onSubmissionFailed
if (change.nextState is FormBlocSubmissionFailed) {
// iterate over all form fields (don't know a better way)...
mySingleFieldBloc1.add(AddFormBlocAndAutoValidateToFieldBloc(
formBloc: this,
autoValidate: true,
));
mySingleFieldBloc2.add(AddFormBlocAndAutoValidateToFieldBloc(
formBloc: this,
autoValidate: true,
));
...
}
}
My proposal: #331