reactjs MDB Datatable(with checkboxes) component not working when re-render - reactjs

I try to make a simple table that can select rows of the table and delete them when clicking the delete button.
So.. I use the MDBDataTableV5 component.
If I do not put the checkbox in the table then this is working perfectly(when data of table update).
And If I set table data as statically when first loading time then this is working well even I put the checkbox in the table.
But in this case, If I set the data of the table as state dynamically then this is not working. I get this error when re-render(when getting data from parents).
mdbreact.esm.js:1 Uncaught TypeError: Cannot read property 'checked' of undefined
at n.value .......
Here is my code.
const headCells = [
{
label: 'id',
field: 'user_id',
width: 150,
attributes: {
'aria-controls': 'DataTable',
'aria-label': 'id',
},
},
{
label: 'name',
field: 'user_name',
width: 200,
},
{
label: 'email',
field: 'user_email',
width: 400,
},
{
label: 'level',
field: 'user_level',
width: 100
}
]
export default function WithCheckBoxes(props) {
const [datatable, setDatatable] = React.useState({
columns: headCells,
rows: [],
});
useEffect(()=>{
setDatatable({
columns: headCells,
rows: props.user_list
})
}, [props]);
return (
<>
<MDBDataTableV5
hover
entriesOptions={[5, 20, 25]}
entries={5}
pagesAmount={4}
data={datatable}
checkbox
headCheckboxID='id'
bodyCheckboxID='checkboxes'
getValueCheckBox={(e) => {
}}
/>
</>
);
}
What is wrong in my code?
I use "With checkboxes table" in this link.
https://mdbootstrap.com/docs/react/tables/datatables/

Related

How do I access this.state in my column for react-table

I want to have a toggle functionality in my react-table component
my columns is set like
const columns = [
{
Header: 'ID',
accessor : d => { return <Link to={"receipts/" + d.id}> {d.unique_id} </Link> },
},
{
Header: 'Student',
accessor: 'name'
},
{
Header: 'Paid Amount',
accessor: 'paid_amount',
},
{
id: 'is_paid',
Header: 'Paid?',
accessor: d => {
console.log(d);
return <Form.Check id={d.id} type='switch' checked={d.is_paid} onChange={this.handleToggle.bind(this)}/>
}
},
];
and my handleToggle is simply making an API call to update this row
But I'm getting
TypeError: Cannot read property 'handleToggle' of undefined
It seems like I'm not getting the this in my columns. How do I access this?
Have a look at this example https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/editable-data, it can be helpful in passing your own props to table and then using them in cell.

How to add a button to every row in MUI DataGrid

I cant add a button into every row of MUI DataGrid.
I have a MUI DataGrid which I render like this:
<DataGrid rows={rows} columns={columns} pageSize={5} checkboxSelection />
I have added into the columns variable 'actions' column where the button should be. rows are just a a data object I get from the props. how can I add a button into every row (for editing the row)? I have tried mapping the data array but it is not possible to add JSX button into every object of data.
You can add your custom component by overriding GridColDef.renderCell method and return whatever element you want.
The example below displays an action column that renders a single button in each row. When clicking the button, it alerts the current row data in json string:
const columns: GridColDef[] = [
{ field: "id", headerName: "ID", width: 70 },
{
field: "action",
headerName: "Action",
sortable: false,
renderCell: (params) => {
const onClick = (e) => {
e.stopPropagation(); // don't select this row after clicking
const api: GridApi = params.api;
const thisRow: Record<string, GridCellValue> = {};
api
.getAllColumns()
.filter((c) => c.field !== "__check__" && !!c)
.forEach(
(c) => (thisRow[c.field] = params.getValue(params.id, c.field))
);
return alert(JSON.stringify(thisRow, null, 4));
};
return <Button onClick={onClick}>Click</Button>;
}
},
];
Just came across this.
What you need to do is include a renderCell method in your columns array.
const columns = [
{
field: 'col1',
headerName: 'Name 1',
width: 150,
disableClickEventBubbling: true,
},
{
field: 'col2',
headerName: 'Name 2',
width: 300,
disableClickEventBubbling: true,
},
{
field: 'col3',
headerName: 'Name 3',
width: 300,
disableClickEventBubbling: true,
},
{
field: 'col4',
headerName: 'Name 4',
width: 100,
disableClickEventBubbling: true,
},
{
field: 'col5',
headerName: 'Name 5',
width: 150,
***renderCell: renderSummaryDownloadButton,***
disableClickEventBubbling: true,
},
{
field: 'col6',
headerName: 'Name 6',
width: 150,
***renderCell: renderDetailsButton,***
disableClickEventBubbling: true,
},
]
In the above I am rendering a Button inside columns 5 and 6 which will appear on every populated row.
Above that you can have a function which creates and returns a Button from Material-ui.
const renderDetailsButton = (params) => {
return (
<strong>
<Button
variant="contained"
color="primary"
size="small"
style={{ marginLeft: 16 }}
onClick={() => {
parseName(params.row.col6)
}}
>
More Info
</Button>
</strong>
)
}
While #NearHuscarl's response answers the question perfectly, I'd like to post a TypeScript example:
const onClick = () => {
const api: GridApi = params.api;
const fields = api
.getAllColumns()
.map((c) => c.field)
.filter((c) => c !== "__check__" && !!c);
const thisRow: any = {};
fields.forEach((f) => {
thisRow[f] = params.getValue(params.id, f);
});
return alert(JSON.stringify(thisRow, null, 4));
};
return <Button onClick={onClick}>Click</Button>;
Also note, I changed the getValue call. (included the row id)
According to MUI v5 params.getValue method is deprecated and will be removed in the next major version, Instead, you can access the current row data from params.row.
{
field: 'action',
headerName: 'Action',
width: 180,
sortable: false,
disableClickEventBubbling: true,
renderCell: (params) => {
const onClick = (e) => {
const currentRow = params.row;
return alert(JSON.stringify(currentRow, null, 4));
};
return (
<Stack direction="row" spacing={2}>
<Button variant="outlined" color="warning" size="small" onClick={onClick}>Edit</Button>
<Button variant="outlined" color="error" size="small" onClick={onClick}>Delete</Button>
</Stack>
);
},
}
The currently top voted answer is outdated as of v5, because the new GridRowParams interface contains the actual row as a parameter, making the manual filtering from the GridApi unnecessary and unpractical.
Using this with renderCell can be as simple as
const columns: GridColDef[] = [
{ field: "id", headerName: "ID", width: 70 },
{
field: "action",
headerName: "Action",
sortable: false,
renderCell: ({ row }: Partial<GridRowParams>) =>
<Button onClick={() => yourActionFunction(row)}>
Action
</Button>,
},
]
in TypeScript or
const columns = [
{ field: "id", headerName: "ID", width: 70 },
{
field: "action",
headerName: "Action",
sortable: false,
renderCell: ({ row }) =>
<Button onClick={() => yourActionFunction(row)}>
Action
</Button>,
},
]
in plain JavaScript.

