Sorry if this has been asked before..
I created a custom column definition below
{
name: "",
label: "Action",
options: {
filter: true,
sort: true,
customBodyRender: (value, tableMeta, updateValue) => {
return (
<Action_DataTable config={{ row: tableMeta, editHandler: editRow, deleteHandler: deleteRow, viewHandler: viewRow }}/>
);
}
}
}
Where Action_DataTable is a custom widget that provides the edit, view and delete button functionality for the application that we're building.. I've checked on the tableMeta.rowData, but the data provided was just array of values which basically can be extracted from the row object using Object.values(). Is there a way for me to get the original row object instead?
What i got was --> [ a, b, c, d ], but what i want is actually { propertyA: a, propertyB: b, propertyC: c, propertyD: d }
Thanks.
Not via the tableMeta, however, I can offer you a way to correlate your data to an action via the customBodyRender. Lets say your first column has a delete button, as in the custom-action-columns example. You can set the empty option to false and then supply a custom id in your data for every row. Then, value in customBodyRender for your delete button will be the unique id for a row of your data which you can use to grab your row data.
In my opinion, tableMeta is missing dataIndex which is like an internally supplied unique id that you could use for this purpose, and it would be much more convenient than my workaround. I'm open to PRs that would provide that.
I'm not sure about supplying the original data in the tableMeta as I don't think the table should be working to keep track of what the original data was that you passed in. I think it would be too costly and error-prone, and since you have access to all of your own data anyway, I think it makes more sense just to have a way to map functions back to your own data easily. Then the library doesn't have to worry about managing and maintaining what you sent in initially, and it can just evolve as you instruct it.
Does that make sense?
Yah i got what you mean there. I also had that similar kind of idea of pulling the row object straight from the store based on the ID using similar idea like yours @gabrielliwerant, though mine is just checking at index 0 of the rowData, which is essentially the object ID itself. I don't mind another workaround though for this.. thanks for the suggestion :+1:
@gabrielliwerant My problem with this approach is that I can't explicitly set a value that would be used in filters and sorts, and set a different render value so I can't do something like this:
const orders = [
{
id: 0,
customer: {
id: 1,
fullName: "Garry Marishenko",
email: "[email protected]"
}
}
];
const columns = [
{
name: "customer",
label: "Customer",
options: {
customDataValue: ({ fullName }) => fullName,
customBodyRender: ({ id, fullName }) => (
<a href={`/customers/${id}`}>{fullName}</a>
),
filterType: "textField"
}
},
{
name: "customer",
label: "Customer Email",
options: {
customDataValue: ({ email }) => email,
customBodyRender: ({ id, email }) => (
<a href={`/customers/${id}`}>{email}</a>
),
filterType: "textField"
}
}
];
I could use the customer's ID for every column and look up additional properties, but if I return a component instead of a string, the table will use the original value and I can't search for fullName or email.
I had a similar problem with currencies: when I return a string, I lose the ability to work with the original number later, perhaps in a custom number filter.
{
name: "Salary",
options: {
filter: true,
customBodyRender: (value, tableMeta, updateValue) => {
const nf = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
return nf.format(value);
}
}
};
To get around this I return <span>nf.format(value)</span> instead, but is there a simpler way to resolve this? I find it uncomfortable that customBodyRender implicitly pollutes the data depending on the return type, but maybe I'm just missing something.
@bkiac I don't know enough about what exactly you are trying to do to answer fully, and I don't want the main thrust of this issue to be lost, so this may need a new issue. To me, using separate filter names and separate data names is a different issue. What's under discussion here is about how to map back arbitrary data to a customBodyRender component, which is doable, but not as easy as it could be. You create your own mappings, transform your data accordingly, and use an id to retrieve whatever meta you want on your side (same with original data if you want to keep it around). However, that's not the same thing as using using different filter names, for which you'd have to lean heavily on the custom filter options.
@gabrielliwerant I wasn't talking about custom filter names exactly. I meant that I can't specify both a data value and a render value. So if I handle my mappings and transformations outside the table and want to display a customer's email and a customer's username with that mapping the custom render part would be solved, but for both columns, the actual data that I can sort and filter will be the same ID which I hand to my mapping.
But if I had access to the whole customer object instead of an ID this would be easier.
I agree that custom filter value may be worth a separate issue, but I felt it's related to this one because I tried to solve this for the first time how this issue's author tried. Thanks anyway!
@bkiac Ok, thanks, I have a clearer idea of what you want now. If you like, you can open a new issue for that request so that it's tracked somewhere and maybe someone will take it (or you could work on it), but it would be lower priority for me due to other more pressing issues.
Most helpful comment
@gabrielliwerant My problem with this approach is that I can't explicitly set a value that would be used in filters and sorts, and set a different render value so I can't do something like this:
I could use the customer's ID for every column and look up additional properties, but if I return a component instead of a string, the table will use the original value and I can't search for
fullNameoremail.I had a similar problem with currencies: when I return a string, I lose the ability to work with the original number later, perhaps in a custom number filter.
To get around this I return
<span>nf.format(value)</span>instead, but is there a simpler way to resolve this? I find it uncomfortable thatcustomBodyRenderimplicitly pollutes the data depending on the return type, but maybe I'm just missing something.