React Modal not closing via OnClick - javascript

I've set an onClick method to close the React Modal but it's not changing state. I believe there may be an issue with the openModalTwo, setOpenModalTwo but I'm not sure sure.
Here is my code:
import { Avatar } from "#material-ui/core";
import React, { useState } from "react";
import { useSelector } from "react-redux";
import { selectUser } from "../features/userSlice";
import "../style/QuestionBox.css";
import Modal from "react-modal";
import PeopleAltOutlinedIcon from "#material-ui/icons/PeopleAltOutlined";
import { ExpandMore } from "#material-ui/icons";
import { Input } from "#material-ui/core";
import LinkIcon from "#material-ui/icons/Link";
import db from "../firebase";
import firebase from "firebase";
function QuestionBox() {
const user = useSelector(selectUser);
const [openModalTwo, setOpenModalTwo] = useState(false);
const [input, setInput] = useState("");
const [inputUrl, setInputUrl] = useState("");
const handleQuestion = (e) => {
e.preventDefault();
db.collection("questions").add({
question: input,
imageUrl: inputUrl,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
user: user,
});
setInput("");
setInputUrl("");
setOpenModalTwo(false);
};
return (
<div className="questionBox" onClick={() => setOpenModalTwo(true)}>
<div className="questionBox__info">
<Avatar src={user.photo} />
<h5>{user.displayName}</h5>
</div>
<div className="questionBox__question">
<p>Where do I start?</p>
</div>
<Modal
isOpen={openModalTwo}
onRequestClose={() => setOpenModalTwo(false)}
shouldCloseOnOverlayClick={false}
style={{
overlay: {
width: 700,
height: 600,
backgroundColor: "transparent",
boxShadow:
"box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);",
zIndex: "1000",
top: "50%",
left: "50%",
marginTop: "-300px",
marginLeft: "-350px",
},
}}
>
<div className="modal__title">
<h5>Add Question Here</h5>
<h5>Share Your Question</h5>
</div>
<div className="modal__info">
<Avatar Avatar className="avatar" src={user.photo} />
<p>
{user.displayName ? user.displayName : user.email} wants to know
</p>
<div className="modal__scope">
<PeopleAltOutlinedIcon />
<p>Public</p>
<ExpandMore />
</div>
</div>
<div className="modal__field">
<Input
required
value={input}
onChange={(e) => setInput(e.target.value)}
type="text"
placeholder="Ask where to start on your project with a specific 'How' or 'What' question."
/>
<div className="modal__fieldLink">
<LinkIcon />
<input
value={inputUrl}
onChange={(e) => setInputUrl(e.target.value)}
type="text"
placeholder="Add a link to help others understand what you want to build."
/>
</div>
<div className="modal__buttons">
<button
onClick={() => setOpenModalTwo({ openModalTwo: false })}
className="cancel"
>
Close
</button>
<button onClick={handleQuestion} type="submit" className="add">
Add Question
</button>
</div>
</div>
</Modal>
</div>
);
}
export default QuestionBox;

Don't know how react-modal exactly works but as you are setting setOpenModalTwo(true) on click on parent container of Modal, when you're trying to close the Modal (by a click I guess), you are also firing the onClick event of your parent div, and so re-open the Modal.
So either move your Modal outside of your div, or use event.preventDefault() on Modal requesting close

Related

How do I close the modal window in react when clicking on the Add product button?

