Modal not displaying on click (React) - reactjs

I am trying to get a modal to function the modal I am trying to mirror is available here.
https://codesandbox.io/s/n9zn3n43o0
The button for the modal is displaying however the modal itself is not.
Here is my exact code for this function.
class App extends React.Component {
constructor(props) {
console.log("Props - ", props);
super(props);
this.state = {
modalVisible: false
};
this.openModal = this.openModal.bind(this);
}
openModal() {
console.log("Open modal called ", this.state.modalVisible);
const modalVisible = !this.state.modalVisible;
this.setState({
modalVisible
});
}
render() {
let styles = this.state.modalVisible
? { display: "block" }
: { display: "none" };
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<button
type="button"
onClick={this.openModal}
className="btn btn-info btn-lg"
>
Open Modal
</button>
<div
id="myModal"
className="modal fade in"
role="dialog"
style={styles}
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button
type="button"
onClick={this.openModal}
className="close"
>
×
</button>
<h4 className="modal-title">Modal Header</h4>
</div>
<div className="modal-body">
<p>Some text in the modal.</p>
</div>
<div className="modal-footer">
<button
onClick={this.openModal}
type="button"
className="btn btn-default"
>
Close
</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
And here is the code of the whole page
import React from "react";
import { Link } from "react-router-dom";
import Popup from "reactjs-popup";
import { Button, ButtonToolbar, Modal } from "react-bootstrap";
import ReactDOM from "react-dom";
import AddWorkstation from "./UpdateUserWorkStationDetailsForm";
class DisplayUserAcountDetails extends React.Component {
constructor() {
super();
this.state = { AccountDetails: [] };
}
// sets the questions form sql into state for questions
getItems() {
var user = window.localStorage.getItem("User");
if (user) {
fetch(`/profile-work-station-detailss/${user}`)
.then(recordset => recordset.json())
.then(results => {
this.setState({ AccountDetails: results.recordset });
});
} else {
alert("user not set");
}
}
//when the component mounts make the sql questions the
componentDidMount() {
this.setState({
AccountDetails: this.getItems()
});
}
render() {
try {
return (
<>
<h3 style={{ textAlign: "center" }}> Workstations</h3>
<button></button>
{this.state.AccountDetails ? (
<ul>
<App /> // calling it here
<Popup
style={{ width: "300px" }}
trigger={<button> Help?</button>}
closeOnDocumentClick
className={"tooltipBoundary"}
>
<AddWorkstation />
</Popup>
<Link to="/update-work-station-details">
<button style={{ float: "right" }}>+</button>
</Link>
<br />
<br />
{this.state.AccountDetails &&
this.state.AccountDetails.map(function(AccountDetails, index) {
return (
<div className="jumbotron">
<h3>Work Station</h3>
<li> Location: {AccountDetails.DeskLocation}</li>
<li>
ExtraInformation: {AccountDetails.ExtraInformation}
</li>
<li>
Primary Work Station:
{AccountDetails.PrimaryWorkStation}
</li>
<li> Date Added: {AccountDetails.PrimaryWorkStation}</li>
<li>
<Link to="/update-work-station-details">
<button>Update Account Details</button>
</Link>
</li>
</div>
);
})}
</ul>
) : (
<ul>
<div className="jumbotron">
<h3>Work Station</h3>
<li> Email: Null </li>
<li> Name: Null </li>
<li> Contact Number: Null </li>
<li>
<Link to="/update-work-station-details">
<button>Update Accoudnt Details</button>
</Link>
</li>
</div>
</ul>
)}
</>
);
} catch (e) {
console.log(e);
}
}
}
export default DisplayUserAcountDetails;
class App extends React.Component {
constructor(props) {
console.log("Props - ", props);
super(props);
this.state = {
modalVisible: false
};
this.openModal = this.openModal.bind(this);
}
openModal() {
console.log("Open modal called ", this.state.modalVisible);
const modalVisible = !this.state.modalVisible;
this.setState({
modalVisible
});
}
render() {
let styles = this.state.modalVisible
? { display: "block" }
: { display: "none" };
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<button
type="button"
onClick={this.openModal}
className="btn btn-info btn-lg"
>
Open Modal
</button>
<div
id="myModal"
className="modal fade in"
role="dialog"
style={styles}
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button
type="button"
onClick={this.openModal}
className="close"
>
×
</button>
<h4 className="modal-title">Modal Header</h4>
</div>
<div className="modal-body">
<p>Some text in the modal.</p>
</div>
<div className="modal-footer">
<button
onClick={this.openModal}
type="button"
className="btn btn-default"
>
Close
</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
I have tried multiple examples but this issue still persists.
Is there something I am missing ?
Any help greatly appreciated.

Hope this helps someone this is the code I have used instead and it worked fine.
class Header extends React.Component {
constructor(props) {
super(props);
this.handleClose = this.handleClose.bind(this);
this.handleShow = this.handleShow.bind(this);
this.state = {
show: false
};
}
handleClose() {
this.setState({
show: false
});
}
handleShow() {
this.setState({
show: true
});
}
render() {
// console.log(this.state);
return (
<div className="header-container">
<Button onClick={this.handleShow}>LOGIN</Button>
<Modal show={this.state.show} onHide={this.handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal Header</Modal.Title>
</Modal.Header>
<Modal.Body>Modal Body</Modal.Body>
</Modal>
</div>
);
}
}

Related

Product Pop-up using React and Django

I am working through a tutorial on React and creating an ecommerce store with a Django backend.
I am new to React.
I have been able to get the React "FrontEnd" home page to display the products from the Django "products.py" which is a simple JSON file stored in the Django file system using the React Axios library.
There is a product pop-up which displays the product information when the use clicks on the view button.
I can't work out how to direct the pop-up to the "products.py" file.
It is still drawing its information from the products.js in the React "FrontEnd" file system.
The code is below. Any assistance would be appreciated.
The code for the product page is below.
Bestsellershop.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { handleOutofStock } from '../../../helper/shopHelper';
import { RatingShop } from '../../../helper/helper';
import Quickview from '../../layouts/Quickview';
import { Modal } from 'react-bootstrap';
import axios from 'axios'
class Bestsellershop extends Component {
constructor(props) {
super(props);
this.state = {
error:null,
modalshow: false,
lastActiveBox: -1,
data:[]
}
this.modalShow = this.modalShow.bind(this);
this.modalClose = this.modalClose.bind(this);
}
componentDidMount(){
var str = "GeeksforGeeks";
this.setState({loading:true});
axios
.get('/api/products/')
.then(res=>{
console.log(res.data);
this.setState({data:res.data, loading:false});
})
.catch(err =>{
console.log(str)
this.setState({error:err, loading:false});
});
}
// Modal
modalShow(index) {
this.setState({ modalshow: true, lastActiveBox: index });
}
modalClose() {
this.setState({ modalshow: false });
}
render() {
const{data,error,loading}=this.state;
return (
<div className="section section-padding">
<div className="container">
<div className="section-title centered">
<span className="subtitle">SuperPharmacy Compounding</span>
<h3 className="title mb-0">Our Products</h3>
</div>
<div className="row">
{error && (
<
error
header="There was some error"
content={JSON.stringify(error)}
/>
)}
{/* Data */}
{data.map((item, i) => (
<div className="col-lg-3 col-md-6" key={i}>
<div className="sigma_product style-6">
<div className="sigma_product-thumb">
<Link to={"/product-single/" + item.id}>
<img src={process.env.PUBLIC_URL + "/" + item.image[0]} alt={item.title} />
</Link>
</div>
<div className="sigma_product-body">
<h5 className="sigma_product-title"> <Link to={"/product-single/" + item.id}>{item.title}</Link>
</h5>
<div className="sigma_rating">
{RatingShop(item.rating)}
</div>
<div className="sigma_product-price">
<span>${new Intl.NumberFormat().format((item.price * (100 - item.discount) / 100).toFixed(2))}</span>
{item.discount > 0 || item.discount !== '' ?
<span>${new Intl.NumberFormat().format((item.price).toFixed(2))}</span>
: ''}
</div>
{/* Cart */}
{item.stock === true ?
<Link to="#" className="sigma_btn btn-sm">Add to Cart</Link>
:
<Link to="#" className="sigma_btn btn-sm" onClick={handleOutofStock}> Add to Cart</Link>
}
{/* Quick view */}
<Link to="#" className="sigma_btn btn-sm light" onClick={(e) => this.modalShow(item.id)}> Quick View </Link>
</div>
</div>
</div>
))}
{/* Data */}
{/* Modal (Quick View) */}
<Modal size="lg" show={this.state.modalshow} className="sigma_quick-view-modal" onHide={this.modalClose} aria-labelledby="contained-modal-title-vcenter" centered>
<Modal.Body className="sigma_modal-sec">
<div className="sigma_close" onClick={this.modalClose}>
<span />
<span />
</div>
<Quickview productId={this.state.lastActiveBox} />
</Modal.Body>
</Modal>
</div>
</div>
</div>
);
}
}
export default Bestsellershop;
The code for the modal pop-up is below.
Quickview.js
import React, { Component } from 'react';
import { getProduct, handleOutofStock } from '../../helper/shopHelper';
import { RatingShop, socialShare, getTags } from '../../helper/helper';
import { Link } from 'react-router-dom';
class Quickview extends Component {
constructor(props) {
super(props)
this.state = {
qty: 1
}
this.increment = this.increment.bind(this);
this.decrement = this.decrement.bind(this);
this.openSocialPopup = this.openSocialPopup.bind(this);
}
increment() {
this.setState({
qty: this.state.qty + 1
});
}
decrement() {
this.setState({
qty: this.state.qty > 1 ? this.state.qty - 1 : 1
});
}
handleChange(event) {
this.setState({ qty: event.target.value });
}
// Open window
openSocialPopup(social) {
window.open(social.link, "MsgWindow", "width=600,height=600")
// alert(social.title)
}
render() {
const productId = this.props.productId;
const modalContent = getProduct(productId);
return (
<div className="row sigma_product-single">
<div className="col-md-6">
<div className="sigma_product-single-thumb">
<img src={process.env.PUBLIC_URL + "/" + modalContent.image[0]} alt={modalContent.title} className="w-100" />
</div>
</div>
<div className="col-md-6">
<div className="sigma_product-single-content">
<h3>{modalContent.title}</h3>
<div className="sigma_product-price">
<span>${new Intl.NumberFormat().format((modalContent.price * (100 - modalContent.discount) / 100).toFixed(2))}</span>
{modalContent.discount > 0 || modalContent.discount !== '' ?
<span>${new Intl.NumberFormat().format((modalContent.price).toFixed(2))}</span>
: ''}
</div>
<div className="sigma_rating-wrapper">
<div className="sigma_rating">
{RatingShop(modalContent.rating)}
</div>
<span>{modalContent.reviews.length} Reviews</span>
</div>
<hr />
<p className="sigma_product-excerpt">
{modalContent.shorttext}
</p>
<div className="sigma_product-meta">
<p><strong>Product SKU: <span>#{modalContent.sku}</span></strong></p>
<p><strong>Availablity:
{modalContent.stock === true ?
<span>In Stock</span>
:
<span>Out of Stock</span>
}
</strong></p>
<p><strong>Tags: </strong>
{getTags(modalContent.tags).map((tag, i) => (
<Link to={"/shop/tag/" + tag.id} key={i}>{tag.title} ,</Link>
))}
</p>
</div>
<hr />
<form className="sigma_product-atc-form">
<div className="sigma_product-buttons d-block">
{/* Cart */}
{modalContent.stock === true ?
<button type="button" className="ml-0 btn-block sigma_btn">Add To
Cart <i className="far fa-shopping-basket" /></button>
:
<button type="button" onClick={handleOutofStock} disabled className="ml-0 btn-block sigma_btn">Add To Cart <i className="far fa-shopping-basket" /></button>
}
{/* Wishlist */}
<Link to="#" className="ml-0 btn-block sigma_btn light">Add To Wishlist <i className="far fa-heart" /> </Link>
<Link to="#" className="ml-0 btn-block sigma_btn light">Compare <i className="far fa-compress" />
</Link>
</div>
</form>
{/* Post Meta Start */}
<div className="sigma_post-single-meta">
<div className="sigma_post-single-meta-item sigma_post-share">
<h5>Share</h5>
<ul className="sigma_sm">
{/* Data */}
{socialShare(modalContent.title).map((social, i) => (
<li key={i}>
<Link to="#" onClick={(e) => this.openSocialPopup(social, i)}>
<i className={social.iconClass} />
</Link>
</li>
))}
{/* Data */}
</ul>
</div>
</div>
{/* Post Meta End */}
</div>
</div>
</div>
);
}
}
export default Quickview;
Update - I have located a helper function file called 'ShopHelper.js'. It contains a function getProduct(id). That function refers to an internal json 'shop.json'.
How do I redirect the shopBlock variable to the Django file?! I am very lost
import shopblock from '../data/shop/shop.json';
import category from '../data/shop/category.json';
// Product details
function getProduct(id) {
return shopblock.filter(product => { return product.id === parseInt(id) })[0];
}
// Count Category

Append data in same page in button click with react Js

How can we list data from the array list on the same page in button click using react?
When user enter quantity setting value text box change event
class ProductList extends Component {
constructor(props) {
super(props);
this.state={
CartArray:[],
ProductList:[],
}
}
handleInputChange = event =>
{
const cart_values = event.target.name.split('-');
let newCart = {};
newCart["Key"]=cart_values[0]
newCart["ProductName"]=cart_values[1]
newCart["ProductBrand"]=cart_values[2]
this.setState(prevState => ({CartArray: [...prevState.CartArray, newCart]}))
}
viewCart = () => {
//What need to write here show data from CartArray:[] to my basket
}
}
Below is my render method. Numerical text box change i am setting in state value
render() {
return (
<div className="card" style={{ marginBottom: "10px"}}>
<div> <button className="btn btn-sm btn-warning float-right" onClick={this.viewCart}>View cart</button></div>
{this.state.ProductList.map((product, key) =>(
<div className="card-body">
<div className="card-title" key={key} value={key}>{product.ProductName}
<img src= {`data:image/jpeg;base64,${product.Image2}`} width="200" height="80" />{product.Brand}
<div>
<button className="btn btn-sm btn-warning float-right"
onClick={this.addToCart}>Add to cart</button>
<div>
<input type="number" min="0" pattern="[0-9]*" onInput={this.handleInputChange.bind(this)} name={`Name${key}-${product.ProductName}-${product.Brand}`} />
</div>
</div>
</div>
</div>
))}
</div>
)
}
If by show you mean to show on screen, not inside viewCart but in separate method render()
render(){
return(
<div>
{
this.state.CartArray.map((product) => {
<p>Key: {product.Key} </p>
<p>ProductName: {product.ProductName} </p>
<p>ProductBrand: {product.ProductBrand} </p>
})
}
</div>
);
}

How to change the state of an item affected by onClick in array?

I'm making a page where I need to make multiple selections of buttons (like a filter, which I'll use for the next page).
the information from these buttons is coming from an array and I'm using .map () to mount the button list.
My problem is how do I change the state of only the button that was clicked. The way it is now, when I click, all the buttons are active.
How can I solve this?
Thank you.
import React from 'react';
import { Link } from 'react-router-dom';
import { FormattedMessage } from 'react-intl';
import messages from './messages';
import { getLevel, getDiscipline } from '../../functions';
import template from './index.pug';
export default class ConfigAssessment extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
constructor(props){
super(props);
this.state = {
level: getLevel(),
discipline: getDiscipline(),
active: '',
first_click: true,
}
}
changeActive = () => {
if (this.state.first_click === true) {
this.setState({
active: 'active',
first_click: false
});
} else {
this.setState({
active: '',
first_click: true,
});
}
}
render() {
return(
<div className="configuration">
<div className="config-title">
<i className="ti-settings" />
<h2>
<FormattedMessage {...messages.configAssessment} />
</h2>
</div>
<div className="config-items">
<div className="form-group">
<label>
<FormattedMessage {...messages.level} />
</label>
<div className="row">
{this.state.level.map((level, i) => (
<div className="col-xs-1 col-md-4 col-lg-3" key={level.id}>
<button
className={`btn btn-light-gray btn-block ${this.state.active}`}
id={level.id}
onClick={this.changeActive}
>
{level.level}
</button>
</div>
))}
</div>
</div>
<div className="form-group">
<label>
<FormattedMessage {...messages.discipline} />
</label>
<div className="row">
{ this.state.discipline.map((discipline, i) => (
<div className="col-xs-1 col-md-4 col-lg-3" key={i}>
<button
className={`btn btn-light-gray btn-block ${this.state.active}`}
onClick={this.changeActive}
>
{discipline.discipline}
</button>
</div>
))}
</div>
</div>
<div className="form-group">
<label>
<FormattedMessage {...messages.selectQuestion} />
</label>
<div className="row">
<div className="col-xs-1 col-md-4 col-lg-3">
<button
className={`btn btn-light-gray btn-block ${this.state.active}`}
onClick={this.changeActive}
>
<FormattedMessage {...messages.typeAutomatic} />
</button>
</div>
<div className="col-xs-1 col-md-4 col-lg-3">
<button
className={`btn btn-light-gray btn-block ${this.state.active}`}
onClick={this.changeActive}
>
<FormattedMessage {...messages.typeManual} />
</button>
</div>
</div>
</div>
<div className="form-group fg-right">
<Link className="btn btn-warning" to="#">
<FormattedMessage {...messages.createAssessment} />
</Link>
</div>
</div>
</div>
);
}
}
Create a separate component for button
class MyButton extends Component {
constructor(props){
super(props);
this.state = {
person: this.props.person
}
}
buttonActiveHandler = () => {
let oldStatus = this.props.person.status;
this.props.person.status = (!oldStatus ? 'active': '');
this.setState({
person:this.props.person
});
}
render() {
return (
<button className={this.state.person.status} onClick={this.buttonActiveHandler}>{this.state.person.name}</button>
);
}
}
export default MyButton;
Then import button component. use map function to for your code block
<div className={classes.Box}>
<h4>Lorem, ipsum.</h4>
{
this.props.survey.map((person, i) => {
return (
<MyButton key={i} person={person}/>
)
})
}
</div>
The easiest solution to this problem is making the component of the content inside the map and then handling the state of that component there. Hence it will maintain individual states.
It depends what you need.
You can create separate component for button with state.
You can also keep state of each button in react state as an array, and then you can get the state of each button by index.
I'd recommend the first solution, it'd easier to manage such state, but it will be harder to get the state of a specific button from the parent component.

Delete todo from state array react

I am building an simple todo app to practise reactjs I have 3 components which looks like this:
Here is the TodoAppComponent.js which is the wrapper of the other two components:
import AddTodoComponent from '../AddTodoComponent/AddTodoComponent';
class TodoAppComponent extends Component {
render() {
return (
<div id="page-content-wrapper">
<div className="container">
<div className="row">
<div className="col-lg-6 col-lg-offset-3">
<h1 className="m-b-md">What needs to be done?</h1>
<AddTodoComponent></AddTodoComponent>
</div>
</div>
</div>
</div>
);
}
}
export default TodoAppComponent;
An AddTodoComponent.jsx where I can add an todo:
import TodoItemComponent from '../TodoItemComponent/TodoItemComponent';
class AddTodoComponent extends Component {
constructor(props) {
super(props);
this.state = {
todo: '',
todoArray: []
};
}
addTodo(e){
this.setState({ todo: e.target.value });
this.state.todoArray.push(<TodoItemComponent todo={this.state.todo}></TodoItemComponent>);
}
handleChange(e) {
this.setState({ todo: e.target.value });
}
render() {
return (
<div>
<div className="input-group m-b-md">
<input type="text" className="form-control add-todo" placeholder="Todo..." value={this.state.todo} onChange={this.handleChange.bind(this)} />
<span className="input-group-btn">
<button className="btn btn-react" type="button" onClick={this.addTodo.bind(this)}>Add</button>
</span>
</div>
<ul className="list-group">
{this.state.todoArray}
</ul>
</div>
);
}
}
export default AddTodoComponent;
As you see I push the TodoItemComponent to an state array.
Here is the TodoItemComponent.jsx:
class TodoItemComponent extends Component {
deleteTodo(){
// this.setState({
// data: update(this.state.data, {$splice: [[index, 1]]})
// })
}
render() {
console.log(this.props.todo, this.props.title);
return (
<div>
<li className="list-group-item todo-item">
<button className="btn btn-xs btn-react btn-circle m-r-md">
<span className="fa fa-check"></span>
</button>
{this.props.todo}
<span className="pull-right">
<button className="btn btn-xs btn-react btn-circle m-r-xs">
<span className="fa fa-pencil-square-o"></span>
</button>
<button className="btn btn-xs btn-react btn-circle" onClick={this.deleteTodo()}>
<span className="fa fa-trash-o"></span>
</button>
</span>
</li>
</div>
);
}
}
export default TodoItemComponent;
As you see I have a button where I can delete the todo item. But how can I acces the state in this file to delete it from the state array?
you can try this
deleteTodo(){
this.props.onDelete(this.props.todo);
}
and in yourAdddTodoComponent
addTodo(e){
this.setState({ todo: e.target.value });
this.state.todoArray.push(<TodoItemComponent onDelete={this.delete} todo={this.state.todo}></TodoItemComponent>);
}
delete:function(index)
{
this.setState({
// data: update(this.state.data, {$splice: [[index, 1]]})
// })
}

React Rendering Multiple Modals in Same Component

I'm new to React and to coding in general. I'm trying to render multiple modals in the same component, but they are all being rendered at the same time so that it looks like all the links are rendering the text in the last modal.
Here's where the state is set:
class Header extends React.Component {
constructor () {
super();
this.state = {open:false}
this.openModal = this.openModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.handleModalChangeEnter = this.handleModalChange.bind(this, true);
this.handleModalChangeLogin = this.handleModalChange.bind(this, false);
}
openModal () {
this.setState({open: true}); }
closeModal () {
this.setState({open: false}); }
render() {
And here's the modal construction:
return (
<header style={home}>
<div style={hello}>
<img style={logo} src='public/ycHEAD.png'/>
<p style={slogan}>One Calendar for All of Yerevan's Tech Events</p>
</div>
<div style={subContainer}>
<ul style={modalDirectory}>
<Button onClick={this.openModal}
style={openButton}>
<li><a style={tabs}>Enter
</a></li>
</button>
<Modal style={modalCont}
isOpen={this.state.open}>
<button onClick={this.closeModal}
style={xButton}>x</button>
</Modal>
<button onClick={this.openModal}
style={openButton}>
<li><a style={tabs}>Login
</a></li>
</button>
<Modal style={modalCont}
isOpen={this.state.open}>
<p>Account</p>
<button onClick={this.closeModal}
style={xButton}>x</button>
</Modal>
Should there be a value in the empty parentheses -> openModal() & closeModal() ?
A friend helped me out with this one. The top half of code remains the same, what changes is in the modal construction (some really helpful aesthetic changes were also made to the 'html'):
return (
<header style={home}>
<div style={hello}>
<img style={logo} src='public/ycHEAD.png'/>
<p style={slogan}>One Calendar for All of Yerevan's Tech Events</p>
</div>
<div style={subContainer}>
<ul style={modalDirectory}>
<li style={tabs}>
<button
onClick={() => this.openModal('login')}
style={openButton}>
Enter
</button>
</li>
<li style={tabs}>
<button
onClick={() => this.openModal('calendar')}
style={openButton}>
Calendar
</button>
</li>
<li style={tabs}>
<button
onClick={() => this.openModal('team')}
style={openButton}>
Meet Us
</button>
</li>
</ul>
</div>
<Modal
style={modalCont}
isOpen={this.state.activeModal === 'login'}>
<p>1!</p>
<button onClick={this.closeModal}
style={xButton}>x</button>
</Modal>
<Modal
style={modalCont}
isOpen={this.state.activeModal === 'calendar'}>
<p>2!</p>
<button onClick={this.closeModal}
style={xButton}>x</button>
</Modal>
<Modal
style={modalCont}
isOpen={this.state.activeModal === 'team'}>
<p>3!</p>
<button onClick={this.closeModal}
style={xButton}>x</button>
</Modal>
</header>
If anyone else can provide a thorough explanation, please do so! Also, there is another way to do this using 'bind', but I don't know how.
I have created similar approach but more detailed model for those who need this solution when using "react-modal". It's not clear in question above if react-modal was used or not because import section is missing, but seems to have references to it. For those who are looking for solution using react-modal to display multiple modals in same component, so here is solution and demo :
import React from "react";
import Modal from "react-modal";
class MutipleButtonsWithModalInSameComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
showModal: false,
activeModal: "",
};
this.handleOpenModal = this.handleOpenModal.bind(this);
this.handleCloseModal = this.handleCloseModal.bind(this);
}
handleOpenModal(val) {
this.setState({ activeModal: val });
this.setState({ showModal: true });
}
handleCloseModal() {
this.setState({ showModal: false });
this.setState({ showModal: "" });
}
render() {
return(
<>
{/* {'one item with modal link -login'} */}
<div className="icon">
<a
className="button"
onClick={() => this.handleOpenModal("login")}
>
login (modal popup)
</a>
<Modal
isOpen={
this.state.showModal &&
this.state.activeModal === "login"
}
contentLabel="login Modal"
>
<div className="content">
<button className="close" onClick={this.handleCloseModal}>X</button>
<p>login content in here</p>
</div>
</Modal>
</div>
{/* {'another item with modal link calendar, add more by mutiplying this below'} */}
<div className="icon">
<a
className="button"
onClick={() => this.handleOpenModal("calendar")}
>
calendar (modal popup)
</a>
<Modal
isOpen={
this.state.showModal &&
this.state.activeModal === "calendar"
}
contentLabel="calendar Modal"
>
<div className="content">
<button className="close" onClick={this.handleCloseModal}>X</button>
<p>calendar content in here...</p>
</div>
</Modal>
</div>
{/* {'another item with modal link team, add more by mutiplying this below'} */}
<div className="icon">
<a
className="button"
onClick={() => this.handleOpenModal("team")}
>
team (modal popup)
</a>
<Modal
isOpen={
this.state.showModal &&
this.state.activeModal === "team"
}
contentLabel="team Modal"
>
<div className="content">
<button className="close" onClick={this.handleCloseModal}>X</button>
<p>team content in here...</p>
</div>
</Modal>
</div>
</>
)
}
}
export default MutipleButtonsWithModalInSameComponent;
Here is a stackblitz link or demo
You can do it in two ways.
1) Simple but doesn't scale: Maintain different state variables and functions for each Modal. i.e.,
this.state = {openModal1:false, openModal2:false}
this.openModal1 = this.openModal1.bind(this);
this.closeModal1 = this.closeModal1.bind(this);
this.openModal2 = this.openModal2.bind(this);
this.closeModal2 = this.closeModal2.bind(this);
As we can see, the problem with this is redundancy of the code.
2) Use functions to eliminate redundancy: Maintain a function to change the content of the modal.
class Header extends React.Component {
constructor () {
super();
this.state = {open:false, ModalContent:''}
this.openModal = this.openModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.handleModalChangeEnter = this.handleModalChange.bind(this);
this.handleModalChangeLogin = this.handleModalChange.bind(this);
}
openModal () {
this.setState({open: true}); }
closeModal () {
this.setState({open: false}); }
handleModalChange1() {
this.setState({ ModalContent : '<h1>Modal1 Content</h1>'
}
handleModalChange2() {
this.setState({ ModalContent : '<h1>Modal2 Content</h1>'
}
render() {
Modal Construction Should be :
return (
<header style={home}>
<div style={hello}>
<img style={logo} src='public/ycHEAD.png'/>
<p style={slogan}>One Calendar for All of Yerevan's Tech Events</p>
</div>
<div style={subContainer}>
<ul style={modalDirectory}>
<button onClick={this.handleModalChange1}
style={openButton}>
<li><a style={tabs}>Enter
</a></li>
</button>
<button onClick={this.handleModalChange2}
style={openButton}>
<li><a style={tabs}>Login
</a></li>
</button>
<Modal style={modalCont}
isOpen={this.state.open}>
<div dangerouslySetInnerHTML={{__html: this.state.ModalContent}} />
<button onClick={this.closeModal}
style={xButton}>x</button>
</Modal>

Resources