Reputation: 7575
In my ReactJS project, I'm using <Dialog>
(http://www.material-ui.com/#/components/dialog), and when I open up the <Dialog>
and press command + a on Mac, it highlights the whole page rather than just the content in the <Dialog>
.
How can I highlight just the content inside <Dialog>
while the <Dialog>
is open by pressing command + a on Mac?
Thank you in advance and will accept/upvote the answer.
Upvotes: 1
Views: 2306
Reputation: 5927
Yes, this can be done. You'll need to listen for Command-A (or Ctrl-A on Windows) on window.document
in componentDidMount()
and perform the text selection programmatically. For cleanup, you un-listen in componentWillUnmount()
.
Working example here: http://www.webpackbin.com/41BuFVuBz
import React from 'react';
import { Dialog } from 'material-ui';
class HelloWorld extends React.Component {
constructor(props) {
super(props);
// In ES6 classes, class methods like handleKeyDown aren't automatically bound to "this"
this.handleKeyDown = this.handleKeyDown.bind(this);
}
handleKeyDown(e) {
// If the A key is pressed while CTRL or COMMAND are also being pressed
if (e.key === 'a' && (e.ctrlKey || e.metaKey)) {
// Don't perform the default action, which would select everything on page
e.preventDefault();
const win = window;
const doc = win.document;
// this.dialogBody is the div's DOM element captured in the ref={}
const element = this.dialogBody;
if (doc.body.createTextRange) { // check if this is Internet Explorer
// Select all text in "element", the IE way
var range = doc.body.createTextRange();
range.moveToElementText(element);
range.select();
} else if (win.getSelection) { // other browsers...
// Select all text in "element", the standard way
var selection = win.getSelection();
var range = doc.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
}
}
componentDidMount() {
// Element has been rendered, start capturing keyboard activity
window.document.addEventListener('keydown', this.handleKeyDown);
}
componnetWillUnmount() {
// Element is no longer been rendered, stop listening
window.document.removeEventListener('keydown', this.handleKeyDown);
}
render() {
return (
<div>
<p>
Some text I don't want selected.
</p>
<p>
More text I don't want selected.
</p>
<Dialog open>
// Capture a reference to the div's DOM element inside ref={...} as this.dialogBody
<div ref={(ref) => (this.dialogBody = ref)}>
<h1>Hello World!</h1>
<p>Nice day, isn't it?</p>
</div>
</Dialog>
</div>
);
}
}
export default HelloWorld;
The code that actually performs the selection of text confined to a DOM element can be seen in slight variations in other answers on SO:
Select all DIV text with single mouse click
selecting all text within a div on a single left click with javascript
Select all or highlight all Text in an Element
...the only additional 'trick' is knowing where to put DOM manipulation code like this within the React component lifecycle (primarily componentDidMount
, usually with the help of a ref
, and sometimes cleanup is necessary in componentWillUnmount
)
Upvotes: 2