I'm coding a list on ReactJS using https://v3.material-ui.com/ . In the list I place a delete button:
<IconButton
color="warning"
className={classes.button}
onClick={this.handleDelete}
value={item}
aria-label={intl.formatMessage({
id: "Worksheet.delete",
defaultMessage: "Delete",
})}
>
<Delete />
</IconButton>
value={item} has the object I want to get to the handleDelete function. Now I'm trying to find out how to retrieve the object. I've tried e.currentTarget, e.target. It's not in there.
Am I doing it the right way?
I found the answer: onClick={() => this.handleDelete(item)}.
This will send the whole object to the handle function
Related
I have a List that has several ListItems which I get from an array, let's call it myCollection. Each ListItem has a MenuIcon which opens a Menu, showing an option to delete the item. The simplified code looks like this:
<List>
<Menu
open={Boolean(anchorEl)}
anchorEl={anchorEl}
...>
<MenuItem onClick={() => handleDelete(⚡collectionItem)}>Delete</MenuItem>
</Menu>
{myCollection.map((collectionItem) => (
<ListItem secondaryAction={
<IconButton onClick={(e) => setAnchorEl(e.currentTarget)}>
<MoreVertIcon />
</IconButton>
}>
{collectionItem.name}
</ListItem>
)}
</List>
My problem is that I need to know which item in myCollection was selected to pass it to the delete function. However, I don't have a reference to the current collectionItem in the myCollection array from the Menu. Moving the Menu into the map function makes no sense because multiple menus would be rendered. How can I solve this problem?
I solved it by giving the IconButtons custom HTML data attributes, e.g.
<IconButton data-collection-id={collection.id} onClick={...}>
...
</IconButton>
Then, in the onClick function, we can retrieve it by using event.currentTarget.getAttribute("data-collection-id").
I wanted to follow like a todo list. Something just like in the picture below.
Right now, the problem with my code is that, its working differently.
I wanted only one input that renders a list of divs instead of input fields.
Exactly just like in the picture below:
Pls check my codesandbox here
CLICK HERE
<FieldArray
name="todos"
render={(arrayHelpers) => (
<div>
{formik.values.todos.map((friend, index) => (
<div key={index} style={{ display: "flex", gap: "1rem" }}>
<input
name={`todos[${index}].name`}
value={formik.values.todos[index].name}
onChange={formik.handleChange}
/>
<button
disabled={formik.values.todos?.length === 1}
type="button"
onClick={() => arrayHelpers.remove(index)}
className="deleteButton"
>
Remove
</button>
</div>
))}
<button
type="button"
onClick={() => arrayHelpers.push({ name: "" })}
>
Add
</button>
</div>
)}
/>
Here is a very simple and rude approach - I used Formik my project some time ago and I'm pretty sure it's not perfect but this is exactly what you need.
So some details.
do not render input for every item in your list, you need only render it's value and element with delete handler
you need only one controlled input and it's value is used for name field in your todos. State is cleaned when you click Add button.
you need to render your element only if formik.values.todos.lenght > 0
you need to disable Delete button when formik.values.todos.lenght === 1
Add button should be disabled when newValue.lenght === 0
Piece a cake, right?
According to the document here it says callback function onPreview will be executed when file link or preview icon is clicked. But only the file link works for me. I can't figure out what is the problem here.
<Upload
beforeUpload={() => false}
listType="picture"
maxCount={1}
accept="video/mp4"
onPreview={() => console.log("HELLO")}
>
<Button readOnly={someLogic} icon={<UploadOutlined />}>
{t("admin_entity.add_video")}
</Button>
</Upload>
As i checked, the issue is come from file's thumbnail.
It works with with an image ( which can generate a thumbnail in list ).
Maybe you can try to override the thumbnail with some event listener on it, just a workaround solution :)
I used iconRender function to solve this problem
iconRender={(originNode) => (
<PlaySquareTwoTone onClick={() => console.log("HELLO")} />
)}
So the problem I am having is that I have a custom rendered column inside which there is a menu button clicking on it open a menu like this:
Now look at below code:
columns={[
{
title: 'Actions',
field: 'tableData.id',
render: rowData => {
return (
<div>
<IconButton aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}>
<MenuIcon />
</IconButton>
<Menu
className={classes.menu}
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem className={classes.sendMail} onClick={()=>
{console.log(rowData)}}>
<ListItemIcon className={classes.icon}>
<SendIcon fontSize="default" />
</ListItemIcon>
Send Assessment Email
</MenuItem>
</Menu>
</div>
)
},
},
The values coming in from the rows i.e rowData is fine on the first onClick of IconButton component but the second onClick of MenuItem shows only the last rowData value no matter which row i select.
Any help would be appreciated. Thank you.
EDIT: I have deployed a quick fix by setting the selected row on Menubutton inside useState and then using that value for the other actions but i wanna know if that is natively or shall i say possible on default rather then the approach i took . i tried stopping event propagation but in vain.
Thanks for asking this questions and seeing that I'm not completely alone...
I am not sure if this could serve as a solution or as a work around, but it works for me.
On the button being used to open the menu, I use the onClick event to set the selected menu row which I want to use, and save it
to the component state.
const [slcRow, setSlcRow] = React.useState(null);
const handleClick = (event, row) => {
setAnchorEl(event.currentTarget);
setSlcRow(row);
};
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={(event ) => {handleClick(event, row) }}
>
Open Menu
</Button>
In the MenuItem onClick event I check the state to retrieve that row and do the work needed...
const handleEditOpen = (event) => {
let row = slcRow;
loadEditData(row.clientId);
setEdit(true);
setAnchorEl(null);
};
<Menu id="long-menu" anchorEl={anchorEl} keepMounted open={open} onClose={handleClose1}>
<MenuItem onClick={(event) => { handleEditOpen(event) }}>Edit </MenuItem>
</Menu
I look on another questions, but cant really solve my problem. Im trying to call a function to open a modal with reactJS, but the call button is in one page and the modal files are in another to be reused if necessary, but when i click in it, its return a not a fuction error; Here is my code.
This is the button. The openModal is not working
<TableCell>
<DbButton
onClick={(e) => openModal(event.id)}
>{<FormattedMessage id='delete' />}</DbButton>
</TableCell>
This is the modal in another file
const openModal = (eventId) => {
setOpen(true)
setEventId(eventId)
}
return (
<Panel border={false}>
<TableEventsComponent
data={dataList}
goTo={goTo}
onChangePage={onChangePage}
onChangeRowsPerPage={onChangeRowsPerPage}
rowsPerPage={rowsPerPage}
page={page}
deleting={deleting}
></TableEventsComponent>
<Dialog
open={open}
onClose={handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">{<FormattedMessage id='alert-title' />}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
{<FormattedMessage id='alert-body' />}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button
onClick={handleClose}
color="primary">
{<FormattedMessage id='cancel' />}
</Button>
<Button
onClick={handleConfirm}
color="primary"
autoFocus>
{<FormattedMessage id='confirm' />}
</Button>
</DialogActions>
</Dialog>
</Panel>
)
Any advice?
Basically, this project is abstracting most of the components, to be reusable and easier to do maintenance. The father index where the modal construction and the logic handles things had a events listener to receive the props passed by, and the son index where the page shows to the user and had the delete button just passa the props to call the function to do the job.
So, on the TableEventsComponent that i put on my second block of code on the question, i put a
openModal={openModal}
And, on the page i got the button, i had
const TableEventsComponent = ({
openModal,
...
})
Thats it, i just not communicating the way it should be.