On button click I am showing a dialog which have input field. I want to autofocus in that input field. I'm using Material UI Component Dialog & OutlinedInput
const SearchIdDialog: React.FC = () => {
const [openSearchId, setOpenSearchId] = React.useState<boolean>(false);
React.useEffect(()=> {
inputRef.current?.focus();
}, [openSearchId]);
const handleClose = () => {
setOpenSearchId(false);
};
const inputRef = React.useRef<HTMLInputElement>(null);
return (
<div>
<Tooltip title="Click to search">
<Button
onClick={() => {
setOpenSearchId(true);
}}
>
Search
</Button>
</Tooltip>
<BootstrapDialog
onClose={handleClose}
open={openSearchId}
>
<SearchStyle
inputRef={inputRef}
/>
</BootstrapDialog>
</div>
);
};
I have tried autoFocus prop but its failing. How to wait for input field to render input field first and then focusing it ?
Note: inputRef is used instead of ref because its a mui component which need inputRef. If I use setTimeOut in useEffect and waits for 1 sec and then focus - it works. But I want it naturally.
Sandbox link- https://codesandbox.io/s/react-typescript-forked-f6hg5y?file=/src/SearchIdDialog.tsx
CodePudding user response:
Since autofocus
is not working, then you can try with setTimeout
.
What I did was to check if openSearchId
is true
Demo
React.useEffect(() => {
if (openSearchId) {
setTimeout(() => {
inputRef.current?.focus();
console.log("focused");
}, 300);
}
}, [openSearchId]);
Does this work for you? You can change the millis of course.
CodePudding user response:
To autofocus on textfield whenever dialog box opens, you can use autoFocus
props. It is working. Demo
CodePudding user response:
First do this:
It calls the focus method after the input element is rendered.
React.useEffect(() => {
inputRef.current?.focus();
}, [inputRef.current]);
If it did not work, try using setInterval
or setTimeout
.
React.useEffect(()=> {
const {current} = inputRef
const interval = setInterval(() => {
if (current != document.activeElement) {
current.focus()
} else {
clearInterval(interval)
}
}, 3000)
return () => clearInterval(interval)
}, [openSearchId]);
React.useEffect(()=> {
const {current} = inputRef
const timeout = setTimeout(() => {
if (current != document.activeElement) {
current.focus()
} else {
clearTimeout(timeout)
}
}, 3000)
return () => clearTimeout(interval)
}, [openSearchId]);
You probably need to restrict the number of times setInterval is called.
Javascript how to clear interval after specific time
CodePudding user response:
Try to wrap your BootstrapDialog componnet in conditional rendering. Something like:
{openSearchId &&
<BootstrapDialog
onClose={handleClose}
open={openSearchId}
>
<SearchStyle
inputRef={inputRef}
/>
</BootstrapDialog>
}
Like this autofocus will be triggered right when you open your dialog.