How to implement Material UI Data Grid in your Project — Part-II

Column Definitions

In Datagrid, the columns prop is static which means it can’t be changed between renders. It can’t be changed once the component is mounted.

With respect to Headers — It has properties like headerName and description(Explained in the previous article)

Size

With respect to the size of columns — It has a default width of 100px. This is fixed which means no matter what the whole grid size(Table size) is it maintains 100px. We can change this value by using property ‘width’

Const columns = [{field:'name',width:150}]

If the grid size is lesser than the column width, it will display a horizontal scroll bar


We can also set the minWidth property to some value. This will be the minimum width for the column. This is useful in responsive design like flex.

flex’ property changes the absolute to fluid width. The whole column behaves as flex — the same as a flex in CSS

For example, Let the total width of the grid be 500px and each column has a flex of 1. So each column would occupy 250px each(1:1). If the first column has a flex of 1.5 and the second has a flex of 1. The first one would occupy 300px and the second one occupies 200px(1.5:1). It’s all boils down to simple ratio calculation.

Note: width and flex won’t work together. In that case, flex overrides width but flex can have minWidth value below which it cannot go

Value Getter

In simple terms,valueGetter enables you to use values of different columns. We can get values from different columns and do operations like concatenation. This resulting value can be displayed in a separate column.

valueGetter expects a function that takes in cell parameters. See details about cell parameters here. It has many built-in and easy-to-access methods and properties. Okay enough let’s see an example

import * as React from 'react';
import { DataGrid } from '@mui/x-data-grid';// params has method called getValue(what id,which field) and returns the value of the particulat cellconst getTotal = (params) => params.getValue(params.id, 'maths')  + params.getValue(params.id, 'science')const columns = [
{ field: 'maths', headerName: 'Maths', width: 130 },
{ field: 'science', headerName: 'Science', width: 130 },
{
field: 'Total',
headerName: 'Total marks',
width: 160,
valueGetter: getTotal,
},
];
const rows = [
{ id: 1, maths: 75, science: 60 },
{ id: 2, maths: 80, science: 70 },
{ id: 3, maths: 50, science: 80 },
{ id: 4, maths: 80, science: 60 },
{ id: 5, maths: 100, science: 90 },
];export default function ValueGetterGrid() {return (<div style={{ height: 400, width: '100%' }}>
<DataGrid rows={rows} columns={columns} />
</div>);
}
We have three columns maths, science, and total marks.

Here the first two fields are independent and the third field is dependent on the first two.

Therefore I used the valueGetter property on the third one to use the first two-column and defined getTotal function to display the result.

Value Formatter

This property is particularly useful when you have nested objects inside rows array(My personal use case). It formats the value within a single column.

import * as React from 'react';
import { DataGrid } from '@mui/x-data-grid';const rows = [
{
id:1,// nested objects
place:{
pincode:613007,
name:'Thanjavur'
}
},
{
id: 2,// nested objects
place:{
pincode:600028,
name:'Chennai'
}
},
{
id: 3,// nested objects
place:{
pincode:641001,
name:'Coimbatore'
}
},
];export default function ValueFormatterGrid() {
return (
<div style={{ height: 300, width: '100%' }}><DataGrid
rows={rows}
columns={[
{
field: 'place',
headerName: 'Place',
width: 150,// Takes the value from nested object
valueFormatter: (params) => params.value.name},
]}/>
</div>);}

Here valueFormatter extracts the name value from place property in rows array.

Value Parser

It is the inverse of valueFormatter. Whatever the value entered by the user will be parsed to some format.

import * as React from 'react';
import { DataGrid } from '@mui/x-data-grid';const rows = [
{
id: 1,
taxRate: 0.1,
},
{
id: 2,
taxRate: 0.2,
},
{
id: 3,
taxRate: 0.3,
},
];export default function ValueParserGrid() {return (
<div style={{ height: 300, width: '100%' }}>
<DataGrid
rows={rows}
columns={[
{
type: 'number',
field: 'taxRate',
editable:true,
headerName: 'Tax Rate',
width: 150,
valueFormatter: (params) => {
const valueFormatted = Number(params.value * 100).toLocaleString();
return `${valueFormatted} %`;
},
// Whatever value you enter will be divided by 100 simultaneously
valueParser: (value) => Number(value) / 100,
},
]}
/>
</div>
);
}

Open sandbox and type

In essence, valueFormater formats the value before display whereas valueParser formats the value live(As the user types)

Render Cell

By default, values displayed in the cell will be a string.Values are contained in <div> in DOM.These <div> has many attributes

<div> attributes for a data grid cell

When it comes to renderCell property, it can do all the work of valueFormatter and valueGetter using cell parameters methods and properties. But it has additional capabilities of accessing and manipulating DOM nodes. For example, adding a button or icon inside the cell, changing the cell into different components.

renderCell property expects a function that takes in GridCellParams and returns our intended result

import * as React from "react";
import { DataGrid } from "@material-ui/data-grid";
import { TextField } from "@material-ui/core";const rows = [
{
id: 1,
taxRate: 0.1
},
{
id: 2,
taxRate: 0.2
},
{
id: 3,
taxRate: 0.3
}
];export default function RenderCell() {return (<div style={{ height: 300, width: "100%" }}><DataGrid
rows={rows}
columns={[
{
field: "taxRate",
headerName: "Tax Rate",// renders default cell into TextField componentrenderCell: (params) => (
<>
<TextField value={params.value} />
</>
),
Width: 150,
editable: true
}
]}
/>
</div>
);
}

The above example renders normal cell into TextField component