everyone. I can't write the code to close the modal window in React. I don't know how this can be done, I need that when clicking on the "Add" button, a modal window opens, the user enters the data, and clicking on the "Add product" button, the window closes immediately
Code:
import React from 'react';
import CatalogProducts from "./CatalogProducts";
import Info from "./Info";
import CreateProduct from "./CreateProduct";
import {Button} from 'react-bootstrap';
import Popup from 'reactjs-popup';
import 'reactjs-popup/dist/index.css';
import '../css/popup.css'
const Main = () => {
return (
<div>
<div className="d-flex justify-content-between" style={{ width: '33rem', margin: '10px' }}>
<Popup contentStyle={{width: "unset", backgroundColor: "red", border: "none", background: "none"}}
trigger={<Button> Add </Button>} modal>
<CreateProduct/>
</Popup>
<input placeholder={'search'}/>
<span>sort by</span>
<input/>
</div>
<CatalogProducts></CatalogProducts>
<Info></Info>
</div>
);
};
export default Main;
import React from 'react';
import {useDispatch} from "react-redux";
import {addProductAction} from "../action/productsAction";
import {ConfigProduct} from "../Utils/configProduct";
import '../css/popup.css'
import '../css/flex.css'
import {Button} from "react-bootstrap";
const CreateProduct = () => {
const dispatch = useDispatch()
const newProduct = new ConfigProduct()
function addProd() {
dispatch(addProductAction(newProduct))
}
return (
<div className = "popup">
<h2 style={{textAlign: "center", color: "red"}}>New product</h2>
<input className="item" placeholder="id" onChange={e => newProduct.idProd = e.target.value}/>
<input className="item" placeholder="info" onChange={e => newProduct.name = e.target.value}/>
<input className="item" placeholder="price" onChange={e => newProduct.infoProd = e.target.value}/>
<input className="item" placeholder="date" onChange={e => newProduct.price = e.target.value}/>
<input className="item" placeholder="enter url" onChange={e => newProduct.date = e.target.value}/>
<p>
<Button onClick={addProd}>Add product</Button>
</p>
</div>
);
};
export default CreateProduct;
I tried setting a flag to change the component class. but it didn't work out for me
In your main.js
[open, setOpen] = useState(false)
const closeModal = () => setOpen(false)
return (
<div>
<div className="d-flex justify-content-between" style={{ width: '33rem', margin: '10px' }}>
<Popup
contentStyle={
{width: "unset", backgroundColor: "red", border: "none", background: "none"}
}
trigger={<Button> Add </Button>}
modal
>
<CreateProduct closeModal={closeModal}/>
</Popup>
<input placeholder={'search'}/>
<span>sort by</span>
<input/>
</div>
<CatalogProducts></CatalogProducts>
<Info></Info>
</div>
)
and inside your CreateProduct.js
const CreateProduct = ({ closeModal }) => {
// your code
function addProd() {
dispatch(addProductAction(newProduct))
closeModal()
}
// rest of your code
)

Component Not Rendering React - Using Older React Router Dom Version

Hey guys using an older version of react-router-dom because I had to for this input form github i forked. Used to using useNavigate but this version is useHistory. I want to go from my main. dashboard to a page called House.js which renders a component MakePost.js. Whenever i travel to House its just a blank white screen. No errors. Help
Here is my Dashboard.js
async function House(){
return(history.push('/House'))
}
return (
<><>
<h2 className="title" style={{ left: "20%", marginTop: -150, marginLeft: 30 }}>Lestinsky Auctions.</h2>
</><>
<Card style={{ width: '400px', height: '500px', alignItems: 'center' }}>
<Card.Body>
<h2 className="text-center mb-4">Profile</h2>
{error && <Alert variant="danger">{error}</Alert>}
<strong>Email:</strong> {currentUser.email}
<Link to="/update-profile" className="btn btn-primary w-100 mt-3">
Update Profile
</Link>
<div>
<Button onClick={House} className="btn btn-primary w-100 mt-3">Go To Auction House</Button>
</div>
</Card.Body>
</Card>
<div style={{ left: '100%' }} className="w-100 text-center mt-2 btn btn-secondary">
<Link className="w-100 text-center mt-2 btn btn-secondary" variant="link" onClick={handleLogout}>
Log Out
</Link>
</div>
</></>
)
Here is my MakePost.js
import React, { useState} from 'react'
import { storage } from '../firebase'
import { ref, uploadBytes } from 'firebase/firebase-storage-compat'
import { v4 } from 'uuid'
function Upload(){
const [imageUpload, setImageUpload] = useState(null)
const uploadImage = () => {
if(imageUpload == null) return;
const imageRef = ref(storage, `images/${imageUpload.name + v4 }`)
uploadBytes(imageRef, imageUpload).then(() => {
alert("Image Uploaded")
})
}
return(
<div>
<input type="file" onChange={(event) => {setImageUpload(event.target.files)}}>
<button onClick={uploadImage}></button>
</input>
</div>
)
}
export default Upload
and here is my House.js
import MakePost from './MakePost'
function House(){
return(
<MakePost></MakePost>
)
}
export default House

Ant Design/antd calendar not working inside a modal

