redux-form: Set focus in first faulty field
Hi,
is there a way to always set the focus to the first faulty field?
I tried to implement a solution in my render field component:
componentDidUpdate() {
const { meta: { submitting, touched, error } } = this.props;
const field = this.refs['field' + this.props.name];
...
if (!submitting && touched && error) {
field.select();
}
}
This works partially, but…
If I enter one char in the first faulty field, the validation is at this moment valid for the field and the next faulty field steals my focus.
How can I prevent this or is there already a built-in solution?
Thanks for your help!
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 1
- Comments: 16 (5 by maintainers)
All suggestions (in all corresponding/found issues) for implementing focusing the first field error were failing for me… then I worked out why… when using
redux-form/immutabletheonSubmitFailerrorsobject does not contain the fields in registration order (possibly requires an ordered list reviver when setting/getting fields?).Also most do numerous DOM queries (query per field). So I solved it with one single DOM query:
In
onSubmitFailGet all the error’ed fields and query them usingquerySelector. This is the most workable/optimal asquerySelector“Returns the first Element within the document that matches the specified selector, or group of selectors.” … so even if the selector is not in field order… it still returns the first error’ed field in the document, then justfocus()it.Could possibly also
scrollIntoView()though in my case this failed as the site has a fixed/floating header.Example
Notes
flattenObjectactually creates correct field names#1336 #488
I just recently started using
redux-forms. I am working on an existing project that is using version 6.8.0. (Based on the implementation and the v7 docs, I think it will work in v7 too.)This solution uses 2 utility functions and the
onSubmitFailcallback.There are two main steps that need to be done for each form:
nameattribute to theformelement (just reuse the unique one you give toreduxForm)onSubmitFailcallback as illustrated above.This solution solves all the issues I believe have been plaguing everyone.
redux-form.Notes:
redux-forms(but I am pretty sure it should work).focusFirstInvalidControlcan be used in any HTML document regardless of it being generated by React.Please let me know if these utilities already exist in an npm package somewhere. If not and you have a cleaner implementation (maybe one that doesn’t use recursion), then please let me know.
Edit: I whipped up an npm package that will set focus on the first invalid control. See qc-dom_utils. You can use the following in place of the
FormUtils.jsmodule above.Edit: I searched in npm and I searched the redux-form code base, but I didn’t find anything to flatten the errors. So, I created the qc-redux-form_utils package.
Thanks for the details, @AubreyHewes!
Since this issue is very UI specific, it’s not a concern of Redux Form, therefore I’m closing it. Feel free to continue the discussion, though.
I’ve been working on this today and found a solution which I think is a bit more elegant than using
document.querySelectorAll, and (with limited testing) seems to work well. In theonSubmitFailmethod I dispatch thefocusaction so theactiveprop of the first failing field is set:Then in the component I pass to
Field, I set the focus on the<input>tag incomponentDidUpdatevia a ref:If that looks useful and works for other folks then I can put in a PR with some documentation on how to do this.