I have a sign in form that when given incorrect credentials an error message pops up. I want this error message to be focused when loaded, that way the user can easily hear the message and then tab down to the fields. I am having trouble identifying the best solution to implement.
aria-live works perfectly in reading the error, but I would like if the error message also focused. What is best practice to read and focus the error message? Would it be to add a ref?
I'm not sure why you'd like to focus the error message since it's read out loud, it should be enough. Also it might be confusing to force focus, maybe the user is in the middle of something else - which is the benefit of using an aria-live "polite" value for instance. Additionally using both aria-live & auto focus may result in reading the error message twice, but this needs to be tested.
This being said, to focus a DOM element you need to use a ref. Create it with useRef and assign it to the element. If the element to focus is rather a React component, you might need forwardRef. If the element is non-focusable (like a div, a span or a paragraph) you will have to add a tabIndex={-1}. Call ref.current.focus() when you need to.
Using a negative value for tabIndex will make them temporarily focusable & will not break the natural focus order of the page.
Sources :
https://developer.mozilla.org/fr/docs/Web/HTML/Global_attributes/tabindex
https://reactjs.org/docs/hooks-reference.html#useref
https://reactjs.org/docs/react-api.html#reactforwardref
Related
I have implemented code in focusGained that in some cases may cause the component (a container I have set to be focusable) which just received that focus to be removed from the screen, and replaced in the container by another component. This will also cause a redraw of the screen to show the changed component.
This does work but I have a bit of a problem, in that the next component in the container also gains focus and so my code removes/replaces it also. I assume this is because on the redraw, that component now occupies the same space where the tap originally occurred.
If the last component in the container was originally selected, then the replacement component is itself given focus and so it is removed and replaced.
Any ideas on what I may have miscoded or anything I can do to avoid the second focusGained call?
I doubt you did something wrong. If we remove the component with the focus we'll find the next available one. The replace method doesn't take focus into consideration but can't grant focus to a component that isn't physically here yet so it's granted to the next component. Not much to do here.
You can requstFocus() after the transition completes to fix the order manually.
I used react-infinite-scroll-component it's working just fine.
However, I want to avoid making the user lose his scroll position when he leaves the page and clicks back?
Also please put on consideration Firefox and Safari.
Not 100% sure because I haven't used it - but since no one else has chimed in... the docs say the component has a prop named key that is described as:
the key for the current data set being shown, used when the same
component can show different data sets at different times,
default=undefined
Also, it has a prop named onScroll that is described as:
a function that will listen to the scroll event on the scrolling
container. Note that the scroll event is throttled, so you may not
receive as many events as you would expect.
... which I suspect one of the arguments of which will tell you which keys it loaded / scrolled through.
So my approach would be to use componentWillUnmount to save the last key it loaded into a parent property (or Redux store if you're using Redux)... and when the component loads, if the key exists in the parent (or Redux store if you're using Redux) then pass it that key.
I've got a long standing bit of JS which I use to turn an input into a Numeric. This code works perfectly outside of ReactJS.
The code plugs into Key, Down, Up, Press events e.t.c. blocks alphas and applies min, max and precision on blur.
When I apply the same code to an input generated by ReactJS the delete and backspace keys change their behaviour.
When they're pressed, the value in the input will revert to whatever the value was when the input gained focus.
It's driving me crazy... any thoughts?
Right, I've found a solution. It was to implement and re-affirm the desired state during the onInput event via the setState method.
If you use JS to attach events via the a React Ref. When that event finishes bubbling React will catch that at a higher document level and reapply the state.
I guess the lesson here is don't be lazy. Integrate your components properly into a framework.
I have React component which has an input element that is a child property of a GridItem component from https://github.com/STRML/react-grid-layout/blob/master/lib/GridItem.jsx
When I click into the input element for some reason the insertion point is not showing and I can't make any edits. I think the click is propagating through to the GridItem. I've tried to stop propagation but the issue remains.
Currently doing this
e.target.focus()
alert('Hello')
which works, the insertion point is correct and I can do edits,
whereas
e.target.focus()
fails, the insertion point is not shown and I'm unable to do edits.
My colleague suggested using jQuery but I'd like to avoid that.
How can you force focus to a React object after clicking on that object?
I could have been in a search for this. Once the form is submitted , if the errors are available it shows on top as the validation summary (May be it will be done). Here is the critical. When i click on the error message, the focus should go to the corresponding error field. The field may be in the same tab or other tabs or other panels etc
Could it be possible to achieve?
A simple way to achieve that would be to make the error message a label for that particular field:
<label for="myField">some error</label>
&
<input id="myField">
Clicking on the message would then automatically focus the field, no matter how far in the DOM the two elements are from each other.
An input can also be focused by JavaScript (see .focus() documentation). In both cases, the input needs to actually be present in the DOM before it can be focused.