I am trying to use antD's calendar picker inside of a modal that has been created using Material-UI. When I put the datepicker inside of the modal component. It shows me the selection box but when I click on it, nothing opens to choose from. I tried wrapping it in a div as well, but that didn't work. Here's an image of the modal:
Modal code:
import React, { useState,useEffect } from "react";
import { withStyles } from "#material-ui/core/styles";
// import Button from "#material-ui/core/Button";
import Dialog from "#material-ui/core/Dialog";
import MuiDialogTitle from "#material-ui/core/DialogTitle";
import MuiDialogContent from "#material-ui/core/DialogContent";
import MuiDialogActions from "#material-ui/core/DialogActions";
import IconButton from "#material-ui/core/IconButton";
import CloseIcon from "#material-ui/icons/Close";
import Typography from "#material-ui/core/Typography";
import { Link } from "#material-ui/core";
import Table from "../Cards/CardTable";
import moment from "moment";
import CardLineChart from "components/Cards/CardLineChart.js";
import CardLineChart2 from "components/Cards/CardLineChart2.js";
import CardStats from "components/Cards/CardStats.js";
import { DatePicker, Space } from "antd";
const { RangePicker } = DatePicker;
const styles = (theme) => ({
root: {
width: 300,
margin: 0,
padding: theme.spacing(2),
},
closeButton: {
position: "absolute",
right: theme.spacing(1),
top: theme.spacing(1),
color: theme.palette.grey[500],
},
});
const DialogTitle = withStyles(styles)((props) => {
const { children, classes, onClose, ...other } = props;
return (
<MuiDialogTitle disableTypography className={classes.root} {...other}>
<Typography variant="h6">{children}</Typography>
{onClose ? (
<IconButton
aria-label="close"
className={classes.closeButton}
onClick={onClose}
>
<CloseIcon />
</IconButton>
) : null}
</MuiDialogTitle>
);
});
const DialogContent = withStyles((theme) => ({
root: {
// width: 200,
padding: theme.spacing(2),
},
}))(MuiDialogContent);
const DialogActions = withStyles((theme) => ({
root: {
margin: 0,
padding: theme.spacing(1),
},
}))(MuiDialogActions);
export default function CustomizedDialogs(props) {
const { name } = props;
console.log("Name is ======>", name)
const [open, setOpen] = useState(false);
const [colors, setColors] = useState(false);
const [deviceMsgs,setDeviceMsgs] = useState(null)
const [start, setStart] = useState();
const [end, setEnd] = useState();
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const onChange = (dates, dateStrings) => {
if (dateStrings.length > 0) {
setStart(dateStrings[0]);
setEnd(dateStrings[1]);
}
};
const DPicker = () => {
return (
<div>
<Space direction="vertical" size={12}>
<RangePicker
ranges={{
Today: [moment(), moment()],
"This Month": [
moment().startOf("month"),
moment().endOf("month"),
],
}}
onChange={onChange}
/>
</Space>
</div>
);
};
return (
<div>
<Link variant="outlined" color="primary" onClick={handleClickOpen}>
{name}
</Link>
<Dialog
maxWidth={"xl"}
// style={{ width: "100%" }}
onClose={handleClose}
aria-labelledby="customized-dialog-title"
open={open}
>
<DialogTitle
style={{ backgroundColor: colors ? "green" : "red" }}
id="customized-dialog-title"
onClose={handleClose}
>
{name}
</DialogTitle>
<DialogContent dividers>
<div>
<DPicker /> //////// Using the picker
<div className="relative w-full pr-4 max-w-full flex-grow flex-1">
<span className="font-semibold text-xl text-blueGray-700">
Last Update : 21 April 2021 17:00:00
</span>
</div>
<div className="m-4 px-4 md:px-10 mx-auto w-full">
<div>
{/* Card stats */}
<div className="flex flex-wrap">
<div className="w-full lg:w-6/12 xl:w-3/12 px-4">
<CardStats
statSubtitle="Total"
statTitle="10"
statArrow="up"
statPercent="3.48"
statPercentColor="text-emerald-500"
statDescripiron="Since last month"
statIconName="fas fa-percent"
statIconColor="bg-lightBlue-500"
/>
</div>
<div className="w-full lg:w-6/12 xl:w-3/12 px-4">
<CardStats
statSubtitle="ACTIVE"
statTitle="6"
statArrow="down"
statPercent="3.48"
statPercentColor="text-red-500"
statDescripiron="Since last week"
statIconName="fas fa-users"
statIconColor="bg-pink-500"
/>
</div>
<div className="w-full lg:w-6/12 xl:w-3/12 px-4">
<CardStats
statSubtitle="INACTIVE"
statTitle="4"
statArrow="down"
statPercent="1.10"
statPercentColor="text-orange-500"
statDescripiron="Since yesterday"
statIconName="far fa-chart-bar"
statIconColor="bg-red-500"
/>
</div>
<div className="w-full lg:w-6/12 xl:w-3/12 px-4">
<CardStats
statSubtitle="ALERT"
statTitle="--"
statArrow="up"
statPercent="12"
statPercentColor="text-emerald-500"
statDescripiron="Since last month"
statIconName="fas fa-chart-pie"
statIconColor="bg-orange-500"
/>
</div>
</div>
</div>
</div>
</Dialog>
</div>
);
}
Obviously, you should check my solution because it is just my assumption of your problem, but anyway it seems that it can help you:
<DatePicker
getPopupContainer={(triggerNode) => {
return triggerNode.parentNode;
}}
/>
By default, popup container is located nearby body but you can change it to your modal element. The my solution above covers that
I found a solution to the problem and it is straightforward.
after tinkering in the dev-tools, I found out that the Z-index of the antd Modal is set to 1055.
A simple override to the date-picker Z-index fixes the issue : I set it to 1056.
Its className is : ".ant-picker-dropdown"
.ant-picker-dropdown{
z-index: 1056;
}
solves the issue.
This will work.
Go to Node Module > antd > dist > antd.compact.css > change the z-index of elements accordingly.

