Search code examples
javascriptreactjsmodal-dialogreact-bootstrap

React react-bootstrap - How do I close a modal window from an outside component


I am using versions:

[email protected]
[email protected]

I have a simple modal component:

import React, { Component } from 'react'

import { Modal } from "react-bootstrap";
import { ProgressBar } from "react-bootstrap";

class ProgressModal extends Component {
  constructor(...args) {
    super(...args);

    this.state = { showModal: false, titleText: ((this.props.titletext === undefined || this.props.titletext === null || this.props.titletext === "") ? "Working..." : this.props.titletext)};

    this.open = this.open.bind(this);
    this.close = this.close.bind(this);
  }

  open() {
    this.setState({showModal: true});
  }

  close() {
    this.setState({showModal: false});
  }

  render() {
    return (
      <Modal centered backdrop="static" keyboard={false} {...this.props}>
        <Modal.Header>
          <Modal.Title className="font-weight-bold">{this.state.titleText}</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <ProgressBar animated striped now={100} />
        </Modal.Body>
      </Modal>
    );
  }
}

export default ProgressModal;

This is intended to be open for longer running activities (like login). I want to open it when the user clicks the login button and then close it when the login is complete. I am having difficulty finding a way to close it other than using a close button from inside the modal window:

<Button className="btn-block" variant="danger" onClick={this.props.onHide}>Close</Button>

This of course only allows the user to close it when they want. I have added an open and close method in the component that I would like to call from external components.

I have tried a number of things:

Adding an id, finding it using getElementById and then triggering the method.

Adding a ref to the opening component as described here.

Doing it programmatically as described here.

I got some ideas from this question on how to call methods in other components.

With all of that said, I still have no way to close the modal window automatically from outside the modal component itself.


Solution

  • Here is what I ended up doing. I couldn't get the 'ref' logic working so I ended up using a global reference in the constructor:

    window.progressModal = this;
    

    I also needed to change the close code since the setting of the showModal state variable to false didn't do anything to close the modal window. Setting showModal to true does open the window though:

    <Modal id={"progress-bar-modal-window"} show={this.state.showModal} centered  backdrop="static" keyboard={false} {...this.props}>
    
    open() {
      this.setState({showModal: true});
    }
    
    close() {
      this.props.onHide();
    }
    

    Now external components can open the modal window using:

    window.progressModal.open();
    

    and they can close it using:

    window.progressModal.close();