MUI DataGrid layout issues using React - javascript

Been trying to get MUI DataGrid to work for a few hours now, but for some reason the styling is placing the pagination information at the top of the table, on top of the column headers.
Maybe its something stupid I'm doing. I have tried a really simple version to illustrate my issues. Hope someone can please help me. BTW I use v5+ of MUI and DataGrid. React is v17+
import React, { FC } from "react";
import { DataGrid, GridRowModel } from "#mui/x-data-grid";
import { GridColDef } from "#mui/x-data-grid";
export const DataGridTest: FC = () => {
const paginationSize = 20;
const columns: GridColDef[] = [
{ field: "username", headerName: "Username", flex: 1, sortable: false, filterable: false },
{ field: "first_name", headerName: "First Name", flex: 1, sortable: false, filterable: false },
{ field: "last_name", headerName: "Last Name", flex: 1, sortable: false, filterable: false },
{ field: "email", headerName: "Email", flex: 1, sortable: false, filterable: false },
{ field: "phone", headerName: "Phone", flex: 1, sortable: false, filterable: false },
];
const rows: GridRowModel[] = [
{
id: 1,
username: "Tony",
first_name: "Tony",
last_name: "Ballony",
email: "Tony#test.com",
phone: "0754512222",
},
{
id: 2,
username: "Joe",
first_name: "Joeseph",
last_name: "Willson",
email: "joe#test.com",
phone: "0754512333",
},
];
return (
<div>
<DataGrid rows={rows} columns={columns} pageSize={paginationSize} />
</div>
);
};
The output looks like this.
So you can see that the pagination section that should be shown below the table data is instead positioned at the top of the page. In fact the border that should be around the data is also moved to the top. I hope someone can help me out here.

You have to specify the height of DataGrid, like:
//// Your code ////
return (
<div>
<DataGrid
style={{ height: "700px" }}
rows={rows}
columns={columns}
pageSize={paginationSize} />
</div>
);
};
You can use stylesheets instead of inline styles ofc. It's just an example.

Related

Unable to update state from onClick event of MDBDatable row in React

