using a Popconfirm from antd to confirm the closing of a modal? - reactjs

I am trying to use a popconfirm of ant design to confirm the closing of a modal, the following code I get the popconfirm to fire and the modal to close, but the popconfirm stays open.
does anyone have any idea how to make the popconfirm close when it is confirmed by giving it yes ?
import { Modal, Popconfirm } from 'antd';
import { useState } from 'react';
export const Ensayo=()=> {
const [open, setOpen] = useState(false);
const [popupOpen, setPopupOpen] = useState(false);
const showModal = () => {
setOpen(true);
};
const handleCancel = () => {
setPopupOpen(true);
};
const handlePopupConfirm = () => {
setOpen(false);
setPopupOpen(false);
};
const handlePopupCancel = () => {
setPopupOpen(false);
};
return (
<div>
<button type="button" onClick={showModal}>
Open Modal
</button>
<Modal
title="Basic Modal"
open={open}
onCancel={handleCancel}
>
<p>Some contents...</p>
<Popconfirm
title="Are you sure you want to close this modal?"
open={popupOpen}
onConfirm={handlePopupConfirm}
onCancel={handlePopupCancel}
okText="Yes"
cancelText="No"
/>
</Modal>
</div>
);
}
I have tried to add the popupOpen condition as a condition for the popconfirm rendering but it doesn't work with that condition it never triggers the popconfirm.

You can move the <Popconfirm> component outside the <Modal>
check the following example
import { Modal, Popconfirm } from "antd";
import { useState } from "react";
export const Ensayo = () => {
const [open, setOpen] = useState(false);
const [popupOpen, setPopupOpen] = useState(false);
const showModal = () => {
setOpen(true);
};
const handleCancel = () => {
setPopupOpen(true);
};
const handlePopupConfirm = () => {
setOpen(false);
setPopupOpen(false);
};
const handlePopupCancel = () => {
setPopupOpen(false);
};
return (
<div>
/* Popconfirm moved here */
<Popconfirm
title="Are you sure you want to close this modal?"
open={popupOpen}
onConfirm={handlePopupConfirm}
onCancel={handlePopupCancel}
okText="Yes"
cancelText="No"
/>
<button type="button" onClick={showModal}>
Open Modal
</button>
<Modal title="Basic Modal" open={open} onCancel={handleCancel}>
<p>Some contents...</p>
</Modal>
</div>
);
};
export default Ensayo;
Output:

Related

Why the div doesn't close?

I am trying when I click outside the div to close the div. Here is my code :
import { useRef, useState } from "react";
import "./styles.css";
const App = () => {
const [showModal, setShowModal] = useState(false);
const noderef = useRef(null);
const handleClick = () => {
console.log(showModal);
if (!showModal) {
console.log("test1");
document.addEventListener("click", handleOutsideClick, true);
} else {
console.log("test2");
document.removeEventListener("click", handleOutsideClick, true);
}
setShowModal(!showModal);
};
const handleOutsideClick = (e) => {
if (!noderef.current.contains(e.target)) handleClick();
};
return (
<div ref={noderef}>
<button onClick={() => handleClick()}>Open Modal</button>
{showModal ? (
<div className="modal">
I'm a modal!
<button onClick={() => handleClick()}>close modal</button>
</div>
) : null}
</div>
);
};
export default App;
When I click on Open Modal it works also when I click on close modal. But when I click outside the div the div is still opened.
How can I do to fix that, it looks it is like there are two clicks
Here is the full project : My project

Ant Design: prevent closing modal conditionally when onOk is called

