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.
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.
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.
we just handled multiple modals by having each pass in a different id and then setting the 'show' state to that:
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>
)
}
i used multiple models like this
render() {
return(
<div>
<button onClick={() => this.setState({ showModal1:true, showModal2:false});} >open modal one</button>
<button onClick={() => this.setState({ showModal2:true, showModal1:false});} >open modal two</button>
<Modal show={this.state.showModal1} onHide={() => this.setState({ showModal1:false});}>
modal one content..
</Modal>
<Modal show={this.state.showModal2} onHide={() => this.setState({ showModal2:false});}>
modal two content..
</Modal>
</div>
);
}
It depends on what do you want to achieve. I have multiple react bootstrap modal dialogs and also have embedded dialogs, like modal dialog shows popup with error message. Generally you can define state variable, like this:
this.state = {showModal1:true, showModal2:false,...}
In your render function you can do like this:
render() {
return(
<div>
<Modal show={this.state.showModal1}>
some modal 1 text comes here
</Modal>
<Modal show={this.state.showModal2}>
some modal 2 text comes here
</Modal>
</div>
);
}
In the code above, if both showModal1 and showModal2 are true, you will get both modal dialogs and the second will above the first one.
import React, { useState } from "react"
import Button from 'react-bootstrap/Button';
import Modal from "react-bootstrap/Modal";
import ModalBody from "react-bootstrap/ModalBody";
import ModalFooter from "react-bootstrap/ModalFooter";
const MyModals = () => {
const [modalState, setModalState] = useState("close");
const handleShowModalOne = () => {
setModalState("modal-one")
}
const handleShowModalTwo = () => {
setModalState("modal-two")
}
const handleClose = () => {
setModalState("close")
}
return (
<>
<Modal show={modalState === "modal-one"}>
<ModalBody>This is Modal One</ModalBody>
<ModalFooter>
<Button variant="primary" onClick={handleClose}>Close</Button>
<Button>Save Changes</Button>
</ModalFooter>
</Modal>
<Modal show={modalState === "modal-two"}>
<ModalBody>This is Modal Two</ModalBody>
<ModalFooter>
<Button variant="primary" onClick={handleClose}>Close</Button>
<Button>Save Changes</Button>
</ModalFooter>
</Modal>
<Button variant="primary" onClick={handleShowModalOne}>Open Model</Button>
<Button variant="primary" onClick={handleShowModalTwo}>Open Second Model</Button></>
)
}
export default MyModals;
I managed to get these 3 react-bootstrap modals working. It is a meet the team component with 3 modals: Marcos, Gonza, and Eliana
import React, { useState } from 'react';
import Modal from 'react-bootstrap/Modal';
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import 'bootstrap/dist/css/bootstrap.min.css';
import './../css/Wrapper.scss'
function About() {
const [marcosModal, setMarcosModal] = useState(false);
const [gonzaModal, setGonzaModal] = useState(false);
const [elianaModal, setElianaModal] = useState(false);
const handleMarcosClose = () => setMarcosModal(false);
const handleMarcosShow = () => setMarcosModal(true);
const handleGonzaClose = () => setGonzaModal(false);
const handleGonzaShow = () => setGonzaModal(true);
const handleElianaClose = () => setElianaModal(false);
const handleElianaShow = () => setElianaModal(true);
return (
<div
className="wrapper"
>
<Container>
<Row>
<div className="col-12 col-xl-8 offset-xl-2">
<Container>
<Row>
<div
className='col-12 col-md-4 pt-5 px-5'>
<h2 className='text-center pt-4'>Marcos</h2>
<p className='text-center'>Marcos is a founder and instructor at Scuba Point, he has 17 years of diving experience and loves the underwater world.</p>
<span className="btn btn-outline-dark btn-lg mx-auto w-100 d-block mb-3" onClick={handleMarcosShow}>SEE MORE</span>
<Modal
keyboard={false}
show={marcosModal}
onHide={handleMarcosClose}
>
<Modal.Header closeButton>
<Modal.Title><h2 className='mt-3'>Marcos bio</h2></Modal.Title>
</Modal.Header>
<Modal.Body>
Marcos is a diving instructor with 17 years of experience.
</Modal.Body>
</Modal>
</div>
<div
className='col-12 col-md-4 pt-5 px-5'>
<h2 className='text-center pt-4'>Gonza</h2>
<p className='text-center'>Gonza is an Argentinian legend who is passionate about diving, he is excellent at keeping it fun too.</p>
<span className="btn btn-outline-dark btn-lg mx-auto w-100 d-block mb-3" onClick={handleGonzaShow}>SEE MORE</span>
<Modal
show={gonzaModal}
onHide={handleGonzaClose}
keyboard={false}
>
<Modal.Header closeButton>
<Modal.Title><h2 className='mt-3'>Gonza bio</h2></Modal.Title>
</Modal.Header>
<Modal.Body>
Meet Gonza, an experienced and passionate Argentinian diving instructor based in Tenerife.
</Modal.Body>
</Modal>
</div>
<div
className='col-12 col-md-4 pt-5 px-5'>
<h2 className='text-center pt-4'>Eliana</h2>
<p className='text-center'>Eliana is a new member of the team, she loves Tenerife and swimming with rays across the rocks.</p>
<span className="btn btn-outline-dark btn-lg mx-auto w-100 d-block mb-3" onClick={handleElianaShow}>SEE MORE</span>
<Modal
show={elianaModal}
onHide={handleElianaClose}
keyboard={false}
>
<Modal.Header closeButton>
<Modal.Title><h2 className='mt-3'>Eliana bio</h2></Modal.Title>
</Modal.Header>
<Modal.Body>
Meet Eliana, a valuable member of the Scuba Point diving team based in Tenerife.
</Modal.Body>
</Modal>
</div>
</Row>
</Container>
</div>
</Row>
</Container>
</div >
)
}
export default About