Closed nuschk closed 7 years ago
You can actually do that. You can change the validateOnChange
Form Option and then implement a new onBlur
Event Handler, you can follow this Blog Post to know how to do that using Field Props Bindings
Make sense?
@foxhound87 might be a good idea to make FAQ more prominent in documentation This has already been answered but discoverability of the answer is pretty low.
Maybe change the name from FAQ to "Common solutions" or something similar and link it in few more places so it's more visible? :)
Thanks for the pointer. It might be even easier than to disable validateOnChange
and fiddle with binding (unless I'm missing something). Can't we something like this:
import { observable, computed, action } from 'mobx';
import { Form, Field } from 'mobx-react-form';
class BlurAwareField extends Field {
@observable $edited = false;
@computed get edited() {
return this.hasNestedFields
? this.check('edited', true)
: this.$edited;
}
onBlur = action(() => {
this.$focus = false;
this.$edited = true;
});
}
export default class BlurAwareForm extends Form {
makeField(data) {
return new BlurAwareField(data);
}
}
@d4rky-pl Will be done, thanks.
@nuschk If you want to do that without reimplementing the onBlur
handler you can use the observers: check the mobx change.newValue
and validate if focus
is changed to false
. I don't see the need to add a new edited
prop. Maybe I'm missing something?
This sounds closely tied to #237. I'd argue that if we had a solution to #237 then not having a built in way to validate on blur wouldn't be a big deal. In both cases, I think what's trying to be avoided is nagging the user with an error message when they haven't even finished typing yet, and if I had to choose a behavior between the two approaches, I'd much prefer some kind of throttled/timeout mechanism as suggested in #237 .
Ah, yes, #237 is really very related. Sorry, I missed that.
Just to clarify, I don't want to validate on blur (I don't car about validation, actually), I just would like to withhold error display until first blur. After first blur, I want to display errors instantaneously.
I need to store that information ("was blurred once") somewhere. @foxhound87 , you're right, I could just as well use an observer in my field renderers for this, though it will introduce local state in the react component, which feels strange. So, I would welcome having this on the field state.
From the UX perspective, I clearly prefer instantaneous feedback to the user on blur. Also, if there is an error on a field and the user corrects the data, the error message should go away immediately.
IMHO, debounced delayed validation feels awkward to the user. I've tried it, and you'd have to set the delay quite high (not everyone types as fast as we nerds). But then sometimes when you tab or click to the next field, you already start typing before the error in the old one shows up. So, you'd still need to insta-validate on blur, and, even more important, insta-validate when the user corrects his error.
A final thought: As you know, redux-forms is probably one of the most widely used form libraries for react. An they chose to set touched
on blur (well, actually, it's configurable: http://redux-form.com/6.6.1/docs/api/ReduxForm.md/, but that's the default) precisely to control error rendering. I think that's certainly a battle tested solution. Plus, as more and more people convert their redux apps to mobx, you'll likely get many converts such as myself, so it would be a plus to have similar concepts. 😉
I'll close this issue and move over to #237 .
@nuschk the touched
prop in mobx-react-form is already true
on onFocus
, then your previous suggestion with the edited
prop is the only way, this is different from the redux-forms (which I don't like because don't feel right to have touchOnBlur
, it should be touched when you actually interact with the input).
@foxhound87 I agree with naming that prop touched
is misleading. I find your definition much less confusing. edited
is not really better, though, so I'm still looking for a better name... 😄
@nuschk something like interacted
? or can be confused with touched
?
interacted
is certainly better than edited
. Yeah, it's not crystal clear either, but, well, naming is hard.
You could also name it by its purpose and thus showError
and put it next to hasError
. This way, of course, it could only ever be true if the field has errors.
It was hard to come up with a good title for this, sorry.
I'm essentially interested in a feature of redux-form that let's us not show an error on a field unless the field received a blur event or the user submitted the form. This leads to less noise when filling out an empty form, as the user can enter data without being nagged by error displays while typing.
Main use case: Entering e.g. an email-address (or phone numbers or addresses). With mobx-forms, as soon as the users starts to type, the field is
touched
and has errors and we hence display those errors.With redux-forms, however,
touched
is only set after the field receives a blur event or the form is submitted (the field is validated in any case, though). This allows us to only show the error after the user is done with the field.There's a
visited
flag that is similar to mobx-form'stouched
.Here's a demo that shows the behavior (the redux devtools chrome extension is handy here, as it can display the whole state):
http://redux-form.com/6.6.0/examples/syncValidation/
Just start typing in the email field and compare it to how mobx-forms handles this use case.
Empty form:
Starting to type (no error is shown, although there is one in the state):
(note that there is an error, but no
touched
)Pressing moves to the next field and shows the error:
To close, I'm also fine with having to implement this stuff on my side, I'm just very unsure of how to best do that. Any pointers appreciated!