In this article we learn how to create Nested AgGrid table in React App.
First open our React project and install AgGrid dependency.
npm install ag-grid-community npm install ag-grid-react npm install ag-grid-enterprise
Then import CSS from ag-grid-community.
import 'ag-grid-community/dist/styles/ag-grid.css'; import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
Using the Component:
- Create a ref to the component that will later be used for the export
const gridRef = useRef();
AgGrid table ColumnData:
const [columnDefs, setColumnDefs] = useState([ { field: 'name', cellRenderer: 'agGroupCellRenderer', width: 150, height: 150, filter: true, }, { field: 'account' }, { field: 'calls' }, { field: 'minutes', valueFormatter: "x.toLocaleString() + 'm'" }, ]);
AgGrid table RowData:
const [rowData, setRowData] = useState( [{ "name": "Nora Thomas", "account": 177000, "calls": 24, "minutes": 25.65, "callRecords": [{ "name": "susan", "callId": 555, "duration": 72, "switchCode": "SW3", "direction": "Out", "number": "(00) 88542069" }, { "name": "susan", "callId": 574, "duration": 24, "switchCode": "SW4", "direction": "In", "number": "(05) 33983060" },] }, { "name": "Mila Smith", "account": 177001, "calls": 24, "minutes": 26.216666666666665, "callRecords": [{ "name": "susan", "callId": 579, "duration": 23, "switchCode": "SW5", "direction": "Out", "number": "(02) 47485405" }, { "name": "susan", "callId": 598, "duration": 49, "switchCode": "SW4", "direction": "Out", "number": "(09) 37470979" },] } ] );
For nested table data we want to pass detailCellRendererParams in AgGrid react and its data is :
const detailCellRendererParams = useMemo(() => { return { detailGridOptions: { rowSelection: 'multiple', suppressRowClickSelection: true, enableRangeSelection: true, pagination: true, paginationAutoPageSize: true, columnDefs: [ { field: 'callId', }, { field: 'direction', }, { field: 'number', minWidth: 150, }, { field: 'duration', valueFormatter: "x.toLocaleString() + 's'", }, { field: 'switchCode', minWidth: 150, }, ], defaultColDef: { sortable: true, flex: 1, }, }, getDetailRowData: (params) => { params.successCallback(params.data.callRecords); }, }; }, []);
Here row data property match with the column data field name and set data in the table.
Now import AgGridReact in ag-grid-react.
import { AgGridReact } from 'ag-grid-react';
<AgGridReact ref={gridRef} rowData={rowData} columnDefs={columnDefs} defaultColDef={defaultColDef} masterDetail={true} detailCellRendererParams={detailCellRendererParams} />
My page will look like this
import React, { useMemo, useRef, useState } from 'react'; import { AgGridReact } from 'ag-grid-react'; import 'ag-grid-enterprise'; import 'ag-grid-community/dist/styles/ag-grid.css'; import 'ag-grid-community/dist/styles/ag-theme-alpine.css'; export const App = () => { const gridRef = useRef(); const containerStyle = useMemo(() => ({ width: '100vh', height: '100vh' }), []); const gridStyle = useMemo(() => ({ height: '100%', width: '100%' }), []); const [rowData, setRowData] = useState( [{ "name": "Nora Thomas", "account": 177000, "calls": 24, "minutes": 25.65, "callRecords": [{ "name": "susan", "callId": 555, "duration": 72, "switchCode": "SW3", "direction": "Out", "number": "(00) 88542069" }, { "name": "susan", "callId": 574, "duration": 24, "switchCode": "SW4", "direction": "In", "number": "(05) 33983060" }] }, { "name": "Mila Smith", "account": 177001, "calls": 24, "minutes": 26.216666666666665, "callRecords": [{ "name": "susan", "callId": 579, "duration": 23, "switchCode": "SW5", "direction": "Out", "number": "(02) 47485405" }, { "name": "susan", "callId": 598, "duration": 49, "switchCode": "SW4", "direction": "Out", "number": "(09) 37470979" }] }] ); const [columnDefs, setColumnDefs] = useState([ { field: 'name', cellRenderer: 'agGroupCellRenderer', width: 150, height: 150, filter: true, }, { field: 'account' }, { field: 'calls' }, { field: 'minutes', valueFormatter: "x.toLocaleString() + 'm'" }, ]); const defaultColDef = useMemo(() => { return { flex: 1, }; }, []); const detailCellRendererParams = useMemo(() => { return { detailGridOptions: { rowSelection: 'multiple', suppressRowClickSelection: true, enableRangeSelection: true, pagination: true, paginationAutoPageSize: true, columnDefs: [ { field: 'callId', }, { field: 'direction', }, { field: 'number', minWidth: 150, }, { field: 'duration', valueFormatter: "x.toLocaleString() + 's'", }, { field: 'switchCode', minWidth: 150, }, ], defaultColDef: { sortable: true, flex: 1, }, }, getDetailRowData: (params) => { params.successCallback(params.data.callRecords); }, }; }, []); return ( <div style={containerStyle}> <div style={gridStyle} className="ag-theme-alpine"> <AgGridReact ref={gridRef} rowData={rowData} columnDefs={columnDefs} defaultColDef={defaultColDef} masterDetail={true} detailCellRendererParams={detailCellRendererParams} /> </div> </div> ); };
Output: