I am working in MERN project where i want to add a bootstarp modal in react calendar. i want that, if any any user clicks on any date a modal should popup. but i don't know how to proceed. please suggest me some good way to achieve this.
my code
import React, { useState } from 'react'
import Calendar from 'react-calendar'
import 'react-calendar/dist/Calendar.css';
import moment from 'moment'
export default function AddMember() {
const [dateState, setDateState] = useState(new Date())
const changeDate = (e) => {
setDateState(e)
}
return (
<>
<div className='container mt-5'>
<div className='row'>
<div className='col-sm-8 col-md-8 col-lg-8'>
<Calendar
value={dateState}
onChange={changeDate}
/>
<p>Current selected date is <b>{moment(dateState).format('MMMM Do YYYY')}</b> </p>
</div>
</div>
</div>
</>
)
}
You can achieve by setting modal state in your changeDate function like this.
import React, { useState } from 'react'
import Calendar from 'react-calendar'
import 'react-calendar/dist/Calendar.css';
import moment from 'moment'
// import Modal from react-bootrap
import Modal from 'react-bootstrap/Modal';
export default function AddMember() {
const [dateState, setDateState] = useState(new Date())
const [show, setShow] = useState(false)
const handleClose = () => setShow(false)
const handleShow = () => setShow(true)
const changeDate = (e) => {
setDateState(e)
handleShow()
}
return (
<>
<div className='container mt-5'>
<div className='row'>
<div className='col-sm-8 col-md-8 col-lg-8'>
<Calendar
value={dateState}
onChange={changeDate}
/>
<p>Current selected date is <b> {moment(dateState).format('MMMM Do YYYY')}</b> </p>
</div>
</div>
</div>
<Modal show={show} onHide={handleClose}>
// your modal content goes here
</Modal>
</>
)
}
Now whenever user clicks or select a date a modal will popup. Happy coding :-)
Related
I would like to pass several data in a modal. My modal works fine but does not display the data I want. I would like to display the data BY ID, but I get all the data. This is my code :
App.js :
import React, { useState, useEffect } from "react";
import Modal from "./Modal";
import PlayCircleIcon from '#mui/icons-material/PlayCircle';
const App = (props) => {
const [image, setImage] = useState([])
return (
<div>
{image.map((image) => {
return (
<div key={image.id}>
<img src={...}
alt={image.title}
/>
<ExpandMoreIcon onClick={handleClick} />
</div>
)
})}
</div>
);
}
export default App;
Modal.js :
import React from 'react';
const Modal = ({ showModal, image }) => {
console.log("result", image);
return (
<div className="modal" >
<div className='modal__content'>
<h1 className='modal__title'>{image.title}</h1>
<p className='modal__description'>{image.description}</h1>
</div>
</div>
);
}
export default Modal;
I think the problem comes from here image={image} in App.js because I get 8 tables in console.log("result", movie);
{showModal && <Modal showModal={handleClick} image={image} />}
Your problem is your modal state is true/false value, so that's why once you trigger showModal, it will show all modals according to your number of images
The fix can be
Note that I modified your state name to align with new state values
const [modalImage, setModalImage] = useState(); //undefined as no image selected
const handleClick = (imageId) => {
setModalImage(imageId);
};
Your elements will be like below
<ExpandMoreIcon onClick={() => handleClick(image.id)} />
{modalImage === image.id && <Modal showModal={() => handleClick(image.id)} image={image} />}
If you want to close the modal, you can reset modalImage state
onClick={() => handleClick(undefined)}
I just noticed that you also can move your modal out of the image loop, and potentially you can pass the entire image object to the modal too
The full implementation
import React, { useState, useEffect } from "react";
import Modal from "./Modal";
import PlayCircleIcon from '#mui/icons-material/PlayCircle';
const App = (props) => {
const [image, setImage] = useState([])
const [modalImage, setModalImage] = useState(); //no image selected
const handleClick = (image) => {
setModalImage(image);
};
useEffect(() => {
...
}, []);
return (
<div>
{image.map((image) => {
return (
<div key={image.id}>
<img src={...}
alt={image.title}
/>
<ExpandMoreIcon onClick={() => handleClick(image)} />
</div>
)
})}
{modalImage && <Modal showModal={() => handleClick(modalImage)} image={modalImage} />}
</div>
);
}
export default App;
Both the map item and the image state array are named image in your code here;
image.map((image) => {
/// your code
})
which could be the ambiguity that led to showing the whole array of data instead of one image in the array.
this is my card js here i have mapped the data from my productdata file and used the states
to get my popup data on the click of more info button. But with this code i am not able to
reflect the change to only one card. I am not getting how can i only reflect this change to my
selected card.
import React, {useState} from 'react';
import Modal from '../Modal';
import productCard from "./productData";
function Card() {
const [showModal, setShowModal] = useState(false);
const openModal = (value) => {
setShowModal(prev => !prev)
};
const listitems = productCard.map((item) =>
<div className="card" key={item.id}>
<div className="card_img">
<img src={item.thumb} alt="img" />
</div>
<div className="card_header">
<h2>{item.product_name}</h2>
<p>{item.description}</p>
<button className="description" onClick={() =>openModal(item.id)}>More
Info</button>
<Modal showModal={showModal} setShowModal={()=>setShowModal(item.id)} />
<p className="price">{item.price}<span>{item.currency}</span></p>
<div className="btn">Add to cart</div>
</div>
</div>)
return (
<>
<h2 className="content_title">Product list</h2>
{/* <div>{this.state.count}</div> */}
<div className="main_content">
<h3>MOBILES</h3>
{listitems};
</div>
</>
)
}
export default Card;
and this is my modal js:
when i click on the more info button it popups the changes with all the cards
import React from 'react';
const Modal = ({showModal, setShowModal}) => {
console.log(showModal)
return (
<>
{showModal ?
<div>hello</div> : null
}
</>
)
}
export default Modal
Each card item from your "listitems" and its child Modal shares the same showModal state. I would recommend creating a separate "Card" component which has its own "showModal" state, controlled by its own button, and pass the "item" as a prop inside that component through a similar mapping of "productCard" like you've done.
I am very new to React hooks can someone please help me how to show a button after 10 seconds I tried a little but I don't know how to implement it.
This is my code
import React, { useState, useEffect } from 'react';
import './App.css';
const App = () => {
const [show, setShow] = useState(false)
useEffect(() => {
});
return (
<div className='container'>
<div className='row'>
<div className='col-12'>
<div className='main'>
<button className='btn btn-primary'>Click here</button>
</div>
</div>
</div>
</div>
)
}
export default App
```
Try this:
useEffect(() => {
setTimeout(() => setShow(true), 10000);
}, []); []: this is important as it will run this effect only once on component load
and use it like:
{show && <button className='btn btn-primary'>Click here</button>} // this will show the button when show state will be true
By default I am trying to show button, Now I am trying to hide button when I click the buton in react using functional components.
This is my code
This is App.js
import React, { useState } from 'react';
import Parent from './Parent/Parent';
import './App.css';
function App() {
return (
<div className="App">
<Parent></Parent>
</div>
);
}
export default App;
This is Parent.js
import React, { useState } from 'react';
import './Parent.css';
const Parent = () => {
const [show, hide] = useState(true)
const hideButton = () => {
hide(false)
}
return (
<div className='container'>
<div className='row'>
<div className='col-12'>
<div className='one'>
<button show ={show} onClick={hideButton} className='btn btn-primary'>Click here</button>
</div>
</div>
</div>
</div>
)
}
export default Parent
You need to do ternary condition to show and hide value:
{show && <button onClick={hideButton} className='btn btn-primary'>Click here</button>}
Full code:
import React, { useState } from "react";
import "./styles.css";
const Parent = () => {
const [show, hide] = useState(true);
const hideButton = () => {
hide(false);
};
return (
<div className="container">
<div className="row">
<div className="col-12">
<div className="one">
{show && (
<button onClick={hideButton} className="btn btn-primary">
Click here
</button>
)}
</div>
</div>
</div>
</div>
);
};
export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Parent />
</div>
);
}
Here is the demo: https://codesandbox.io/s/romantic-newton-1wvl1?file=/src/App.js:0-678
Can we create a toggle-able modal in a functional component without using hooks. Actually I'm trying to design a modal in a functional component but I couldn't achieve what I tried for. And on google, all I could find is hooks.
here's what I wrote but its not working
import React from 'react';
import { Card, CardImg, CardImgOverlay, CardBody, CardText, CardTitle, Breadcrumb, BreadcrumbItem, Button, Modal, ModalHeader } from 'reactstrap';
import { Link } from 'react-router-dom';
let isModalOpen = false;
const toggleModal = () => {
isModalOpen = !isModalOpen;
console.log(isModalOpen);
}
function RenderComments({comments}) {
if(comments!=null){
const list = comments.map((comment) =>{
let options = { year: 'numeric', month: 'long', day: 'numeric' };
let dt = new Date(comment.date);
return (
<li key={comment.id}>
{comment.comment}<br/><br/>
-- {comment.author}, {dt.toLocaleString('en-US', options)}
<br/><br/>
</li>
);
});
return(
<div className="col-12 col-md-7 mt-3 mb-3">
<h4>Comments</h4>
<ul className="list-unstyled">
{list}
</ul>
<Button onClick={toggleModal} outline color="secondary"><span className="fa fa-pencil"></span> Submit Comment</Button>
</div>
);
}else{
return (<div></div>);
}
}
const DishDetail = (props) => {
if(props.dish!=undefined){
return(
<div className="container">
<div className="row">
<Breadcrumb>
<BreadcrumbItem><Link to="/menu">Menu</Link></BreadcrumbItem>
<BreadcrumbItem active>{props.dish.name}</BreadcrumbItem>
</Breadcrumb>
<div className="col-12">
<h3>{props.dish.name}</h3>
</div>
<RenderDish dish = {props.dish} />
<RenderComments comments = {props.comments} />
</div>
<Modal isOpen={isModalOpen} toggle={toggleModal}>
<ModalHeader toggle={toggleModal}>
Login
</ModalHeader>
</Modal>
</div>
)
}else{
return(<div></div>);
}
}
export default DishDetail;
Can somebody please explain why this piece of code is not working?
in debugger I found that isOpen attribute of modal is always false and is not changing on clicking the button
Actually your code works but the react component is not rerendered because react doesn't know something has changed, that's why you have to use an useState hook.
that doesn't change the code much, just put the isModalOpen state at the top of the function
const [isModalOpen, setisModalOpen] = useState(false);
const toggleModal = () => {
setisModalOpen(!isModalOpen);
console.log(isModalOpen);
}