Push array variables in MDBReact datatables

So, I have a API which returns the data which should be shown in table with datatable option.
I'm using 'mdbreact' to use datatable.
But there is no documentation about pushing array variables into rows of datatables. How to push my array variables into rows of datatables ?
My code :
import React, { Component } from 'react';
import { MDBDataTable } from 'mdbreact';
class DummyTest extends Component {
DummyFunc() {
var data = {
columns: [
{
label: 'Location',
field: 'Location',
sort: 'asc',
width: 150
},
{
label: 'Entry Time',
field: 'EntryTime',
sort: 'asc',
width: 150
},
{
label: 'Exit Time',
field: 'ExitTime',
sort: 'asc',
width: 150
},
],
rows: [
]
};
const datatableProps = {data, rows: datas};
}
In return
<MDBDataTable
striped
bordered
hover
data={datatableProps}
/>
you can update the rows data after fetching it from the API. sample using hooks.
something like this.setState({datatableProps: ...datatableProps, rows: API_ROWD_ATA})

mdbreact table filter not working using React

I am using datatable with help of mdbreact table from "https://mdbootstrap.com/docs/react/tables/datatables/" here problem with search filter not working with table values. When I type string in search box following error throws and app crashed.
import { MDBDataTable } from 'mdbreact';
const data = {
columns: [
{
label: 'Email',
field: 'emailid',
sort: 'asc',
width: 270
},
{
label: 'First Name',
field: 'namefirst',
sort: 'asc',
width: 270
}
],
rows: [
{"emailid": "xxx#gmail.com", "namefirst": "xxxxx"}]
}
render(){
return(
<div>
<MDBDataTable
striped
hover
data={data}
/>
</div>
}
Here I assigned data static but in my application display dynamic values. On other pages search working fine same code I used but not working one page in my application.

Reactjs-tables. How to join multiple values into 1 cell?

I am using react-table but I have 2 values that I want to join into one cell. Does anyone know how to do this?
Say I have this sample code, right now it has "name" which as the first and last name combined.
What happens if in my db I have it separate by first name and last. How could I join them together in the ui here(I know I could do this at the db level but this just an example)
import ReactTable from 'react-table'
render() {
const data = [{
name: 'Tanner Linsley',
age: 26,
friend: {
name: 'Jason Maurer',
age: 23,
}
},{
...
}]
const columns = [{
Header: 'Name',
accessor: 'name' // String-based value accessors!
}, {
Header: 'Age',
accessor: 'age',
Cell: props => <span className='number'>{props.value}</span> // Custom cell components!
}, {
id: 'friendName', // Required because our accessor is not a string
Header: 'Friend Name',
accessor: d => d.friend.name // Custom value accessors!
}, {
Header: props => <span>Friend Age</span>, // Custom header components!
accessor: 'friend.age'
}]
<ReactTable
data={data}
columns={columns}
/>
}
would this work?
const columns = [
{
Header: 'Full Name',
accessor: d => `${d.firstName} ${d.lastName}`
}
]
In case you want to sort by one of the values
{
Header: "Price",
accessor : "unit_price", // matters for grouping and sorting
Cell : props => <span>
{props.original.currency} {Numeral(props.original.unit_price).format('0,0.00')}
</span>
},

Resources