I'm using Ant Design v4.22.4 and use Model through useModal.
I want to keep the modal open conditionally when onOk function is called (when ok button is clicked`. Is there way to prevent closing the modal?
Yes you can do this, onOK function expects a function that changes the visibility state, here is a sample code:
import { Button, Modal } from 'antd';
import React, { useState } from 'react';
const App = () => {
const [isModalVisible, setIsModalVisible] = useState(false);
const showModal = () => {
setIsModalVisible(true);
};
const handleOk = () => {
setIsModalVisible(true);
};
const handleCancel = () => {
setIsModalVisible(false);
};
return (
<>
<Button type="primary" onClick={showModal}>
Open Modal
</Button>
<Modal title="Basic Modal" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
</>
);
};
export default App;
With this, whenever the user clicks on the OK button, the modal still remains visible.

How to resize width of Ant Design modal based on different screen sizes?

I just want the max width of the modal to be 1200px and then 100% width if screen width is less than 1200px. Ive tried using style={{maxWidth: "1200px"}} but that doesn't work and there is no explanation of how to do this in the Ant Design docs. Any help is appreciated!
import React, { useState } from 'react';
import { Modal, Button } from 'antd';
const App = () => {
const [isModalVisible, setIsModalVisible] = useState(false);
const showModal = () => {
setIsModalVisible(true);
};
const handleOk = () => {
setIsModalVisible(false);
};
const handleCancel = () => {
setIsModalVisible(false);
};
return (
<>
<Button type="primary" onClick={showModal}>
Open Modal
</Button>
<Modal
style={{maxWidth: "1200px"}}
title="Basic Modal"
visible={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
</>
);
};
ReactDOM.render(<App />, mountNode);
Add this code and use maxModalSize value
const [maxModalSize, setMaxModalSize] = useState(1200);
const resize = () => {
const maxSize = Math.min(1200, window.innerWidth);
setMaxModalSize(maxSize);
};
useEffect(() => {
window.addEventlistener("resize", resize);
return () => window.removeEventlistener("resize", resize);
});

Trying to get Material ui dialog into contextualised modal

I have a modal component which I have put into context.
If I return html , some divs etc, then no problem, but
ideally I want to do this with the material-ui dialog.
But if I put in materail-ui dialog, as below,
then nothing is displayed.
The component:
import React, { useCallback, useEffect, useState } from 'react'
import {Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle} from "#material-ui/core";
import {useTranslation} from "react-i18next";
import {errorStyles} from "../errorStyle";
// Create a React context
const ModalContext = React.createContext(null);
//Declare the modal component
const Modal = ({ modal, unSetModal, errorClasses = errorStyles(),
title, subtitle, children, }) => {
useEffect(() => {
const bind = e => {
if (e.keyCode !== 27) {
return
}
if (document.activeElement && ['INPUT', 'SELECT'].includes(document.activeElement.tagName)) {
return
}
unSetModal()
}
document.addEventListener('keyup', bind)
return () => document.removeEventListener('keyup', bind)
}, [modal, unSetModal])
const { t } = useTranslation()
return (
<>
<Dialog
className={errorClasses.modal}
fullWidth
maxWidth='md'
aria-labelledby='max-width-dialog-title'
>
<DialogTitle id='max-width-dialog-title'
className={errorClasses.header}>{title}</DialogTitle>
<DialogContent>
<DialogContentText>{subtitle}</DialogContentText>
</DialogContent>
<DialogActions>
<button className={errorClasses.cancelButton}
onClick={unSetModal}>{t("Close")}</button>
</DialogActions>
</Dialog>
</>
)
}
const ModalProvider = props => {
const [modal, setModal] = useState()
const unSetModal = useCallback(() => {
setModal('')
}, [setModal])
return (
<ModalContext.Provider value={{ unSetModal, setModal }} {...props} >
{props.children}
{modal && <Modal modal={modal} unSetModal={unSetModal} />}
</ModalContext.Provider>
)
}
// useModal: shows and hides the Modal
const useModal = () => {
const context = React.useContext(ModalContext)
if (context === undefined) {
throw new Error('useModal must be used within a UserProvider')
}
return context
}
export { ModalProvider, useModal }
And in another component (an edit form)
import { useModal, ModalProvider } from '../context/modal-context'
.....
export function DeviceModal (props) {
const { setModal } = useModal()
...
some other markup
<div style={{ position: 'sticky', bottom:'0', width:'100%', height:'40px', paddingTop:'5px'}}>
<Grid container direction="row-reverse" item xs={12} alignItems="right">
<button className={classes.cancelButton}
onClick={() => { setModal(<></>)}} >
{'Cancel'}
</button>
</Grid>
</div>
Hope someone can help
Thanks
Answer:
By adding the following to the dialogprops, it is resolved.
open={true}
backdropComponent={Backdrop}
and also, getting it to display values from the parent.
const ModalProvider = props => {
const [modal, setModal] = useState();
const [title, setTitle] = useState();
const [errMsg, setErrMsg] = useState();
const unSetModal = useCallback(() => {
setModal('')
}, [setModal])
// Provide the Modals functions and state variables to the consuming parent component
return (
<ModalContext.Provider value={{ unSetModal, setModal, setTitle, setErrMsg }} {...props} >
{props.children}
{modal && <Modal modal={modal} unSetModal={unSetModal} title={title} errMsg={errMsg} />}
</ModalContext.Provider>
)}
In the parent use setTitle("yada yada") setErrMsg('more yerra yada");

In reactjs modal close button is not working

I am use bootstrap modal in reactjs project. Here is the link of package which i have installed in my project: https://www.npmjs.com/package/react-responsive-modal
When, I click on open the modal button then it is working, but when i click on close button then close button is not working. I am using the hooks in my project. Below, I have mentioned my code:
import React, { useState } from 'react'
import Modal from 'react-responsive-modal'
const Login = () => {
const [open, openModal] = useState(false)
const onOpenModal = () => {
openModal({open: true})
};
const onCloseModal = () => {
openModal({open: false})
};
return(
<div>
<h1>Login Form</h1>
<button onClick={onOpenModal}>Open modal</button>
<Modal open={open} onClose={onCloseModal} center>
<h2>Simple centered modal</h2>
</Modal>
</div>
)
}
export default Login;
The issue is because, you are setting object in state,
openModal({open: true})
This will store object in state.
setState require's direct value which needs to be change, your setState must be this,
const onOpenModal = () => {
openModal(!open) //This will negate the previous state
};
const onCloseModal = () => {
openModal(!open) //This will negate the previous state
};
Demo
You can simplify your code and just use 1 change handle for your modal,
const Login = () => {
const [open, openModal] = useState(false)
const toggleModal = () => {
openModal(!open)
};
return(
<div>
<h1>Login Form</h1>
<button onClick={toggleModal}>Open modal</button>
<Modal open={open} onClose={toggleModal} center>
<h2>Simple centered modal</h2>
</Modal>
</div>
)
}
Demo
Your naming of the model hook is misleading and you're using the setState part of the Hook wrong, probably mixing it up with the this.setState convention for non-Hook React code.
import React, { useState } from 'react'
import Modal from 'react-responsive-modal'
const Login = () => {
const [modalOpen, setModalOpen] = useState(false)
const onOpenModal = () => {
setModalOpen(true)
};
const onCloseModal = () => {
setModalOpen(false)
};
return(
<div>
<h1>Login Form</h1>
<button onClick={onOpenModal}>Open modal</button>
<Modal open={modalOpen} onClose={onCloseModal} center>
<h2>Simple centered modal</h2>
</Modal>
</div>
)
}
export default Login;

Resources