How to pass a value to a modal - javascript

For example, i have this functon that returns to me some ids and i get delete this posts with the id's returned with: onClick={() => { Delete(idvalue[i]) }}
However I need to open a modal before deleting the item asking if the person is sure they want to delete, and when they click on the yes I have no idea how to pass the right value to delete and where will stay this onClick to open the modal.
function Idchecker() {
for (let i = 0; i < idvalue.length; i++) {
if (idvalue[i] == item.id) {
return (
<div className="img-array">
<button className="click-img" onClick={() => { Delete(idvalue[i]) }}>
<img src={trash} alt="botão excluir" className="imgsbtns" />
</button>
<button className="click-img">
<img src={edit} alt="botão editar" className="imgsbtns" />
</button>
</div>
)
}
}
}
the modal:
return (
<Modal
{...props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
style={{ fontFamily: "Questrial" }}
>
<Modal.Header>
<Modal.Title id="contained-modal-title-vcenter">
DELETE THE POST
</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>
are you sure?
</p>
<Button onClick={Delete}>YES</Button>
</Modal.Body>
<Modal.Footer>
<Button onClick={props.onHide}>CLOSE</Button>
</Modal.Footer>
</Modal>
);
}

Add two state:
openDeleteModal to manage opening modal (argument for example, you have this argument yet)
deleteId to store id.
const [openDeleteModal, setOpenDeleteModal] = useState(false);
const [deleteId, setDeleteId] = useState(null);
When you click on post you must open modal and update deleteId, so rewrite onClick function:
onClick={()=>{
setDeleteId(idvalue[i]);
setOpenDeleteModal(true)}
}
Pass deleteId and setOpenModal via props to Modal component and rewrite modal buttons function:
<Modal.Body>
<p>
are you sure?
</p>
<Button
onClick={()=>{
Delete(deleteId)
setOpenDeleteModal(false) //close modal after delete
}}>
YES
</Button>
</Modal.Body>
<Modal.Footer>
<Button onClick={()=>setOpenDeleteModal(false)}>CLOSE</Button>
</Modal.Footer>

Related

React use a form in a modal to pass the inputted data to a function

I am using react-bootstrap/Modal and react-hook-form. I want the user to insert data in the input which after submitting will go to the function where I want to make an object with it.
<form onSubmit={handleSubmit(update)}>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Edit</Modal.Title>
</Modal.Header>
<Modal.Body>
<label>Description</label>
<input name="message" type="text" ref={register} placeholder="description"/>
</Modal.Body>
<Modal.Footer>
<button variant="secondary" onClick={handleClose}>
Cancel
</button>
<button type="submit" variant="primary" onClick={update}>
Edit
</button>
</Modal.Footer>
</Modal>
</form>
//I will need the async function later to await an api call.
const update = (data) => {
(async () => {
console.log("data", data)
})()
}
Thanks for helping!
EDIT:
I found the solution, I had to put the form in the modal but outside the modal components.
<Modal show={show} onHide={handleClose}>
<form onSubmit={handleSubmit(update)}>
<Modal.Header closeButton>
<Modal.Title>Edit</Modal.Title>
</Modal.Header>
<Modal.Body>
<label>Description</label>
<input name="message" type="text" placeholder="description" />
</Modal.Body>
<Modal.Footer>
<button variant="secondary" onClick={handleClose}>
Cancel
</button>
<button type="submit" variant="primary" onClick={update}>
Edit
</button>
</Modal.Footer>
</form>
</Modal>
Since you are using the react-hook-forms, simply can get the result after form submission.
The result object looks like this in your case:
{message: "some message data"}
So, you need to get the "message" property of data parameter on update function.
Note: you pass message as the name property of your input element so the data.message will give you the corresponding data on input element which is controlled by react-hook-forms
const update = (data) => {
(async () => {
console.log("data", data.message)
})()
}

Bootstrap React Modal Component not working dynamically

