# grid-grouping

> Data grid groups orders by field while supporting paging, filtering, sorting, and editing.

**Framework:** react  **Component:** Grid  **Variant:** grouping

## Get this item

**If you are an agent, fetch the JSON.** Source is inlined, so one request is enough and no tooling is required:

```
GET https://ai.syncfusion.com/r/react/ts/grid-grouping.json
```

**Install Package(s)**

```bash
npm install @syncfusion/ej2-react-grids @syncfusion/ej2-react-popups
```

**Notes**

- Syncfusion release: 2026 Volume 2 (v34.1.29)
- The Syncfusion package is licensed. The composition in this file is source you own and edit. See https://ai.syncfusion.com/licensing.md

## Source files

### src/components/grid-grouping/Grid.tsx

```tsx
import { GridComponent, ColumnsDirective, ColumnDirective, Page, Edit, Toolbar, Group, Sort, Inject, type FilterSettingsModel, Filter } from '@syncfusion/ej2-react-grids';
import { DialogComponent } from '@syncfusion/ej2-react-popups';
let refresh: Boolean;

const purchaseData = JSON.stringify([
    {
        'OrderID': 10248,
        'CustomerID': 'VINET',
        'OrderDate': '1996-07-04T10:10:00.000Z',
        'ShippedDate': '1996-07-16T12:20:00.000Z',
        'Freight': 32.38,
        'ShipName': 'Vins et alcools Chevalier',
        'ShipAddress': '59 rue de l\'Abbaye',
        'ShipCity': 'Reims',
        'ShipRegion': null,
        'ShipCountry': 'France'
    },
    {
        'OrderID': 10249,
        'CustomerID': 'TOMSP',
        'OrderDate': '1996-07-05T12:20:00.000Z',
        'ShippedDate': '1996-07-10T13:20:00.000Z',
        'Freight': 11.61,
        'ShipName': 'Toms Spezialitäten',
        'ShipAddress': 'Luisenstr. 48',
        'ShipCity': 'Münster',
        'ShipRegion': null,
        'ShipCountry': 'Germany'
    },
    {
        'OrderID': 10250,
        'CustomerID': 'HANAR',
        'OrderDate': '1996-07-08T08:40:00.000Z',
        'ShippedDate': '1996-07-12T07:50:00.000Z',
        'Freight': 65.83,
        'ShipName': 'Hanari Carnes',
        'ShipAddress': 'Rua do Paço, 67',
        'ShipCity': 'Rio de Janeiro',
        'ShipRegion': 'RJ',
        'ShipCountry': 'Brazil'
    },
    {
        'OrderID': 10251,
        'CustomerID': 'VICTE',
        'OrderDate': '1996-07-08T07:50:00.000Z',
        'ShippedDate': '1996-07-15T15:50:00.000Z',
        'Freight': 41.34,
        'ShipName': 'Victuailles en stock',
        'ShipAddress': '2, rue du Commerce',
        'ShipCity': 'Lyon',
        'ShipRegion': null,
        'ShipCountry': 'France'
    },
    {
        'OrderID': 10252,
        'CustomerID': 'SUPRD',
        'OrderDate': '1996-07-09T12:05:00.000Z',
        'ShippedDate': '1996-07-11T17:30:00.000Z',
        'Freight': 51.3,
        'ShipName': 'Suprêmes délices',
        'ShipAddress': 'Boulevard Tirou, 255',
        'ShipCity': 'Charleroi',
        'ShipRegion': null,
        'ShipCountry': 'Belgium'
    },
    {
        'OrderID': 10253,
        'CustomerID': 'HANAR',
        'OrderDate': '1996-07-10T11:20:00.000Z',
        'ShippedDate': '1996-07-16T10:10:00.000Z',
        'Freight': 58.17,
        'ShipName': 'Hanari Carnes',
        'ShipAddress': 'Rua do Paço, 67',
        'ShipCity': 'Rio de Janeiro',
        'ShipRegion': 'RJ',
        'ShipCountry': 'Brazil'
    },
    {
        'OrderID': 10254,
        'CustomerID': 'CHOPS',
        'OrderDate': '1996-07-11T10:00.00.000Z',
        'ShippedDate': '1996-07-23T20:40:00.000Z',
        'Freight': 22.98,
        'ShipName': 'Chop-suey Chinese',
        'ShipAddress': 'Hauptstr. 31',
        'ShipCity': 'Bern',
        'ShipRegion': null,
        'ShipCountry': 'Switzerland'
    },
    {
        'OrderID': 10255,
        'CustomerID': 'RICSU',
        'OrderDate': '1996-07-12T10:40:00.000Z',
        'ShippedDate': '1996-07-15T05:40:00.000Z',
        'Freight': 148.33,
        'ShipName': 'Richter Supermarkt',
        'ShipAddress': 'Starenweg 5',
        'ShipCity': 'Genève',
        'ShipRegion': null,
        'ShipCountry': 'Switzerland'
    },
    {
        'OrderID': 10256,
        'CustomerID': 'WELLI',
        'OrderDate': '1996-07-15T20:50:00.000Z',
        'ShippedDate': '1996-07-17T21:50:00.000Z',
        'Freight': 13.97,
        'ShipName': 'Wellington Importadora',
        'ShipAddress': 'Rua do Mercado, 12',
        'ShipCity': 'Resende',
        'ShipRegion': 'SP',
        'ShipCountry': 'Brazil'
    },
    {
        'OrderID': 10257,
        'CustomerID': 'HILAA',
        'OrderDate': '1996-07-16T03:20:00.000Z',
        'ShippedDate': '1996-07-22T14:40:00.000Z',
        'Freight': 81.91,
        'ShipName': 'HILARION-Abastos',
        'ShipAddress': 'Carrera 22 con Ave. Carlos Soublette #8-35',
        'ShipCity': 'San Cristóbal',
        'ShipRegion': 'Táchira',
        'ShipCountry': 'Venezuela'
    },
    {
        'OrderID': 10258,
        'CustomerID': 'ERNSH',
        'OrderDate': '1996-07-17T18:30:00.000Z',
        'ShippedDate': '1996-07-23T14:50:00.000Z',
        'Freight': 140.51,
        'ShipName': 'Ernst Handel',
        'ShipAddress': 'Kirchgasse 6',
        'ShipCity': 'Graz',
        'ShipRegion': null,
        'ShipCountry': 'Austria'
    },
    {
        'OrderID': 10259,
        'CustomerID': 'CENTC',
        'OrderDate': '1996-07-18T01:20:00.000Z',
        'ShippedDate': '1996-07-25T16:20:00.000Z',
        'Freight': 3.25,
        'ShipName': 'Centro comercial Moctezuma',
        'ShipAddress': 'Sierras de Granada 9993',
        'ShipCity': 'México D.F.',
        'ShipRegion': null,
        'ShipCountry': 'Mexico'
    },
    {
        'OrderID': 10260,
        'CustomerID': 'OTTIK',
        'OrderDate': '1996-07-19T11:20:00.000Z',
        'ShippedDate': '1996-07-29T03:10:00.000Z',
        'Freight': 55.09,
        'ShipName': 'Ottilies Käseladen',
        'ShipAddress': 'Mehrheimerstr. 369',
        'ShipCity': 'Köln',
        'ShipRegion': null,
        'ShipCountry': 'Germany'
    },
    {
        'OrderID': 10261,
        'CustomerID': 'QUEDE',
        'OrderDate': '1996-07-19T18:30:00.000Z',
        'ShippedDate': '1996-07-30T23:10:00.000Z',
        'Freight': 3.05,
        'ShipName': 'Que Delícia',
        'ShipAddress': 'Rua da Panificadora, 12',
        'ShipCity': 'Rio de Janeiro',
        'ShipRegion': 'RJ',
        'ShipCountry': 'Brazil'
    },
    {
        'OrderID': 10262,
        'CustomerID': 'RATTC',
        'OrderDate': '1996-07-22T21:40:00.000Z',
        'ShippedDate': '1996-07-25T19:10:00.000Z',
        'Freight': 48.29,
        'ShipName': 'Rattlesnake Canyon Grocery',
        'ShipAddress': '2817 Milton Dr.',
        'ShipCity': 'Albuquerque',
        'ShipRegion': 'NM',
        'ShipCountry': 'USA'
    }]);
const customerData = [
    {
        'CustomerID': 'ALFKI',
        'ContactName': 'Maria ',
        'CompanyName': 'Alfreds Futterkiste',
        'Address': 'Obere Str. 57',
        'Country': 'Germany'
    },
    {
        'CustomerID': 'ANATR',
        'ContactName': 'Ana Trujillo',
        'CompanyName': 'Ana Trujillo Emparedados y helados',
        'Address': 'Avda. de la Constitución 2222',
        'Country': 'Mexico'
    },
    {
        'CustomerID': 'ANTON',
        'ContactName': 'Antonio Moreno',
        'CompanyName': 'Antonio Moreno Taquería',
        'Address': 'Mataderos  2312',
        'Country': 'Mexico'
    },
    {
        'CustomerID': 'AROUT',
        'ContactName': 'Thomas Hardy',
        'CompanyName': 'Around the Horn',
        'Address': '120 Hanover Sq.',
        'Country': 'UK'
    },
    {
        'CustomerID': 'BERGS',
        'ContactName': 'Christina Berglund',
        'CompanyName': 'Berglunds snabbköp',
        'Address': 'Berguvsvägen  8',
        'Country': 'Sweden'
    },
    {
        'CustomerID': 'BLAUS',
        'ContactName': 'Hanna Moos',
        'CompanyName': 'Blauer See Delikatessen',
        'Address': 'Forsterstr. 57',
        'Country': 'Germany'
    },
    {
        'CustomerID': 'BLONP',
        'ContactName': 'Frédérique Citeaux',
        'CompanyName': 'Blondesddsl père et fils',
        'Address': '24, place Kléber',
        'Country': 'France'
    },
    {
        'CustomerID': 'BOLID',
        'ContactName': 'Martín Sommer',
        'CompanyName': 'Bólido Comidas preparadas',
        'Address': 'C/ Araquil, 67',
        'Country': 'Spain'
    },
    {
        'CustomerID': 'BONAP',
        'ContactName': 'Laurence Lebihan',
        'CompanyName': 'Bon app',
        'Address': '12, rue des Bouchers',
        'Country': 'France'
    },
    {
        'CustomerID': 'BOTTM',
        'ContactName': 'Elizabeth Lincoln',
        'CompanyName': 'Bottom-Dollar Markets',
        'Address': '23 Tsawassen Blvd.',
        'Country': 'Canada'
    },
    {
        'CustomerID': 'BSBEV',
        'ContactName': 'Victoria Ashworth',
        'CompanyName': 'B\'s Beverages',
        'Address': 'Fauntleroy Circus',
        'Country': 'UK'
    },
    {
        'CustomerID': 'CACTU',
        'ContactName': 'Patricio Simpson',
        'CompanyName': 'Cactus Comidas para llevar',
        'Address': 'Cerrito 333',
        'Country': 'Argentina'
    },
    {
        'CustomerID': 'CENTC',
        'ContactName': 'Francisco Chang',
        'CompanyName': 'Centro comercial Moctezuma',
        'Address': 'Sierras de Granada 9993',
        'Country': 'Mexico'
    },
    {
        'CustomerID': 'CHOPS',
        'ContactName': 'Yang Wang',
        'CompanyName': 'Chop-suey Chinese',
        'Address': 'Hauptstr. 29',
        'Country': 'Switzerland'
    },
    {
        'CustomerID': 'COMMI',
        'ContactName': 'Pedro Afonso',
        'CompanyName': 'Comércio Mineiro',
        'Address': 'Av. dos Lusíadas, 23',
        'Country': 'Brazil'
    },
    {
        'CustomerID': 'CONSH',
        'ContactName': 'Elizabeth Brown',
        'CompanyName': 'Consolidated Holdings',
        'Address': 'Berkeley Gardens 12  Brewery',
        'Country': 'UK'
    }];

export const orderDataSource = JSON.parse(purchaseData, (_field, value) => {
    if (typeof value === 'string' && /^\d{4}-\d\d-\d\dT/.test(value)) {
        return new Date(value);
    }
    return value;
});

const customerNames = new Map(customerData.map((customer) => [customer.CustomerID, customer.ContactName]));

export const data1 = orderDataSource.map((item) => ({
    ...item,
    CustomerName: customerNames.get(item.CustomerID) ?? item.CustomerID
}));

function Grouping() {
    const filterSettings: FilterSettingsModel = {type: 'Excel'};
    const toolbarOptions: any = ['Edit', 'Update', 'Cancel'];
    const editSettings: any = { allowEditing: true };
    const editparams: any = { params: { popupHeight: '300px' } };
    const validationRule: Object = { required: true };
    const orderidRules: Object = { required: true, number: true };
    const format: any = { type: 'dateTime', format: 'M/d/y hh:mm a' };

    const groupOptions: Object = { showGroupedColumn: false, columns: ['ShipCountry'] };
    let gridInstance: GridComponent;
    const visible = false;
    const animationSettings: Object = { effect: 'None' };
    let alertDialogInstance: DialogComponent;
    const alertButtons = [{
        click: () => {  
            alertDialogInstance.hide();
        },
        buttonModel: { content: 'OK', isPrimary: true }
    }];
    function dataBound() {
        if (refresh) {
            gridInstance.groupColumn('ShipCountry');
            refresh = false;
        }
    }
    function load() {
        refresh = (this as any).refreshing;
    }
    function columnDragStart(args) {
        if (args.column.field === 'OrderDate') {
            alertDialogInstance.show();
        }
    }
    function created() {
        gridInstance.on('columnDragStart', columnDragStart, this);
    }
    return (
        <div className='control-pane'>
            <div className='control-section'>
                <GridComponent dataSource={data1} allowPaging={true} ref={grid => gridInstance = grid} toolbar={toolbarOptions} pageSettings={{ pageCount: 5 }} allowFiltering={true} filterSettings={filterSettings} editSettings={editSettings} allowGrouping={true} groupSettings={groupOptions} allowSorting={true} height="320"
                    dataBound={dataBound.bind(this)} load={load} created={created}>
                    <ColumnsDirective>
                        <ColumnDirective field='OrderID' headerText='Order ID' width='140' textAlign='Right' validationRules={orderidRules} isPrimaryKey={true}></ColumnDirective>
                        <ColumnDirective field='CustomerName' headerText='Customer Name' width='150' validationRules={validationRule}></ColumnDirective>
                        <ColumnDirective field='Freight' headerText='Freight' width='140' format='C2' textAlign='Right' editType='numericedit' ></ColumnDirective>
                        <ColumnDirective field='OrderDate' headerText='Order Date' allowGrouping={false} editType='datetimepickeredit' format= {format} width='160' ></ColumnDirective>
                        <ColumnDirective field='ShipCountry' headerText='Ship Country' width='150' editType='dropdownedit' edit={editparams} ></ColumnDirective>
                    </ColumnsDirective>
                    <Inject services={[Page, Group, Sort, Edit, Toolbar, Filter]} />
                </GridComponent>
                <DialogComponent id="alertDialog" header='Grouping' visible={visible} animationSettings={animationSettings} width='300px' content='Grouping is disabled for this column' ref={alertdialog => alertDialogInstance = alertdialog} target='.control-section' buttons={alertButtons} ></DialogComponent>
                <div className="e-dsalign">Source:
                    <a href="https://en.wikipedia.org/wiki/List_of_prolific_inventors" target='_blank'>Wikipedia: List of Prolific inventors</a>
                </div>
            </div>
        </div>
    )
}
export default Grouping;
```
