I'd like to get a TextField to select the whole text currently in the field whenever I click/tap/focus on the field. The following code works in Chrome (71.0.3578.98), but not in Safari (12.0.2). Any ideas why?
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
return (
<>
<h1>Test Focus React</h1>
<input
type="text"
defaultValue="test"
onFocus={event => {
event.target.select();
}}
/>
</>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
And yet this static HTML file without any React works fine on Safari.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Test Focus JS</title>
</head>
<body>
<h1>Test Focus JS</h1>
<input type="text" value="test" onClick="this.select();" />
</body>
</html>
Can anyone help me see how to get the selection to work on Safari with React?
When things like interacting with the DOM fail, it usually is related to how events fire synchronously / asynchronously in different contexts (react vs onclick), and browsers even (with Safari having weird optimisations sometimes).
I'm guessing it'll just work by making it async, like:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
return (
<>
<h1>Test Focus React</h1>
<input
type="text"
defaultValue="test"
onFocus={event => {
// event properties must be copied to use async
const target = event.target;
setTimeout(() => target.select(), 0);
}}
/>
</>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
This is well known issue, you can work around this basically using set timeout
onFocus={event => {
setTimeout(event.target.select.bind(event.target), 20);
}}
Here is working example. I tested on safari worked without any issue.
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