I am using React Bootstrap, I am using map function of javascript to loop through admins, when i loop through them all values outside the modal display the correct values from the admins array, but inside the modal it shows only one standard object from the array everytime. The id of that component is different outside the modal and inside the modal, the modal inside displays only the user with id 1 in every component or every time the modal is clicked
admins = [ {id: 5, email: "angelinsneha#gmail.com", name: "angelin", role: "admin"},
{id: 4, email: "angelinsneha14#gmail.com", name: "angu", role: "admin"},
{id: 1, email: "angelin#gmail.com", name: "aanjuu", role: "admin"}]
<div className="rgtss pb-5">
{admins.length > 0
? admins.map((i) => (
<div className="bdr">
<div>
<p>{i.name} {i.id}</p>
<span>{i.email}</span>
</div>
<div className="mt-3">
<p>{i.role}</p>
</div>
<div>
<DropdownButton
id="dropdown-basic-button"
variant="dark"
title=""
size="sm"
>
<Dropdown.Item href={id == i.id ? "/profile" : ""}>
Edit
</Dropdown.Item>
{4 == i.id ? (
""
) : (
<Dropdown.Item onClick={handleShow}>Delete {i.id}</Dropdown.Item>
)}
</DropdownButton>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Delete Account {i.id}</Modal.Title> // only id 1 is displayed in modal, everytime the loop runs
</Modal.Header>
<Modal.Body>
Are you sure you want to delete this team account:{" "}
<b>{i.name}</b>?
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button
variant="danger"
onClick={() => handledelete(i.id)}
>
Delete
</Button>
</Modal.Footer>
</Modal>
</div>
</div>
))
: ""}
</div>
I have no idea why this is happening, can you'll help me?
You're creating modals in a loop (in this case, 3), which is not best practice for this very problem. You'd expect that each modal has the right props depending on the item of the array, but then how does the code know which modal to display ?
Your <Modal> should be outside the loop. Store a variable to know which admin to display when the modal is brought up. (It could be the index in the array, or adding a selected boolean to the admin).
When you trigger your handleShow, set this variable as well (don't forget to unset it when you're done, to prevent side-effects)
You should also use === instead of == unless it's really intended (see this SO post for more info)
EDIT: In code, it should look like this (don't copy/paste, it is untested)
const MyComponent = () => {
const [adminSelected, setAdminSelected] = useState(-1);
return (
<div className="rgtss pb-5">
{admins.length > 0
? admins.map((i, idx) => (
<div className="bdr">
<div>
<p>
{i.name} {i.id}
</p>
<span>{i.email}</span>
</div>
<div className="mt-3">
<p>{i.role}</p>
</div>
<div>
<DropdownButton
id="dropdown-basic-button"
variant="dark"
title=""
size="sm"
>
<Dropdown.Item href={id === i.id ? '/profile' : ''}>
Edit
</Dropdown.Item>
{4 === i.id ? (
''
) : (
<Dropdown.Item onClick={() => {
setAdminSelected(idx);
handleShow();}}>
Delete {i.id}
</Dropdown.Item>
)}
</DropdownButton>
</div>
</div>
))
: ''}
<Modal show={show} onHide={() => {
setAdminSelected(-1);
handleClose();}}>
<Modal.Header closeButton>
<Modal.Title>Delete Account {i.id}</Modal.Title> // only id 1 is
displayed in modal, everytime the loop runs
</Modal.Header>
<Modal.Body>
Are you sure you want to delete this team account: <b>{i.name}</b>?
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="danger" onClick={() => handledelete(i.id)}>
Delete
</Button>
</Modal.Footer>
</Modal>
</div>
);
};
Note that I added the idx variable in mapping to know which admin has been clicked (-1 for none), and I'm setting it along with the handleShow method.

React-Bootstrap Modal Is only styling in plain HTML

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>

Can have simultaneously at onClick function props and a function at reactjs?

Hello i have a modal with two buttons
<Modal show={props.show} onHide={props.handleModalOpen}>
<Modal.Header closeButton>
<Modal.Title>Fill this form to continue</Modal.Title>
</Modal.Header>
<Modal.Body>This is the modal </Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={props.handleModalOpen}>
Close
</Button>
<Button variant="primary" onClick={()=>(myhadler,props.handleModalOpen)}>
Save Changes
</Button>
</Modal.Footer>
</Modal>
On onClick i want to trigger a function that called
myhandler
and close the modal if the button is pressed with
props.handleModalOpen.
The props.handleModalOpen is communicating with other component that is the parent. My problem is that when i pressed the button my function myhandler in not working and the only that i achive is to close the modal. Is there a way to run simultaneously my function and the props.handleModalOpen without problem
The function
myhandler
is used to save the form data in local storage
You can just call myHandler() in callback's scope and add a state if the button opened with handleModalOpen
const [isOpened, setIsOpened] = useState(false);
<Modal.Footer>
<Button
variant="secondary"
onClick={() => {
props.handleModalOpen();
setIsOpened(true);
}}
>
Close
</Button>
<Button
variant="primary"
onClick={() => {
myHandler();
if (isOpened) {
props.handleModalOpen();
setIsOpened(false);
}
}}
>
Save Changes
</Button>
</Modal.Footer>

conditional passing component as array prop in react

How can I conditionally pass the footer's button component? cancelBtnBasicModal and okBtnBasicModal the button is still there without text label.
Below is a modal component, it worked, but if I don't pass in
render() {
const { titleBasicModal, showBasicModal, handleOkBasicModal, handleCancelBasicModal,
contentBasicModal, cancelBtnBasicModal, okBtnBasicModal, loading } = this.props
return (
<div>
<Modal
visible={showBasicModal}
title={titleBasicModal}
onCancel={handleCancelBasicModal}
footer={[
<Button onClick={handleCancelBasicModal}>
{cancelBtnBasicModal}
</Button>,
<Button key="submit" type="primary" size="large" loading={loading} onClick={handleOkBasicModal}>
{okBtnBasicModal}
</Button>
]}
>
{contentBasicModal}
</Modal>
</div>
);
}
I tried
footer={[
{cancelBtnBasicModal && <Button onClick={handleCancelBasicModal}>
{cancelBtnBasicModal}
</Button>},
<Button key="submit" type="primary" size="large" loading={loading} onClick={handleOkBasicModal}>
{okBtnBasicModal}
</Button>
]}
But won't work coz footer prop accept array.
You need to pass an Array, spread operation is for rescue.
You can do something like that:
footer={[
...(cancelBtnBasicModal ? [
<Button onClick={handleCancelBasicModal}>
{cancelBtnBasicModal}
</Button>]: []),
<Button key="submit" type="primary" size="large" loading={loading} onClick={handleOkBasicModal}>
{okBtnBasicModal}
</Button>
]}
You can separate that logic by setting an array footerBtns with the default button (okBtnBasicModal in this case) and then we add the next button if it's passed through props.
Finally assign footerBtns to footer in the Modal component.
render() {
const { titleBasicModal, showBasicModal, handleOkBasicModal,
handleCancelBasicModal, contentBasicModal, cancelBtnBasicModal,
okBtnBasicModal, loading } = this.props
let footerBtns = [
<Button key="submit" type="primary" size="large" loading={loading}
onClick={handleOkBasicModal}>
{okBtnBasicModal}
</Button>
]
/* using unshift to add the button to the beginning of the Array */
cancelBasicModal && footerBtns.unshift(
<Button onClick=
{handleCancelBasicModal}>{cancelBtnBasicModal}
</Button>
);
return (
<div>
<Modal
visible={showBasicModal}
title={titleBasicModal}
onCancel={handleCancelBasicModal}
footer={footerBtns}>
{contentBasicModal}
</Modal>
</div>
);
}
More info on using unshift()

Categories

Resources