I'm using MDBReact for the creation of a simple data table that has some rows and setMe and getMe buttons. onClick of setMe button I wish to set a value to the cropName state value and onClick of getMe button, I wish to retrieve the update state value.
The problem is that I only receive emptystring values every time inside the getMe function even after updating the state.
I have tried the following code, but unfortunately, it does not seem to update the state value. I only get an emptystring when the getMe button is clicked.
import React, { useState } from 'react';
import { render } from 'react-dom';
import { MDBDataTable } from 'mdbreact';
import './style.css';
import '#fortawesome/fontawesome-free/css/all.min.css';
import 'bootstrap-css-only/css/bootstrap.min.css';
import 'mdbreact/dist/css/mdb.css';
function App() {
const [cropName, setCropName] = useState('');
const [data, setData] = useState([]);
function setMe(e) {
console.log(setCropName('Hello'));
}
function getMe(e) {
console.log(cropName);
}
function loadTable() {
setData({
columns: [
{
label: 'Action',
field: 'radio',
sort: 'asc',
width: 150,
},
{
label: 'Position',
field: 'position',
sort: 'asc',
width: 270,
},
{
label: 'Office',
field: 'office',
sort: 'asc',
width: 200,
},
{
label: 'Age',
field: 'age',
sort: 'asc',
width: 100,
},
{
label: 'Start date',
field: 'date',
sort: 'asc',
width: 150,
},
{
label: 'Salary',
field: 'salary',
sort: 'asc',
width: 100,
},
],
rows: [
{
radio: (
<div className="field-input pt-2">
Click this
<button id="asdfsdasafsdf" onClick={setMe}>
set me!
</button>
<button id="asdfsdasafsdf" onClick={getMe}>
get me!
</button>
</div>
),
position: 'System Architect',
office: 'Edinburgh',
age: '61',
date: '2011/04/25',
salary: '$320',
},
{
name: 'Garrett Winters',
position: 'Accountant',
office: 'Tokyo',
age: '63',
date: '2011/07/25',
salary: '$170',
},
],
});
}
return (
<div>
<MDBDataTable striped bordered hover data={data} />
<button onClick={loadTable}>Load Table</button>
</div>
);
}
render(<App />, document.getElementById('root'));
Here the live demo of my implementation.
It looks like the state updates are not available to the functions fired from the table row event. I got my way around it by using useEffect statement and setting the dependency as the property that gets modified by the table row event.
import React, { useState, useEffect } from 'react';
import { render } from 'react-dom';
import { MDBDataTable } from 'mdbreact';
import './style.css';
import '#fortawesome/fontawesome-free/css/all.min.css';
import 'bootstrap-css-only/css/bootstrap.min.css';
import 'mdbreact/dist/css/mdb.css';
function App() {
const [cropName, setCropName] = useState('');
const [data, setData] = useState([]);
useEffect(()=>{
console.log('Crop changed')
}, [cropName])
function setMe(e) {
setCropName('Hello ID: '+Math.random());
}
function getMe(e) {
console.log(cropName);
}
function loadTable() {
setData({
columns: [
{
label: 'Action',
field: 'radio',
sort: 'asc',
width: 150,
},
{
label: 'Position',
field: 'position',
sort: 'asc',
width: 270,
},
{
label: 'Office',
field: 'office',
sort: 'asc',
width: 200,
},
{
label: 'Age',
field: 'age',
sort: 'asc',
width: 100,
},
{
label: 'Start date',
field: 'date',
sort: 'asc',
width: 150,
},
{
label: 'Salary',
field: 'salary',
sort: 'asc',
width: 100,
},
],
rows: [
{
radio: (
<div className="field-input pt-2">
Click this
<button id="asdfsdasafsdf" onClick={setMe}>
set me!
</button>
<button id="asdfsdasafsdf" onClick={getMe}>
get me!
</button>
</div>
),
position: 'System Architect',
office: 'Edinburgh',
age: '61',
date: '2011/04/25',
salary: '$320',
},
{
name: 'Garrett Winters',
position: 'Accountant',
office: 'Tokyo',
age: '63',
date: '2011/07/25',
salary: '$170',
},
],
});
}
return (
<div>
<MDBDataTable striped bordered hover data={data} />
<button onClick={loadTable}>Load Table</button>
{cropName}
</div>
);
}
render(<App />, document.getElementById('root'));
Demo

mdbreact (MDBDataTable) add clickEvent for specific columns expect all

I have added clickEvent in my code fo MDBDataTable. I have some columns in table, I have added clickEvent but it applying for all columns. I need click event for all columns except "addBtn" column. Becausse it is contains buttons - Edit and Delete.
const data = {
columns: [
{
label: "First Name",
field: "firstName",
sort: "asc",
width: 150,
},
{
label: "Last Name",
field: "lastName",
sort: "asc",
width: 150,
},
{
label: "Email",
field: "email",
sort: "asc",
width: 270,
},
{
label: "Role",
field: "authorities",
sort: "asc",
width: 200,
},
{
label: "Contact",
field: "phoneNumber",
sort: "asc",
width: 100,
},
{
label: "Type",
field: "userType",
sort: "asc",
width: 100,
},
{
label: "Action",
field: "addBtn",
sort: "asc",
width: 300,
},
],
rows:
userdData &&
userdData.length > 0 &&
userdData.map(rec => {
return {
firstName: rec?.firstName,
lastName: rec?.lastName,
email: rec?.email,
authorities: rec?.authorities[0],
phoneNumber: rec.phoneNumber !== null ? rec.phoneNumber !== null : "",
userType: rec?.userType,
addBtn: actionButtons(rec, rec?.id),
clickEvent: () => handleClick(rec)
}
}),
}
I have attached screen shot of the my page

