Reputation: 63
I would like to have a modal that will pop up when a table row is clicked. The modal is opening when I click a row in my table component. However I'm not getting the desired result with the css. I want it to overlap everything that is on the page when a row is clicked. Right now it's showing on top of the page and I cant see the content in it.
//Modal.js
import React from "react";
import Table from "react-bootstrap/Table";
export default function Modal() {
return (
<div className="modalContainer">
<Table responsive="true" size="sm" striped bordered hover>
<thead>
<tr>
<th>Own Product</th>
<th>Competitors Products</th>
</tr>
</thead>
<p>Brand</p>
<p>Category</p>
<p>In Stock</p>
<p>Name</p>
<p>Price</p>
<p>Product Code</p>
<p>Product Link</p>
</Table>
</div>
);
}
//Code from Table.js
render() {
let { isLoaded, products } = this.state; //instead of typing
this.state all the time
if (!isLoaded) {
return <Loading />;
} else {
return (
<div className="tableContainer">
{this.props.rows}
<Table responsive="true" size="sm" striped bordered hover>
<thead>
<tr>
<th>Product ID</th>
<th>Product Name</th>
<th>Match ID</th>
<th>Match Score</th>
<th>Match Name</th>
<th>Match Price</th>
<th>Match State</th>
</tr>
</thead>
<tbody>
{products.map(product => (
//use filter instead to show only the matched ones
<tr key={product.id} onClick={() => this.toggleModal()}>
<td>{product.id}</td>
<td>{product.name}</td>
<td>{product.matches[0].id}</td>
<td>{Math.round(product.matches[0].score)}</td>
<td>{product.matches[0].name}</td>
<td>{product.matches[0].price}</td>
<td>{product.matches[0].matchLabel}</td>
</tr>
))}
{this.state.modalOpen ? <Modal /> : null}
</tbody>
</Table>
</div>
);
}
}
//CSS
.tableContainer {
position: relative;
width: 100%;
height: 100%;
}
.modalContainer {
margin: -30% auto;
position: absolute;
width: 100%;
height: 100%;
justify-content: center;
border: 1px solid black;
z-index: 1;
left: 0;
top: 0;
overflow: auto;
background-color: rgba(219, 239, 250);
}
Upvotes: 1
Views: 584
Reputation: 3258
State for modal
state = {
axiosStatus: {
status: '',
title: '',
details: '',
},
modal: false,
}
modal handler
modalHandler = ()=> {
this.setState({modal: !this.state.modal});
};
modal content hander
axiosStatusHandler = (status, title, details)=>{
let oldState = this.state.axiosStatus;
oldState.status = status;
oldState.title = title;
oldState.details = details;
this.setState({axiosStatus: oldState});
};
Jsx for modal
<Modal show={this.state.modal} modalClosed={this.modalHandler}>
<ModalContent
status = {this.state.axiosStatus.status}
title = {this.state.axiosStatus.title}
details = {this.state.axiosStatus.details}
/>
</Modal>
Modal Component
import React from 'react';
import './Modal.css';
import Aux from '../../../hoc/Auxi';
import Backdrop from '../Backdrop/Backdrop';
const Modal = ( props ) => (
<Aux>
<Backdrop show={props.show} clicked={props.modalClosed} />
<div
className={"Modal"}
style={{
transform: props.show ? 'translateY(0)' : 'translateY(-100vh)',
opacity: props.show ? '1' : '0'
}}>
{props.children}
</div>
</Aux>
);
export default Modal;
Backdrop Component
import React from 'react';
import './Backdrop.css';
const backdrop = (props) => (
props.show ? <div className={"Backdrop"} onClick={props.clicked}></div> : null
);
export default backdrop;
Backdrop css
.Backdrop {
width: 100%;
height: 100%;
position: fixed;
z-index: 100;
left: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.5);
}
ModalContenet Component
import React from 'react';
const ModalContent = (props)=>{
return (
<div style={{textAlign: 'center'}}>
{/* <h3 style={{color: '#FF0000'}}>Failed</h3>*/}
<b><h2 style={{color: '#FF0000'}}>{props.title}</h2></b>
<h2 style={{color: '#FF0000'}}>{props.details}</h2>
</div>
)
};
export default ModalContent;
Upvotes: 0
Reputation: 9907
The issue is that your tableContainer
is position:relative
, which re-sets the positioning context for its children. So, your <Modal>
is absolutely positioned with respect to the tableContainer
instead of the browser window.
You can either change your css to so your Modal is e.g. position:fixed
or move your modal out of your tableContainer
like this:
return (
<>
{this.state.modalOpen ? <Modal /> : null}
<div className="tableContainer">
{this.props.rows}
<Table responsive="true" size="sm" striped bordered hover>
//....//
</Table>
</div>
</>
Upvotes: 1