Hello,
I added my action buttons using customBodyRender:
{
name: "Action",
options: {
filter: true,
sort: false,
empty: true,
customBodyRender: () => {
return (
<ActionButtons
onView={this.onView}
onEdit={this.onEdit}
onDelete={this.onDelete}
/>
);
}
}
},
And in table options, I use onRowClick to get the data (included an object of the component
const options = {
filter: true,
download: false,
selectableRows: false,
filterType: "dropdown",
responsive: "scroll",
rowsPerPage: 10,
customToolbar: () => (
<CustomToolbar
handleFormOpen={this.handleFormOpen}
/>
),
onRowClick: (event, rowData) => {
this.handleClickedActionButton(event, rowData);
},
};
As I have 3 buttons in one cell (view, edit and delete) for each row, I need to know which button was clicked in order to perform an action to the data (call a function).
I tried using event.currentTarget to get the id of the button clicked, use that id in a switch statement in order to identify which one was and base on that call the correct function.
Something like this:
onRowClick: (event, rowData) => {
this.handleClickedActionButton(event, rowData);
},
};
//
handleClickedActionButton = (event, rowData ) => {
const buttonID = event.currentTarget.dataset.id;
switch (buttonID) {
case "btnView":
console.log("View");
break;
case "btnEdit":
console.log("Edit");
break;
case "btnDelete":
console.log("Delete");
break;
default: console.log("No action button clicked.");
}
};
But I just get an error saying "Type error: event.currentTarget is undefined".
How can I implement this idea in a better way? T.T
_Originally posted by @ladyllma in https://github.com/gregnb/mui-datatables/issues/297#issuecomment-480146733_
customBodyRender takes a "tableMeta" argument as it's second parameter. This argument contains the rowData as well as a bunch of other information. Here's the description from the docs:
function(value: any, tableMeta: {
rowIndex: number,
columnIndex: number,
columnData: array, // Columns Options object
rowData: array, // Full row data
tableData: array, Full table data
tableState: {
announceText: null|string,
page: number,
rowsPerPage: number,
filterList: array,
selectedRows: {
data: array,
lookup: object,
},
showResponsive: boolean,
searchText: null|string,
},
}, updateValue: function)
I would refactor your code so that you pass in the rowData to your ActionButtons component, and then handle the onClick events on the buttons inside of that component.
Check out the custom-action-columns example, as it seems like your use case. customBodyRender contains all the information you should need to operate on your data including the value of the data for that cell.
thank you for helping me but i'm new in react js can you provide your words with code or link for example and i'll edit on it , thank you so much
This is the example Gabriel mentioned: https://github.com/gregnb/mui-datatables/blob/master/examples/custom-action-columns/index.js
In your case, you'd want to change your code to be more like this:
{
name: "Action",
options: {
filter: true,
sort: false,
empty: true,
customBodyRender: (value, tableMeta, updateValue) => {
return (
<ActionButtons
onView={this.onView}
onEdit={this.onEdit}
onDelete={this.onDelete}
rowData={tableMeta.rowData}
/>
);
}
}
},
You'd then need to update your ActionButtons component to deal with this new prop. Essentially, what you're trying to do in "handleClickedActionButton", that would go inside of ActionButtons - most likely you'd be setting up onClick events on the buttons inside of that component.
And actually, I just realized you're passing in onView, onEdit, and onDelete into this component. If those are being attached to the buttons inside of the ActionButtons, you may just need to update your code like so:
{
name: "Action",
options: {
filter: true,
sort: false,
empty: true,
customBodyRender: (value, tableMeta, updateValue) => {
return (
<ActionButtons
onView={() => this.onView(tableMeta.rowData) }
onEdit={() => this.onEdit(tableMeta) }
onDelete={() => this.onDelete(tableMeta) }
/>
);
}
}
},
That would cause onView, onEdit, and onDelete to get info about the row.