Reputation: 2449
I have a modal box which has a couple buttons inside. On click outside I want that modal close. I've added ref to the parent element and it's works fine, everything closing when you click outside. But if you click on that buttons inside this modal box , it closes too. How to detect child elements inside this ref and do not allow close modal box?
public handleClickoutside() {
this.props.showMessage()
}
public handleClick = (e) => {
if (this.DOMArrowBox.current !== e.target) {
this.handleClickoutside()
}
}
public componentWillMount() {
document.addEventListener("mousedown", this.handleClick, false)
}
public componentWillUnmount() {
document.removeEventListener("mousedown", this.handleClick, false)
}
<div className={this.props.className} ref={this.DOMArrowBox}>
<Social />
<CallMe className="arrow__box-button" open={this.props.open} />
<Close
className="arrow-button_close"
onClick={this.props.showMessage}
/>
</div>
Upvotes: 1
Views: 494
Reputation: 6731
Use onBlur
event to handle clickoutside. Please, have a look on this answer with working example.
Upvotes: 0
Reputation: 1114
I think the best way to resolve this, is to revert the issue : let's imagine that you're not catching the click outside your modal, but the click on the modal background wrapper.
You should wrap your <Modal>
into a invisible <Wrapper>
, with a lesser z-index than the modal, and with the following styles, to take the parent element/window full width & height :
.modal-wrapper {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1; // has to be < of Modal's z-index
width: 100%; // or 100vw
height: 100%; // or 100vh
}
Then, attach the ref
on the <Wrapper>
and in your handleClick
method, replace !==
by ===
(because, remember, we reverted the problem).
Hope this help.
Upvotes: 1
Reputation: 282080
You can add a ref on the Button inside modal too and check if the target element is contained within that or not
public handleClickoutside() {
this.props.showMessage()
}
public handleClick = (e) => {
if (!this.DOMArrowBox.current.contains(e.target) && !ReactDOM.findDOMNode(this.btnRef.current).contains(e.target)) {
this.handleClickoutside()
}
}
public componentWillMount() {
document.addEventListener("mousedown", this.handleClick, false)
}
public componentWillUnmount() {
document.removeEventListener("mousedown", this.handleClick, false)
}
<div className={this.props.className} ref={this.DOMArrowBox}>
<Social />
<CallMe className="arrow__box-button" ref={this.btnRef}open={this.props.open} />
<Close
className="arrow-button_close"
onClick={this.props.showMessage}
/>
</div>
Upvotes: 1