When clicking on modal window body, it runs outer div's onClick handler. event.stoppropagation() working fine for button inside outer div and buttons inside modal but don't know how to unbind outer div click handler on modal body.
sample code (Modal is not working on csb, please run on your code editor)
import React, { useState } from "react";
import { Button, Modal } from "react-bootstrap";
export default function App() {
const [show, setShow] = useState(false);
const handleShow = (event) => {
event.stopPropagation();
setShow(true);
};
const handleClose = (event) => {
event.stopPropagation();
setShow(false);
};
const deleteModal = () => {
return (
<Modal
id="deleteModal"
className="modal"
show={show}
onHide={handleClose}
centered
size="sm"
backdrop="static"
keyboard={false}
>
<Modal.Body>
<div>
<span>Delete Tweet ?</span>
</div>
<div>This can’t be undone</div>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Cancel
</Button>
<Button variant="primary">Delete</Button>
</Modal.Footer>
</Modal>
);
};
const postHandler = () => {
alert("clicked on div");
};
return (
<div onClick={postHandler} style={{ border: "1px solid" }}>
{deleteModal()}
<h1>Hello CodeSandbox</h1>
<Button variant="info" onClick={handleShow}>
Delete
</Button>
</div>
);
}
P.S- I'm using react-bootstrap for creating modal.
return (
<>
{show && deleteModal()} // just move this logic outside the div
<div onClick={postHandler} style={{ border: '1px solid' }}>
<h1>Hello CodeSandbox</h1>
<Button variant="info" onClick={handleShow}>
Delete
</Button>
</div>
</>
);
Hey, if you just move the deleteModal outside the div then it would solve your problem.
Related
i have created a antd modal and i want to change modal body color to red here is my code,had applied background color but it is not showing also i want to align image and modalName in a row using flex, i have intalled antd version 4.2, and i am using styled components. dont know whats wrong.please help,and thanks in advance.
modal.js
import React , {useState} from "react";
import { Modal ,Button} from "antd";
import styled from "styled-components";
import "antd/dist/antd.css";
const Modall = () => {
const [isModalVisible, setIsModalVisible] = useState(false);
const showModal = () => {
setIsModalVisible(true);
}
const handleOk = () => {
setIsModalVisible(false);
}
const handleCancel = () => {
setIsModalVisible(false);
}
return (
<Wrapper>
<div className="head">hello</div>
<Button type="primary" onClick={showModal}>
Open Modal
</Button>
<Modal
title="Basic Modal"
open={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
>
<div className="modalName">hello</div>
<div className="modalHead">
<img src='simple.svg' className="newStyle"></img>
<div className="modalName" >beautiful</div>
/div>
</Modal>
</Wrapper>
);
}
export default Modall;
const Wrapper = styled.div`
.ant-modal, .ant-modal-content .ant-modal-body .modalHead{
display:flex;
}
.ant-modal, .ant-modal-content .ant-modal-body{
background:red;
}
`
not sure but i think you need to add 'bodyStyle' in your modal to add a background to your modal , kinda like this
<Modal
title="Basic Modal"
open={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
bodyStyle={{
backgroundColor: "red"
}}
>
you should put Wrapper in modal body, try this:
return (
<>
<div className="head">hello</div>
<Button type="primary" onClick={showModal}>
Open Modal
</Button>
<Modal
title="Basic Modal"
open={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
className="modalStyle"
>
<Wrapper><div className="modalName">hello</div></Wrapper>
</Modal>
</>
);
const Wrapper = styled.div`
background:red;
`
https://codesandbox.io/s/determined-chatelet-es5big?file=/src/App.js
In my react Project, I want a modal to popup when the input field is in the hover state. I'm using the react-bootstrap modal. But the problem I'm having is that it's only the modal button that displays when the input is in the focus state. The modal should pop up automatically when the input is being focused. My code below. Kindly assist
App Component
import React, { useState, useEffect } from "react";
import stays from "./Components/stays.json";
import FancyModalButton from "./Components/FancyModalButton";
export default function SearchGuest() {
const [Data, setData] = useState([]);
const [filteredData, setFilteredData] = useState(Data);
const [hasFocus, setFocus] = useState(false);
useEffect(() => {
setData(stays);
setFilteredData(stays);
}, []);
return (
<>
<form action="">
{hasFocus ? <FancyModalButton /> : null}
<input
onFocus={() => setFocus(true)}
onBlur={() => setFocus(false)}
type="text"
name="guest"
placeholder="text"
style={{ border: "1px solid yellow" }}
/>
<input type="number" name="location" placeholder="number" />
<button>Search</button>
</form>
{console.log(filteredData)}
</>
);
}
Modal Component
import React, { useState } from "react";
// import Modal from "styled-react-modal";
import { Button, Modal } from "react-bootstrap";
export default function FancyModalButton() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Button variant="primary" onClick={handleShow}>
Modal
</Button>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleClose}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
</>
);
}
The Image of What I have
This is a continuation from my previous post Rendering Modal Popup
After editing my code, I was able to launch my modal pop-up but had issues having it styled the same way as in the tutorial.
This is the desired styling that I pulled from a React-Boostrap tutorial
https://react-bootstrap.github.io/components/modal/
After running the same code as in the tutorial, this was my output. It's styled in plain HTML.
This is my import statement which I've used to import dependencies from the tutorial
import { Button, Modal } from 'react-bootstrap';
Updated code which successfully launched my modal pop-up
const Example = ({ show, onClose, onSave }) => (
<Modal show={show} onHide={onClose}>
<Modal.Header closeButton>
<Modal.Title>Modal heading</Modal.Title>
</Modal.Header>
<Modal.Body>Woohoo, you're reading this text in a modal!</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={onClose}>
Close
</Button>
<Button variant="primary" onClick={onSave}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
)
const addToCart = () => {
Axios.post(process.env.REACT_APP_BACKEND_API + "/cart/",)
.then((res) => {
setShowExample(true);
})
.catch((err) => {
if (err.response && err.response.status === 401) {
setIsLoggedIn(false);
}
});
};
<div className="field is-grouped">
<div className="control">
<button className="button is-primary" onClick={addToCart}>
ADD TO CART
</button>
<Example //added
show={showExample}
onClose={() => setShowExample(false)}
onSave={() => setShowExample(false)}
/>
</div>
So I have just added a Modal from react-Modal to a page through a button click, the problem I am facing is when i click that button to make the modal pop up, it does but the content of the page the modal covers seeps through, so the Modal looks like this.
The table etc shouldn't be there, only a blank white screen.
Can anyone help me please?
Below is the first class where I click to show the modal.
const [showModal, setShowModal] = useState(false)
<button onClick={() => { setShowModal(true) }} className="paddingNextButton float-right viewButtonHover btn btn-md btn-outline-secondary"> Next</button>
<ModalForm isModalOpen={showModal} closeModal={() => { setShowModal(false) }} />
Below is another class of the Modal itself.
import React from 'react'
import Modal from 'react-modal'
import { Overlay } from 'react-bootstrap'
Modal.setAppElement('#root')
function ModalForm({ isModalOpen, closeModal }) {
return (
<div>
<Modal isOpen={isModalOpen} onRequestClose={closeModal}
style={
{
overlay: {
backgroundColor: "grey"
},
content: {
color: "red"
}
}
}
>
<h1>Title</h1>
<p></p>
</Modal>
</div>
)
}
export default ModalForm
Ah, I see the problem now. You don't have a Modal.Body, or a Modal.Header for that matter. What you need should be something like this:
<Modal isOpen={isModalOpen} onRequestClose={closeModal} style={{...}}>
<Modal.Header closeButton>
<Modal.Title>
Title
</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>Modal body goes here</p>
</Modal.Body>
</Modal>
So I have a start page that gives options to open a login modal or sign up modal. However, once you are in the login modal I give an option so you can switch to sign up modal. However, I can't seem to get this to work. The one time I got it to work, the modal showed up in the wrong section of the screen since it was being opened in relation to the login modal and not the start page.
I am new to React so any insight would be appreciated. Should I use redux, since I can't pass props from child to parent. So that way when I return to start page I can rerender with info saying that I had clicked sign-up link on the login modal.
function LoginContent(props) {
const [ open, setOpen ] = useState(false)
const { show, closeModal } = props;
function handleSubmit(e){
e.preventDefault();
}
function handleSignUpButton(){
closeModal();
console.log(open)
setOpen(!false)
console.log(open)
}
//added so that the component doesn't get affected by parent css
//and is being rendered from the "modal-root" DOM node from the index.html file
return ReactDOM.createPortal(
<>
<div className={show ? "overlay" : "hide"} onClick={closeModal} />
<div className={show ? "modal" : "hide"}>
<button onClick={closeModal} id="close">X</button>
<div className="login_form">
<h1> Log in to Continue </h1>
<form onSubmit={handleSubmit}>
<input className="username" type='text' name='username' placeholder='Email Address' />
<input className="password" type='password' name='password' placeholder='password' />
<button className="login_button"> Sign In</button>
</form>
</div>
<div className="login_demo">
<h3 className="login_demo_pointer" type="submit">Demo Login</h3>
</div>
<hr />
<div className="login_switch">Don't have an account.
<button className="signup_link" onClick={handleSignUpButton}>Sign Up</button>
{open && <SignUpContent open={open} closeModal={closeModal} show={show} />} </div>
</div>
</>, document.getElementById("modal-root")
);
}
function Start() {
const history = useHistory();
const [showLogin, setLogin ] = useState(false);
const openModalLogin = () => setLogin(true);
const closeModalLogin = () => setLogin(false);
const [showSignUp, setShow ] = useState(false);
const openModalSignUp = () => setShow(true);
const closeModalSignUp = () => setShow(false);
return (
<div className="bodyStart">
<img src="https://i.imgur.com/5gjRSmB.gif" alt="" id="bg" />
<div className="start_logo">
<img src={require("../styling/logo.png")} alt="" onClick={() => {
history.push('/home')
history.go(0)}} className="logo" />
</div>
<div className="start">
<div className="start_heading">
<h2>Mother Nature is Calling.</h2>
<h4>Find a place to recharge and escape the day to day.</h4>
</div>
<div className="start_location">
<p>Where?</p>
<div className="start_input">
<input type="text" placeholder="anywhere" />
<ArrowForwardIcon onClick={() => {
history.push('/search')
history.go(0)}}
className="arrow" fontSize="large"/>
</div>
</div>
<div className="start_authentication">
<Button className="login"
variant="contained"
color="primary"
size="large"
onClick={() => openModalLogin()}> Login </Button>
{showLogin && <LoginContent closeModal={closeModalLogin} show={showLogin} />}
<Button className="signup"
variant="contained"
size="large"
onClick={()=> openModalSignUp()}> Sign-Up </Button>
{showSignUp && <SignUpContent closeModal={closeModalSignUp} show={showSignUp} />}
</div>
</div>
</div>
)
}
I have made similar modals with Material-UI. You can change loginOpen state and signupOpen states in modals. See codepen below
Codepen
const { useState } = React;
const { Button, Dialog, DialogTitle, DialogContent, DialogActions } = MaterialUI;
function LoginDialog(props) {
const { open, setLoginOpen, setSignupOpen } = props;
const switchSignup = (event) => {
setLoginOpen(false)
setSignupOpen(true)
}
return (
<Dialog aria-labelledby="simple-dialog-title" open={open}>
<DialogTitle id="simple-dialog-title">LOGIN</DialogTitle>
<DialogContent>If you don't have an account, press SIGNUP</DialogContent>
<DialogActions>
<Button onClick={(event) => {setLoginOpen(false)}}>CLOSE</Button>
<Button>LOGIN</Button>
<Button onClick={switchSignup}>SIGNUP</Button>
</DialogActions>
</Dialog>
);
}
function SignupDialog(props) {
const { open, setLoginOpen, setSignupOpen } = props;
const switchLogin = (event) => {
setSignupOpen(false)
setLoginOpen(true)
}
return (
<Dialog aria-labelledby="simple-dialog-title" open={open}>
<DialogTitle id="simple-dialog-title">SIGNUP</DialogTitle>
<DialogContent>If you have an account, press LOGIN</DialogContent>
<DialogActions>
<Button onClick={(event) => {setSignupOpen(false)}}>CLOSE</Button>
<Button>SIGNUP</Button>
<Button onClick={switchLogin}>LOGIN</Button>
</DialogActions>
</Dialog>
);
}
const App = () => {
const [loginOpen, setLoginOpen] = useState(false)
const [signupOpen, setSignupOpen] = useState(false)
const handleLogin = (event) => {
setLoginOpen(true)
}
const handleSignup = (event) => {
setSignupOpen(true)
}
return (
<div>
<Button variant='contained' color='primary' onClick={handleLogin} >
LOGIN
</Button>
<Button variant='outlined' color='primary' onClick={handleSignup} >
SIGNUP
</Button>
<LoginDialog open={loginOpen} setLoginOpen={setLoginOpen} setSignupOpen={setSignupOpen} />
<SignupDialog open={signupOpen} setLoginOpen={setLoginOpen} setSignupOpen={setSignupOpen} />
</div>
)
}
ReactDOM.render(<App />, document.getElementById("root"));