formsy / formsy-material-ui

A Formsy compatibility wrapper for Material-UI form components
MIT License
571 stars 149 forks source link

[FormsyText] Validating onBlur doesn't enable the submit button if this is the last field before submit. #6

Closed sys13 closed 8 years ago

sys13 commented 8 years ago

If a user fills out a textfield as the last required input, with onBlur the submit button isn't enabled unless the user clicks away from the field. With onChange this problem would likely be resolved.

WIth onChange we can also validate urls in real-time without waiting until they click away, forcing them to re-click on the field.

I can see why with URLs you might want to wait until they have finished typing so we don't pre-maturely show an error but having to re-click on the field is even more frustrating (from my point-of view).

mbrookes commented 8 years ago

Hmm... validation was originally onChange, but this meant you would get validation errors while typing (particularly annoying for URLs, email address or other regex style validations), so changed to onBlur, but hadn't considered what would happen if the textfield was the last field.

I can see three possible solutions (without considering implementation details for the first two):

Allow the user to hit enter to trigger validation (not great for mobile, and lacks discoverability / poor UX), revert to onChange and add a delay to the validation until after the user stops typing, revert to onChange and live with the validation noise.

None is perfect, so I'm open to other suggestions.

sys13 commented 8 years ago

I don't like the hitting enter idea. Adding a delay might work with a throttled version of the function (maybe using http://underscorejs.org/#throttle). onChange would be the simplest. I've seen this behaviour on other websites and the noise kind of acts like hint text.

mbrookes commented 8 years ago

I think it would be debounce rather than throttle, but I'm not keen on pulling in all of underscore just for one function, so would probably implement natively (or copy in the relevant code).

dmlinn commented 8 years ago

A simple fix might be to default inputs to validate onChange (particularly for fields that are required but have no other validation), and set some sort of prop to validate onBlur if needed (for fields like email). I do appreciate the onBlur functionality, as I was duplicating FormsyText and adding it myself before the update.

Another more complex fix might be to implement a showErrorOn prop or something of the like that could be set to blur or change. This way the overall validation of the form will always be set on change, but the display of individual input errors can be manipulated.

Hoping I can get some time to contribute. My current workaround, FWIW:

_handleOnChange(e) { let thisInput = this.refs[ e.currentTarget.name ]; thisInput.setValue(e.currentTarget.value); }

mbrookes commented 8 years ago

A prop to make the validation event configurable for either onChange or onBlur makes certain sense, that way whitelist type validations (such as isWords, isNumeric) can complain as soon as an illegal character is typed, but pattern-matching validations such as isUrl can be configured to only fire on onBlur.

However, the problem of an onBlur input in the last field not enabling a submit button remains.

For the second option, my understanding is that the validation is run on setValue, which validates both the input and the form as a whole, so not sure how you would separate the two validations to check the form onChange, but only check the field onBlur.

Also, there would be no validation message on the last field if invalid and updating onBlur...

vijayrawatsan commented 8 years ago

Not entirely related but this might help... https://github.com/christianalfoni/formsy-react/issues/180

mbrookes commented 8 years ago

Thank, yes, I had seen that. I believe a choice of validation events is the best compromise (a validateOnChange property perhaps?)

This is assuming that validating the last field onBlur, and having the submit button disabled depending on validation is mutually exclusive (unless I'm missing some other capability of Formsy).

I hope to have some time to revisit this in the next week or two. PRs always welcome in the meantime! :)