Yerlan Yeszhanov
Yerlan Yeszhanov

Reputation: 2449

close modal when click outside?

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?

enter image description here

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

Answers (3)

gazdagergo
gazdagergo

Reputation: 6731

Use onBlur event to handle clickoutside. Please, have a look on this answer with working example.

Upvotes: 0

samb102
samb102

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

Shubham Khatri
Shubham Khatri

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

Related Questions