I am using React-bootstrap in my project. I need to open multiple dialog. Is there any way to achieve this?
Note: There is answers for bootstrap here but it does not work in react-bootstrap. Thanks.
If you are using scss as css preprocessor, then you can use a loop for defining the proper z-index 's in order to make everything appears as one top of other.
This loop handles upto 5 levels, you can increase the number if you want
@for $i from 1 through 6 {
  $zIndexBackdrop:  #{1000 + (5 * $i)};
  $zIndexContent:  #{1000 + (5 * $i) + 2};
  .modal-backdrop.show:nth-of-type(#{$i}) {
    z-index: $zIndexBackdrop;
  }
  div[role="dialog"][aria-modal="true"]:nth-of-type(#{$i}) {
    z-index: $zIndexContent;
  }
}
The loop here 1 through 6 loops 5 times, you can increase the depth of modals if you want by increase the number.
I have used generic class names used by react-bootstrap modals, please do a cross check on how backdrops and main modals are being created.
we just handled multiple modals by having each pass in a different id and then setting the 'show' state to that:
https://github.com/AgileVentures/agile-ventures-website-react-front-end/blob/4_homepage_changes_mob/src/App.js#L26
class App extends Component {
  constructor(props, context) {
    super(props, context);
    this.handleShow = this.handleShow.bind(this);
    this.handleClose = this.handleClose.bind(this);
    this.state = {
      show: null
    };
  }
  handleClose() {
    this.setState({show: id});
  }
  handleShow(id) {
    this.setState({show: id});
  }
  render() {
    return (
      <div className="App">
        <Grid>
          <Row>
            <Col xsOffset={1} sm={5}>
              <Button bsStyle="primary" bsSize="large" onClick={() => this.handleShow('here')}>
                <h1>You are here!</h1>
              </Button>
              <Modal
                show={this.state.show == 'here'} onHide={this.handleClose}
              >
                <Modal.Header closeButton closeLabel="close window">
                </Modal.Header>
                <Modal.Body>
                  <p className='landing-page-markers you-are-here'>Tired of toy projects, tutorials and online courses?
                      <img src={logo} className="App-logo" alt="logo" />
                  </p>
                </Modal.Body>
              </Modal>
            </Col>
          </Row>
          ... more modals passing in different ids ...
If you are using React 16.8+, you can use the React Hook useState (and functional component) so you can specify which modals you want it to appear based on the state:
export const MyModals = () => {
const [modalState, setModalState] = useState< "modal-one" | "modal-two" | "close" >("close")
const handleShowModalOne = () => {
 setModalState("modal-one")
}
const handleShowModalTwo = () => {
 setModalState("modal-two")
}
const handleClose = () => {
 setModalState("close")
}
return (
 <div>
   <Button onClick={handleShowModalOne}>Show Modal One</Button>
   <Modal show={modalState === "modal-one"}>
     <Modal.Body>This is Modal One</Modal.Body>
     <Modal.Footer>
       <Button onClick={handleShowModalTwo}>Show Modal Two</Button>
     </Modal.Footer>
   </Modal>
   <Modal show={modalState === "modal-two"}>
     <Modal.Body>This is Modal Two</Modal.Body>
     <Modal.Footer>
       <Button onClick={handleClose}>Close</Button>
     </Modal.Footer>
   </Modal>
 </div>
)
}
The "nth-of-type" solution is not working for me. Instead, I solved it with "nth-last-child" like these.
div[role="dialog"][aria-modal="true"]:nth-last-child(1) {
  z-index: 1125;
}
.modal-backdrop.show:nth-last-child(2){
  z-index: 1100;
}
div[role="dialog"][aria-modal="true"]:nth-last-child(3) {
  z-index: 1075;
}
.modal-backdrop.show:nth-last-child(4){
  z-index: 1050;
}
div[role="dialog"][aria-modal="true"]:nth-last-child(5) {
  z-index: 1025;
}
.modal-backdrop.show:nth-last-child(6){
  z-index: 1000;
}
The idea is that every time a modal is shown, a modal element and a shadow element will be appended to the body (this happens already by the library). So from the last child, the (n + 1) element will be a modal and the (n + 2) element will be modal shadow element.
In the example, I set the nested modals to be working at most 3 levels but you can add two of these style as deep as you want.
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