I have a modal that has 3 components. Each component represents a stage, so for example the first component is inputing the user's first name when the user click next, and it will go to the next component, which is inputing address and then user clicks next and it will take the user to the last stage, inputing a nickname. On every input
element from the components, it will have an autoFocus
. So far in the last two components, the inputs
have an autoFocus except for the first component.
Not sure why the first doesn't have it, when I initialise the modal I see the input
doesn't have the autoFocus
, then I hit next then the second component input
has it and I go back to the first component - hit the back button - then I see the input
from the first component has an autoFocus
. Very strange, I've been trying so many way to resolve this, from setting autoFocus={false}
to the modal, creating a ref
for the first input but still not working.
It looks like it's an issue with the modal, where it's initialized the focus is somewhere but not on the input
. Has anyone encountered this issue?
Example (pseudo) code
//Component Hosting the modal
render(){
if(this.state.modal_stage === 1){
<FirstName />
}else if(this.state.modal_stage === 2){
<LasgtName />
}else if(this.state.modal_stage === 3){
<NickName />
}
return(
<Modal
dialogClassName="locationModal customModal"
show={this.state.modalShow} onHide={this.hideModal}
autoFocus="false">
<Modal.Header>
<div className="closeModal" onClick={this.hideModal}></div>
</Modal.Header>
<Modal.Body>
{ current_stage}
</Modal.Body>
<Modal.Footer>
{backButton}
{nextButton}
</Modal.Footer>
</Modal>
);
}
//<FirstName /> component
constructor(props){
super(props)
this.inputRef = React.createRef();
}
componentDidMount(){
this.inputRef.current.focus();
}
....
render(){
return(
<div>
<input type="text" placeholder="firstName" ref={this.inputRef}/>
</div>
);
}
Your help will be appreciated!!
Note:
I tried to set this autoFocus="false"
to autoFocus={false}
in the modal but the issue still remains.
Just add autoFocus = {false} on modal and autoFocus = {true} on input.
You can prevent closing of modal dialog by setting the beforeClose event argument cancel value to true.
Add The State and MethodsAdd a button inside the render block to trigger the modal. When the button is clicked, the isOpen state will be set to true. Now, to display the modal, all you need to do is pass the isOpen state value to the show prop of the <Modal /> component.
Autofocus can make your app more convenient for users. For example, instead of clicking into a field before typing, they can immediately start typing as soon as a form loads.
Here is a similar solution as the one from @dev_junwen using a functional component and hooks. Also no need for a timeout.
import React, { useEffect, useRef } from 'react';
const FirstInput = ({ item, save }) => {
const innerRef = useRef();
useEffect(() => innerRef.current && innerRef.current.focus());
return <input ref={innerRef} />;
};
Found out a solution that will fix your problem. You can add a little timeout for your component to focus on your input. This should fix your issue.
class FirstInput extends React.Component {
constructor(props) {
super(props);
this.innerRef = React.createRef();
}
componentDidMount() {
// Add a timeout here
setTimeout(() => {
this.innerRef.current.focus();
}, 1)
}
render() {
return <input ref={this.innerRef} />;
}
}
This is a working example: https://codesandbox.io/s/react-bootstrap-autofocus-efkve?fontsize=14
Apparently there is a bug with react-bootstrap that doesn't allow autoFocus
on a Modal component. The workaround while this bug is fixed is disabling animations on the Modal component.
<Modal animation={false}>
<Form.Control autoFocus />
</Modal>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With