How to properly render a button or icon inside Data Grid column? - material-ui

i have a Data Grid table, there's a colomn that holds actions (edit and delete):
(Below is my whole code)
import React, { useEffect } from 'react'
import { DataGrid } from '#mui/x-data-grid'
import { useNavigate } from 'react-router-dom'
import EditIcon from '#mui/icons-material/Edit'
import DeleteForeverIcon from '#mui/icons-material/DeleteForever'
import { Button } from '#mui/material'
const rows = [
{
id: 1,
lastName: 'Snow',
firstName: 'Jon',
age: 35,
edit: EditIcon,
delete: `${(<Button variant="text">Text</Button>)}`,
},
]
const Colors = () => {
const columns = [
{ field: 'id', headerName: 'ID', width: 70 },
{ field: 'firstName', headerName: 'First name', width: 130 },
{ field: 'lastName', headerName: 'Last name', width: 130 },
{
field: 'age',
headerName: 'Age',
type: 'number',
width: 90,
},
{ field: 'edit', headerName: 'Edit', width: 150 },
{ field: 'delete', headerName: 'Delete', width: 150 },
]
return (
<div style={{ height: 560, width: '100%' }}>
<DataGrid
sx={{ backgroundColor: 'white' }}
rows={rows}
columns={columns}
pageSize={8}
rowsPerPageOptions={[8]}
checkboxSelection
/>
</div>
)
}
export default Colors
Now my problem is, i would like to use a material icon inside edit column.
I tried by implementing icon directly like this:
const rows = [
{
id: 1,
lastName: 'Snow',
firstName: 'Jon',
age: 35,
edit: EditIcon, //<--
},
]
Or calling a button by this way:
const rows = [
{
id: 1,
lastName: 'Snow',
firstName: 'Jon',
age: 35,
delete: `${(<Button variant="text">Text</Button>)}`, //<--
},
]
Result: i'm getting a render [object object] instead of icon or button.
How to properly render a button or icon inside Data Grid column?

I think you can try doing this. MUI exposes an actions column type that you can pass custom icons and implementations to. If you scroll down a bit on this link you can find a lot of column options.
Actions column
import { GridActionsCellItem, GridRowParams } from "#mui/x-data-grid-pro";
import EditIcon from "#mui/icons-material/Edit";
{
field: "actions",
type: "actions",
align: "left",
headerName: t("actions"),
getActions: (params: GridRowParams) => [
<GridActionsCellItem
key={0}
icon={<EditIcon titleAccess={t("edit")} color="primary" />}
label={t("edit")}
onClick={() => handleEditPressed(params)}
/>,
],
},

I fixed my problem by using renderCell, with this i can render html inside grid data the way i want (i can put button for exemple):
{
field: 'edit',
headerName: 'Edit',
width: 70,
renderCell: (params) => {
return <EditIcon /> //<-- Mui icons should be put this way here.
},
},

Related

MUI data grid boolean cell type conditional formatting