How to lock the position of close button with paper component of modal in material ui for responsive screen?

I had built a cards page where I'm rendering multiple cards on a page. On clicking each card a popup card renders aka modal component but my close button is not responsive to the card.
Here is an image. See the button is going the wrong position when I open it to inspect.
Here is my link to complete code at codesandbox.
imagePopup.js modal component with close button
import React from "react";
import { makeStyles } from "#material-ui/core";
import Modal from "#material-ui/core/Modal";
import Backdrop from "#material-ui/core/Backdrop";
import Fade from "#material-ui/core/Fade";
import ActionButton from "./ActionButton";
import { CloseOutlined } from "#material-ui/icons";
const useStyles = makeStyles((theme) => ({
modal: {
display: "flex",
alignItems: "center",
justifyContent: "center"
},
paper: {
backgroundColor: theme.palette.background.paper,
boxShadow: theme.shadows[5]
},
actionBtn: {
position: "absolute",
right: 555,
top: 85
}
}));
export default function ImagePopup(props) {
const classes = useStyles();
const { openModal, setOpenModal, handleOpen, handleClose, img } = props;
return (
<div>
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
className={classes.modal}
open={openModal}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500
}}
>
<Fade in={openModal}>
<div>
<div className={classes.actionBtn}>
<ActionButton
// to edit icon functionality
color="secondary"
onClick={handleClose}
>
<CloseOutlined fontSize="small" />
</ActionButton>
</div>
<div className={classes.paper}>
<img src={img} height="500" />
</div>
</div>
</Fade>
</Modal>
</div>
);
}
Adjust your actionBtn bloc style like this:
actionBtn: {
position: "absolute",
marginLeft: 352,
marginTop: -5,
borderRadius: 0,
'& > button': {
background: "transparent" // If you want button to be transparent
}
}

React: Preview content while typing

I have a simple list where I'm adding media content.
I'm using Embed to display the media contents.
When I want to enter a media link suck as Youtube/twitter .., I want to be able to preview it after pasting it and before clicking on Add.
I tried to add an onChange but didn't work. How to do so ?
https://codesandbox.io/s/vigorous-greider-seycx?file=/src/App.js:0-1201
import React, { useState } from "react";
import Embed from "react-embed";
export default () => {
const reactList = [
{
id: "2",
title: "Twitter",
media: "https://twitter.com/Betclic/status/1382074820628783116?s=20"
}
];
const [links, setLinks] = useState(reactList);
const [media, setMedia] = React.useState("");
function handleChange(event) {
setMedia(event.target.value);
}
function handleAdd() {
const newList = links.concat({ media });
setLinks(newList);
}
return (
<div>
<div>
<input type="text" value={media} onChange={handleChange} />
<div
style={{ height: "250px", width: "500px", border: "3px solid black" }}
>
Preview
<Embed url={media} onChange={handleChange} />
</div>
<button type="button" onClick={handleAdd}>
Add
</button>
</div>
<ul>
<div style={{ width: "50vh" }}>
{links.reverse().map((url, indexurl) => (
<li key={url.id}>
<div>{url.title}</div>
<Embed url={url.media} />
</li>
))}
</div>
</ul>
</div>
);
};
I think I have to set an automatic refresh for the component, because when I set the link in a modal, after closing and reopening the modal, it works. What do you think?

Categories