Align column content to the right of cell React MUIDataTable

I'm new to MUI and i want to align the content of a column to the right.my code looks like this:
<MUIDataTable
title={""}
data={data || []}
columns={realColumns ? realColumns(data, modeMO) : columns(data, modeMO)}
options={{
filterType: "textField",
responsive: "simple",
selectableRows: selectable, // set checkbox for each row
search: false, // set search option
filter: false, // set data filter option
download: false, // set download option
print: false, // set print option
pagination: true, //set pagination option
viewColumns: false, // set column option
elevation: 0,
rowsPerPageOptions: [10, 20, 40, 80, 100],
//setCellProps: () => ({ align: 'right' }) ,
onRowSelectionChange: (
currentRowsSelected,
allRowsSelected,
rowsSelected
) => {
setSelectedRows(
allRowsSelected.map((el) => {
return data[el.dataIndex];
})
);
},
selectToolbarPlacement: "none"
}}
/>;
and this is what's displayed:
table Picture
so i would like to align all the numbers in "Montant à régler" column to the right.
can somebody help please.
Disclaimer: This is totally un-tested and only a snip of "columns".
Give your columns a custom render and set the cell properties i.e. something like:
export const columns = [
{
name: "category",
label: "Fun Guy Category",
options: {
setCellProps: () => ({ style: { minWidth: "100px", maxWidth: "800px", justifyContent: 'end' }}),
customBodyRender: (data, type, row) => {return <pre>{data}</pre>}
},
},
If you are using basic tables of Material UI then you can align it through passing align prop to the TableCells to align content in each row and column. You can set align equals to right, left, etc.
If you are using DataGrid or data tables of Material UI (Which I think you are) then you can pass align prop to each column. See the edited example code below from Material UI:
import * as React from "react";
import { DataGrid } from "#mui/x-data-grid";
const columns = [
{ field: "id", align: "rights", headerName: "ID", width: 70 },
{ field: "firstName", align: "center", headerName: "First name",
width: 130 },
{ field: "lastName", align: "left", headerName: "Last name",
width: 130 },
{
field: "age",
headerName: "Age",
type: "number",
width: 90
},
{
field: "fullName",
headerName: "Full name",
description: "This column has a value getter and is not
sortable.",
sortable: false,
width: 160,
valueGetter: (params) =>
`${params.getValue(params.id, "firstName") || ""} ${
params.getValue(params.id, "lastName") || ""
}`
}
];
const rows = [
{ id: 1, align: "right", lastName: "Snow", firstName: "Jon", age:
35 },
{ id: 2, lastName: "Lannister", firstName: "Cersei", age: 42 },
{ id: 3, lastName: "Lannister", firstName: "Jaime", age: 45 },
{ id: 4, lastName: "Stark", firstName: "Arya", age: 16 },
{ id: 5, lastName: "Targaryen", firstName: "Daenerys", age: null
},
{ id: 6, lastName: "Melisandre", firstName: null, age: 150 },
{ id: 7, lastName: "Clifford", firstName: "Ferrara", age: 44 },
{ id: 8, lastName: "Frances", firstName: "Rossini", age: 36 },
{ id: 9, lastName: "Roxie", firstName: "Harvey", age: 65 }
];
export default function DataTable() {
return (
<div style={{ height: 400, width: "100%" }}>
<DataGrid
rows={rows}
columns={columns}
pageSize={5}
rowsPerPageOptions={[5]}
checkboxSelection
/>
</div>
);
}
You can learn many more about Material UI Tables here:
Material UI Tables
Hope this helps.

Material-UI datagrid datepicker

I'm making a scheduler using Material-UI's DataGrid component and it looks great so far. Here's how I have it set up:
import React, {useState, useEffect } from "react";
import {DataGrid, GridToolbar} from '#material-ui/data-grid';
import axios from 'axios'
const columns = [
{
field: 'name',
headerName: 'Name',
editable: true,
flex: 1
},
{
field: 'email',
headerName: 'Email',
editable: true,
flex: 1
},
{
field: 'number',
headerName: 'Phone Number',
editable: true,
flex: 1
},
{
field: 'appointmentType',
headerName: 'Appointment Type',
editable: true,
flex: 1
},
{
field: 'description',
headerName: 'Description',
editable: true,
flex: 1
},
{
field: 'date',
headerName: 'Date',
editable: true,
width: 150,
type: 'dateTime'
},
];
const Scheduler = () => {
const [tableData, setTableData] = useState([]);
useEffect(() => {
fetchData()
}, [])
const fetchData = async () => {
const {data} = await axios.get("/api/patients")
setTableData(data.data)
console.log(data)
}
return (
<div style={{display: 'flex', flexDirection: 'column', paddingTop: 100}}>
<div style={{textAlign: 'center', paddingBottom: 30}}>
<h1>Appointments</h1>
</div>
<div style={{display:'flex', justifyContent: 'center', alignItems:'center'}}>
<div style={{height: 400, width: '90%'}}>
<DataGrid
getRowId={(row) => row._id}
rows={tableData}
columns={columns}
pageSize={10}
rowsPerPageOptions={[10]}
autoHeight
components={{
Toolbar: GridToolbar
}}
/>
</div>
</div>
</div>
);
};
export default Scheduler;
I have a couple questions.
How do I make the datetime picker built into the datagrid (when type: is declared as 'datetime') localized? This system is being designed for something outside the US, so I'd like to localize it to British English.
How would I restrict certain dates and times in the aforementioned datetime picker?
Thank you.

Display empty table/datagrid with empty lines in Material UI

I'm trying to display an empty table (ie with no data to display), with a predefined height but with a set of empty lines.
By default, the table is displayed with no lines (its background is empty).
I would like to display empty lines. Even, if the number of rows is lower than the maximum number of allowed rows in a page, I would like to complete the display with empty lines.
I tried at least a dirty solution by adding manually an empty line, but even like this the result is not as exptected as the line is squashed and not well displayed. Cf attached image:
Below is the code of my component:
export default function MyComponent() {
const classes = useStyles();
const columns: GridColumns = [
{
field: 'data1',
headerName: 'DATA 1',
width: 130,
headerClassName: 'data--header',
cellClassName: 'data--cell',
},
{
field: 'data2',
headerName: 'DATA 2',
width: 130,
headerClassName: 'data--header',
cellClassName: 'data--cell',
},
{
field: 'data3',
headerName: 'DATA 3',
width: 130,
headerClassName: 'data--header',
cellClassName: 'data--cell',
},
{
field: 'data4',
headerName: 'DATA 4',
width: 130,
headerClassName: 'data--header',
cellClassName: 'data--cell',
},
{
field: 'data5',
headerName: 'DATA 5',
width: 130,
headerClassName: 'data--header',
cellClassName: 'data--cell',
},
{
field: 'data6',
headerName: 'DATA 6',
width: 130,
headerClassName: 'data--header',
cellClassName: 'data--cell',
},
];
const rows = [
{ id: "0", data1: "AAA", data2: "BBB", data3: "CCC", data4:"DDD", data5:"EEE", data6: "FFF" },
];
for(var i=1; i<10 ; i++) {
rows.push({id: i, data1: "", data2: "", data3: "", data4:"", data5:"", data6: ""})
}
return (
<div className={classes.root} style={{ height: 300, width: 700 }}>
<DataGrid disableColumnMenu hideFooter rowCount="10"rows={rows} columns={columns} rowHeight="30" />
</div>
);
}
Can anybody give my a hint to move on this task ? I'm a bit stuck (and if there is a solution without the manual creation of empty lines it would even be better :-)).
Thank you!

Categories