Is there a way to conditionally format MUI datagrid cell that has a 'boolean' type.
Here is a sandbox from documentation with a checkbox column that has a boolean type: https://codesandbox.io/s/1ckfjp?file=/demo.tsx:1771-1855
const columns: GridColumns = [
...
{
field: 'isPaid',
headerName: 'Is paid?',
type: 'boolean',
width: 140,
editable: true,
},
...
Is using cellRender (in cols definition (https://mui.com/x/react-data-grid/column-definition/#rendering-cells)) the only way to render my own green or red icons depending if value is true or false? Or is there a better way?
So far this seems the easiest way:
const columns: GridColumns = [
...
{
field: 'isPaid',
headerName: 'Is paid?',
type: 'boolean',
width: 140,
editable: true,
renderCell: (params) => {
return params.value ? (
<CheckIcon
style={{
color: theme.palette.success.light,
}}
/>
) : (
<CloseIcon
style={{
color: grey[500],
}}
/>
);
},
},
...

Display all row instead of 3 row

Goal:
Display all row in the in table at the same time.
Problem:
It display only 3 row at the same time in the table.
I would like to display all row at the same time without any limitation.
It doesn't work to use "height: '100%'"
Any idea?
Codesandbox:
https://codesandbox.io/s/mkd4dw?file=/demo.tsx
Thank you!
demo.tsx
import * as React from 'react';
import Box from '#mui/material/Box';
import Rating from '#mui/material/Rating';
import {
DataGrid,
GridRenderCellParams,
GridColDef,
useGridApiContext,
} from '#mui/x-data-grid';
function renderRating(params: GridRenderCellParams<number>) {
return <Rating readOnly value={params.value} />;
}
function RatingEditInputCell(props: GridRenderCellParams<number>) {
const { id, value, field } = props;
const apiRef = useGridApiContext();
const handleChange = (event: React.SyntheticEvent, newValue: number | null) => {
apiRef.current.setEditCellValue({ id, field, value: newValue });
};
const handleRef = (element: HTMLSpanElement) => {
if (element) {
const input = element.querySelector<HTMLInputElement>(
`input[value="${value}"]`,
);
input?.focus();
}
};
return (
<Box sx={{ display: 'flex', alignItems: 'center', pr: 2 }}>
<Rating
ref={handleRef}
name="rating"
precision={1}
value={value}
onChange={handleChange}
/>
</Box>
);
}
const renderRatingEditInputCell: GridColDef['renderCell'] = (params) => {
return <RatingEditInputCell {...params} />;
};
export default function CustomEditComponent() {
return (
<div style={{ height: 250, width: '100%' }}>
<DataGrid
rows={rows}
columns={columns}
experimentalFeatures={{ newEditingApi: true }}
/>
</div>
);
}
const columns = [
{
field: 'places',
headerName: 'Places',
width: 120,
},
{
field: 'rating',
headerName: 'Rating',
renderCell: renderRating,
renderEditCell: renderRatingEditInputCell,
editable: true,
width: 180,
type: 'number',
},
];
const rows = [
{ id: 1, places: 'Barcelona', rating: 5 },
{ id: 2, places: 'Rio de Janeiro', rating: 4 },
{ id: 3, places: 'London', rating: 3 },
{ id: 4, places: 'New York', rating: 2 },
];
You need to make use of autoHeight prop supported by the <DataGrid /> component, update your DataGrid component usage to this:
<DataGrid
autoHeight
rows={rows}
columns={columns}
experimentalFeatures={{ newEditingApi: true }}
/>
Reference: https://mui.com/x/react-data-grid/layout/#auto-height

MUI Datagrid rendercell getValue return undefined

Since I pushed my code on production, I cant call anymore getValue inside renderCell
Environnement is the same as dev by the way
Here is the columns def:
const columns = [
{
field: 'edit',
headerName: 'Edit',
sortable: false,
width: 78,
renderCell: (params) => (
<div>
<EditProduct defaultCats={props.defaultCats} prodId={params.getValue('id')} productIdGL={params.getValue('productId')} />
</div>
),
align: "left",
},
{
field: 'active',
headerName: 'Off / On',
width: 104,
renderCell: (params) => (
<div><CustomSwitch
checked={Boolean(params.value)}
onChange={() => myswitch(params.getValue('id'), Boolean(params.value))}
name="switch-"
inputProps={{ 'aria-label': 'primary checkbox' }}
></CustomSwitch>
</div>
),
align: "left",
},
{ field: 'category_name', headerName: 'Catégorie', width: 120 },
{ field: 'item_name', headerName: 'Nom du produit', width: 220 },
{
field: 'price',
headerName: 'Prix de vente',
type: 'number',
width: 140,
},
{
field: 'profit',
headerName: 'Profit par vente',
type: 'number',
width: 160,
alt: 'Test'
},
{ field: 'type', headerName: 'Type', width: 90 },
{ field: 'id', headerName: '#', width: 80 },
];
Error:
Unhandled Runtime Error
TypeError: Cannot read property 'undefined' of undefined
Any help appreciate since this bug occur only on production
mui-core: 4.11.4
mui-datagrid: 4.0.0-alpha.26
params.getValue(params.id, 'id') || ''
Instead of
params.getValue('id')

Radio Buttons in ag-grid

I am using ag-grid to display my data and i have below question:
1.Instead of check boxes i want radio buttons to be displayed when i expand the group and also my grouping is not working as expected.?
Plunkr link for the above grid what i tried so far https://plnkr.co/edit/KahAzPv6QEccaaRKlzCN?p=preview
var gridOptions = {
columnDefs: [
{headerName: "Jobs",field: "job", width: 90,rowGroupIndex: 0 ,hide:true},
// this tells the grid what values to put into the cell
//showRowGroup: 'position'
// this tells the grid what to use to render the cell
// cellRenderer:'agGroupCellRenderer'
//{field: 'position', rowGroup: true, hide: true},
{headerName: "Name", field: "name"}
],
rowData: [
{position:'Developer',name:'Test1',job:'Position'},
{position: 'Manager', name:'Test2',job:'Position'},
{position: 'Musician',job:'Position'},
{position: 'Manager',name:'Test4',job:'Position'},
{position: 'Europe',job:'Location'},
{position: 'Australia',name:'Test4',job:'Location'}
],
/* autoGroupColumnDef:{
headerName:'',
cellRendererParams:{
suppressCount: true,
checkbox:true
}
}*/
autoGroupColumnDef: {
headerName: "Jobs",
field: "position",
width: 250,
cellRenderer:'agGroupCellRenderer',
cellRendererParams: {
checkbox: true
}
}
};

extjs form panel set default value textfield

This seems like a trivial issue, but... I have a list of addresses in a panel to which I wish to add geolocation coordinates (and to display them on a map) that is rendered in a form panel, so that when I click on the address of interest in the panel an onTap is fired to do execute the onSelectGeolocation given below to open the form panel rendered in the ViewPort and to add any existing records to the associated form elements:
onSelectGeolocation: function(view, index, target, record, event) {
console.log('Selected a Geolocation from the list');
var geolocationForm = Ext.Viewport.down('geolocationEdit');
if(!geolocationForm){
geolocationForm = Ext.widget('geolocationEdit');
}
geolocationForm.setRecord(record);
geolocationForm.showBy(target);
}
The line that uses the setRecord method to write any existing records in my store to the form elements, however, is preventing the default values in my form panel below from getting written to the desired form elements. When I comment this out, all is good. Problem is that I need to grab those records that exist in my store, e.g., address, to display in my form. How can I do this AND write default values to my textfield elements in my form?
My form panel that is rendered as a ViewPort via the onTap is:
Ext.define('EvaluateIt.view.GeolocationEdit', {
extend: 'Ext.form.Panel',
alias : 'widget.geolocationEdit',
requires: [
'Ext.form.Panel',
'Ext.form.FieldSet',
'Ext.field.Number',
'Ext.field.DatePicker',
'Ext.field.Select',
'Ext.field.Hidden'
],
config: {
// We give it a left and top property to make it floating by default
left: 0,
top: 0,
// Make it modal so you can click the mask to hide the overlay
modal: true,
hideOnMaskTap: true,
// Set the width and height of the panel
width: 400,
height: 330,
scrollable: true,
layout: {
type: 'vbox'
},
defaults: {
margin: '0 0 5 0',
labelWidth: '40%',
labelWrap: true
},
items: [
{
xtype: 'datepickerfield',
destroyPickerOnHide: true,
name : 'datOfEvaluatione',
label: 'Date of evaluation',
value: new Date(),
picker: {
yearFrom: 1990
}
},
{
xtype: 'textfield',
name: 'address',
label: 'Address',
itemId: 'address'
},
{
xtype: 'textfield',
name: 'latitude',
label: 'Latitude',
itemId: 'latitude',
value: sessionStorage.latitude,
},
/* {
xtype: 'textfield',
name: 'longitude',
label: 'Longitude',
itemId: 'longitude',
value: sessionStorage.longitude
},
{
xtype: 'textfield',
name: 'accuracy',
label: 'Accuracy',
itemId: 'accuracy',
value: sessionStorage.accuracy
},*/
{
xtype: 'button',
itemId: 'save',
text: 'Save'
}
]
}
});
Behavior is as expected. I will use Ext.getCmp on the id's for each item instead.