---
title: "Row Grouping - Multiple Group Columns"
enterprise: true
framework: vue
version: "36.1.0"
---

# Row Grouping - Multiple Group Columns

Display the group structure with one group column representing each level of row grouping.

#### Enabling Single Group Column

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  RowGroupingDisplayType,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, RowGroupingModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :autoGroupColumnDef="autoGroupColumnDef"
      :groupDisplayType="groupDisplayType"
      :groupDefaultExpanded="groupDefaultExpanded"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "country", rowGroup: true, hide: true },
      { field: "year", rowGroup: true, hide: true },
      { field: "athlete" },
      { field: "sport" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 100,
    });
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      minWidth: 200,
    });
    const groupDisplayType = ref<RowGroupingDisplayType>("multipleColumns");
    const groupDefaultExpanded = ref(1);
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      autoGroupColumnDef,
      groupDisplayType,
      groupDefaultExpanded,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Enabling Single Group Column](https://www.ag-grid.com/examples/grouping-multiple-group-columns/enabling-multiple-group-column/vue3/)

## Enabling Multiple Group Columns

The example above demonstrates that both `country` and `year` are grouped. One group column is used to display the group value cells for each column that was grouped.

Multiple Group Columns can be enabled by setting the `groupDisplayType` grid option to `"multipleColumns"` as shown below:

```ts
<ag-grid-vue
    :groupDisplayType="groupDisplayType"
    /* other grid options ... */>
</ag-grid-vue>

this.groupDisplayType = 'multipleColumns';
```

## Configuration

The columns are added to the grid when row grouping is present, and can be configured via the `autoGroupColumnDef` grid option to define [Column Options](https://www.ag-grid.com/vue-data-grid/column-properties/).

#### Multiple Group Column Configuration

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  HeaderValueGetterParams,
  ModuleRegistry,
  RowGroupingDisplayType,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, RowGroupingModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :autoGroupColumnDef="autoGroupColumnDef"
      :groupDisplayType="groupDisplayType"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { headerName: "Country", field: "country", rowGroup: true, hide: true },
      { headerName: "Year", field: "year", rowGroup: true, hide: true },
      { field: "athlete" },
      { field: "sport" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 100,
    });
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      headerValueGetter: (params: HeaderValueGetterParams) =>
        `${params.colDef.headerName} Group Column`,
      minWidth: 220,
      cellRendererParams: {
        suppressCount: true,
      },
    });
    const groupDisplayType = ref<RowGroupingDisplayType>("multipleColumns");
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      autoGroupColumnDef,
      groupDisplayType,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Multiple Group Column Configuration](https://www.ag-grid.com/examples/grouping-multiple-group-columns/multiple-group-column-configuration/vue3/)

The example above uses the configuration demonstrated below to change the column's header name and apply a minimum width. It also [Configures the Group Cell Component](https://www.ag-grid.com/vue-data-grid/grouping-multiple-group-columns/#cell-component) using the `cellRendererParams` option to remove the count from each row group.

```ts
<ag-grid-vue
    :autoGroupColumnDef="autoGroupColumnDef"
    /* other grid options ... */>
</ag-grid-vue>

this.autoGroupColumnDef = {
    headerValueGetter: params => `${params.colDef.headerName} Group Column`,
    minWidth: 220,
    cellRendererParams: {
        suppressCount: true,
    }
};
```

### Display the Parent Group Value

The group hierarchy is represented by relative location to the parent. When scrolling through the grid it can become harder to keep track of the parent group value.

Setting the grid property `showOpenedGroup` to `true` will show the value of the parent group inside the group column.

#### Show Opened Groups Many Columns

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  RowGroupingDisplayType,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, RowGroupingModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :autoGroupColumnDef="autoGroupColumnDef"
      :groupDisplayType="groupDisplayType"
      :showOpenedGroup="true"
      :groupDefaultExpanded="groupDefaultExpanded"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "country", rowGroup: true, hide: true },
      { field: "year", rowGroup: true, hide: true },
      { field: "athlete" },
      { field: "sport" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 150,
    });
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      minWidth: 220,
    });
    const groupDisplayType = ref<RowGroupingDisplayType>("multipleColumns");
    const groupDefaultExpanded = ref(-1);
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      autoGroupColumnDef,
      groupDisplayType,
      groupDefaultExpanded,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Show Opened Groups Many Columns](https://www.ag-grid.com/examples/grouping-multiple-group-columns/show-opened-groups-many-columns/vue3/)

The example above demonstrates the following configuration to show the parent group value inside the group column:

```ts
<ag-grid-vue
    :showOpenedGroup="showOpenedGroup"
    /* other grid options ... */>
</ag-grid-vue>

this.showOpenedGroup = true;
```

## Cell Component

The group columns use the `agGroupCellRenderer` component to display the group information, as well as the chevron control for expanding and collapsing rows. The renderer also embeds the grouped columns renderer and displays this inside of the group cell.

This can be configured with several [Group Renderer Properties](https://www.ag-grid.com/vue-data-grid/grouping-multiple-group-columns/#configurable-options) using the `autoGroupColumnDef` property `cellRendererParams`. The example below removes the row count and enables checkboxes for row selection.

#### Group Cell Renderer Configuration

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  RowGroupingDisplayType,
  RowSelectionModule,
  RowSelectionOptions,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import CustomMedalCellRenderer from "./customMedalCellRendererVue";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  RowSelectionModule,
  ClientSideRowModelModule,
  RowGroupingModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :autoGroupColumnDef="autoGroupColumnDef"
      :groupDisplayType="groupDisplayType"
      :rowSelection="rowSelection"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    CustomMedalCellRenderer,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      {
        field: "total",
        rowGroup: true,
        cellRenderer: "CustomMedalCellRenderer",
      },
      { field: "year" },
      { field: "athlete" },
      { field: "sport" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 100,
    });
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      headerName: "Gold Medals",
      minWidth: 240,
      cellRendererParams: {
        suppressCount: true,
      },
    });
    const groupDisplayType = ref<RowGroupingDisplayType>("multipleColumns");
    const rowSelection = ref<RowSelectionOptions | "single" | "multiple">({
      mode: "singleRow",
      checkboxLocation: "autoGroupColumn",
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      autoGroupColumnDef,
      groupDisplayType,
      rowSelection,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Group Cell Renderer Configuration](https://www.ag-grid.com/examples/grouping-multiple-group-columns/renderer-config-group-cell/vue3/)

The example above demonstrates the following configuration:

```ts
<ag-grid-vue
    :columnDefs="columnDefs"
    :autoGroupColumnDef="autoGroupColumnDef"
    :rowSelection="rowSelection"
    /* other grid options ... */>
</ag-grid-vue>

this.columnDefs = [
    { field: 'total', rowGroup: true, cellRenderer: CustomMedalCellRenderer },
    // ... other column definitions
];
this.autoGroupColumnDef = {
    cellRendererParams: {
        suppressCount: true,
    }
};
this.rowSelection = {
    mode: 'singleRow',
    checkboxLocation: 'autoGroupColumn',
};
```

### Configurable Options

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `suppressPadding` | `boolean` |  |  | Set to `true` to not include any padding (indentation) in the child rows. |
| `suppressDoubleClickExpand` | `boolean` |  |  | Set to `true` to suppress expand on double click. |
| `suppressEnterExpand` | `boolean` |  |  | Set to `true` to suppress expand on ↵ Enter |
| `totalValueGetter` | `string \| TotalValueGetterFunc` |  |  | The value getter for the total row text. Can be a function or expression. |
| `suppressCount` | `boolean` |  |  | If `true`, count is not displayed beside the name. |
| `innerRenderer` | `any` |  |  | The renderer to use for inside the cell (after grouping functions are added) |
| `innerRendererParams` | `any` |  |  | Additional params to customise to the `innerRenderer`. |
| `innerRendererSelector` | `CellRendererSelectorFunc` |  |  | Callback to enable different innerRenderers to be used based of value of params. |

### Checkbox Selection

The `agGroupCellRenderer` can be configured to show checkboxes for row selection. Setting the [Row Selection](https://www.ag-grid.com/vue-data-grid/row-selection/) `checkboxLocation` property to `'autoGroupColumn'` hides the [Checkbox Column](https://www.ag-grid.com/vue-data-grid/row-selection-single-row/#customising-the-checkbox-column) instead using the group cell renderer to display checkboxes.

Setting `groupSelects` to `'descendants'` causes selecting a group row to also select all of its children.

#### Group Cell Renderer Checkbox Selection

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  RowGroupingDisplayType,
  RowSelectionModule,
  RowSelectionOptions,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  RowSelectionModule,
  ClientSideRowModelModule,
  RowGroupingModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :groupDisplayType="groupDisplayType"
      :rowSelection="rowSelection"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "country", rowGroup: true, hide: true },
      { field: "sport", rowGroup: true, hide: true },
      { field: "athlete" },
      { field: "year" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 100,
    });
    const groupDisplayType = ref<RowGroupingDisplayType>("multipleColumns");
    const rowSelection = ref<RowSelectionOptions | "single" | "multiple">({
      mode: "multiRow",
      groupSelects: "descendants",
      selectAll: "all",
      checkboxLocation: "autoGroupColumn",
    });
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      groupDisplayType,
      rowSelection,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Group Cell Renderer Checkbox Selection](https://www.ag-grid.com/examples/grouping-multiple-group-columns/renderer-config-checkbox/vue3/)

The example above demonstrates the following configuration:

```ts
<ag-grid-vue
    :rowSelection="rowSelection"
    /* other grid options ... */>
</ag-grid-vue>

this.rowSelection = {
    mode: 'multiRow',
    groupSelects: 'descendants',
    selectAll: 'all',
    checkboxLocation: 'autoGroupColumn',
};
```

### Custom Inner Renderer

When using the group cell renderer, the `agGroupCellRenderer` component will inherit the grouped columns renderer and display this inside of the group cell, adjacent to any configured checkboxes, cell count, and the expand/collapse chevron control.

This inner renderer can be overridden with a [Custom Cell Component](https://www.ag-grid.com/vue-data-grid/component-cell-renderer/) by setting the `innerRenderer` and `innerRendererParams` properties on the `cellRendererParams` configuration.

#### Group Cell Renderer Configuration

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";

import type { ColDef, GridApi, GridReadyEvent } from "ag-grid-community";
import {
  ClientSideRowModelModule,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { AgGridVue } from "ag-grid-vue3";

import CustomMedalCellRenderer from "./customMedalCellRenderer";
import "./styles.css";

// Enable extended validations only for development
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, RowGroupingModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
            <ag-grid-vue
              style="width: 100%; height: 100%;"
              :columnDefs="columnDefs"
              @grid-ready="onGridReady"
              :defaultColDef="defaultColDef"
              :autoGroupColumnDef="autoGroupColumnDef"
              :groupDisplayType="groupDisplayType"
              :rowData="rowData">
            </ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    CustomMedalCellRenderer,
  },
  setup(props) {
    const columnDefs = ref<ColDef[]>([
      { field: "total", rowGroup: true },
      { field: "country" },
      { field: "year" },
      { field: "athlete" },
      { field: "sport" },
    ]);
    const gridApi = shallowRef<GridApi | null>(null);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 100,
    });
    const autoGroupColumnDef = ref<ColDef>({
      headerName: "Gold Medals",
      minWidth: 220,
      cellRendererParams: {
        suppressCount: true,
        innerRenderer: "CustomMedalCellRenderer",
      },
    });
    const groupDisplayType = ref(null);
    const rowData = ref(null);

    onBeforeMount(() => {
      groupDisplayType.value = "multipleColumns";
    });

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      columnDefs,
      gridApi,
      defaultColDef,
      autoGroupColumnDef,
      groupDisplayType,
      rowData,
      onGridReady,
    };
  },
});

createApp(VueExample).mount("#app");
```

[Live example: Group Cell Renderer Configuration](https://www.ag-grid.com/examples/grouping-multiple-group-columns/renderer-config-inner/vue3/)

The example above uses the following configuration to provide a custom inner renderer to the group column:

```ts
<ag-grid-vue
    :autoGroupColumnDef="autoGroupColumnDef"
    /* other grid options ... */>
</ag-grid-vue>

this.autoGroupColumnDef = {
    cellRendererParams: {
        innerRenderer: CustomMedalCellRenderer,
    },
};
```

### Custom Cell Renderer

The Group Cell Renderer can be entirely replaced with a [Custom Cell Component](https://www.ag-grid.com/vue-data-grid/component-cell-renderer/) by setting the `cellRenderer` property on the `autoGroupColumnDef` configuration.

#### Custom Group Cell Renderer

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  AutoGroupColumnDef,
  CellDoubleClickedEvent,
  CellKeyDownEvent,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  RowGroupingDisplayType,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import CustomGroupCellRenderer from "./customGroupCellRendererVue";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, RowGroupingModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :autoGroupColumnDef="autoGroupColumnDef"
      :defaultColDef="defaultColDef"
      :groupDefaultExpanded="groupDefaultExpanded"
      :groupDisplayType="groupDisplayType"
      :rowData="rowData"
      @cell-double-clicked="onCellDoubleClicked"
      @cell-key-down="onCellKeyDown"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
    CustomGroupCellRenderer,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      {
        field: "country",
        rowGroup: true,
        hide: true,
      },
      {
        field: "year",
        rowGroup: true,
        hide: true,
      },
      {
        field: "athlete",
      },
      {
        field: "total",
        aggFunc: "sum",
      },
    ]);
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      cellRenderer: "CustomGroupCellRenderer",
    });
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 120,
    });
    const groupDefaultExpanded = ref(1);
    const groupDisplayType = ref<RowGroupingDisplayType>("multipleColumns");
    const rowData = ref<IOlympicData[]>(null);

    function onCellDoubleClicked(
      params: CellDoubleClickedEvent<IOlympicData, any>,
    ) {
      if (params.colDef.showRowGroup) {
        params.node.setExpanded(!params.node.expanded);
      }
    }
    function onCellKeyDown(params: CellKeyDownEvent<IOlympicData, any>) {
      if (!("colDef" in params)) {
        return;
      }
      if (!(params.event instanceof KeyboardEvent)) {
        return;
      }
      if (params.event.code !== "Enter") {
        return;
      }
      if (params.colDef.showRowGroup) {
        params.node.setExpanded(!params.node.expanded);
      }
    }
    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/small-olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      autoGroupColumnDef,
      defaultColDef,
      groupDefaultExpanded,
      groupDisplayType,
      rowData,
      onGridReady,
      onCellDoubleClicked,
      onCellKeyDown,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Custom Group Cell Renderer](https://www.ag-grid.com/examples/grouping-multiple-group-columns/renderer-config-custom/vue3/)

> **Note**
>
> It is also possible to [Determine Cell Renderers Dynamically](https://www.ag-grid.com/vue-data-grid/component-cell-renderer/#providing-custom-components-dynamically).

## Filtering

To enable filters on the group column, set the `filter` property of the `autoGroupColumnDef` to `'agGroupColumnFilter'`. This configuration will cause the group column to inherit the filter from the column it is representing.

#### Group Column Filtering

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  NumberFilterModule,
  RowGroupingDisplayType,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import {
  GroupFilterModule,
  RowGroupingModule,
  SetFilterModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  NumberFilterModule,
  ClientSideRowModelModule,
  RowGroupingModule,
  SetFilterModule,
  GroupFilterModule,
  TextFilterModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :autoGroupColumnDef="autoGroupColumnDef"
      :groupDefaultExpanded="groupDefaultExpanded"
      :groupDisplayType="groupDisplayType"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      {
        field: "country",
        rowGroup: true,
        hide: true,
        filter: "agTextColumnFilter",
      },
      { field: "year", rowGroup: true, hide: true, filter: true },
      { field: "athlete" },
      { field: "sport" },
      { field: "total" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 100,
    });
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      minWidth: 200,
      filter: "agGroupColumnFilter",
      floatingFilter: true,
    });
    const groupDefaultExpanded = ref(1);
    const groupDisplayType = ref<RowGroupingDisplayType>("multipleColumns");
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      autoGroupColumnDef,
      groupDefaultExpanded,
      groupDisplayType,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Group Column Filtering](https://www.ag-grid.com/examples/grouping-multiple-group-columns/filtering-grouped-columns/vue3/)

> **Note**
>
> When the column with row grouping enabled is also visible, the corresponding group column floating filter will be in read-only mode.

The example above demonstrates the following configuration to inherit the filter from the grouped column:

```ts
<ag-grid-vue
    :autoGroupColumnDef="autoGroupColumnDef"
    /* other grid options ... */>
</ag-grid-vue>

this.autoGroupColumnDef = {
    filter: 'agGroupColumnFilter',
    floatingFilter: true,
};
```

## Hiding Expanded Parent Rows

Expanded rows can be configured to disappear when they are open, instead moving the group cell renderer into the first child row. To enable this feature set the `groupHideOpenParents` grid option to `true`.

#### Hide Open Parents

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  RowGroupingDisplayType,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ColumnsToolPanelModule,
  ContextMenuModule,
  RowGroupingModule,
  SetFilterModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
  RowGroupingModule,
  SetFilterModule,
]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <div class="example-wrapper">
      <div class="example-header">
        <span class="legend-item ag-row-level-0"></span>
        <span class="legend-label">Top Level Group</span>
        <span class="legend-item ag-row-level-1"></span>
        <span class="legend-label">Second Level Group</span>
        <span class="legend-item ag-row-level-2"></span>
        <span class="legend-label">Bottom Rows</span>
      </div>
      <ag-grid-vue
        style="width: 100%; height: 100%;"
        @grid-ready="onGridReady"
        :columnDefs="columnDefs"
        :defaultColDef="defaultColDef"
        :autoGroupColumnDef="autoGroupColumnDef"
        :groupHideOpenParents="true"
        :groupDisplayType="groupDisplayType"
        :rowData="rowData"></ag-grid-vue>
      </div>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "country", rowGroup: true, hide: true },
      { field: "year", rowGroup: true, hide: true },
      { field: "athlete", minWidth: 200 },
      { field: "total", aggFunc: "sum" },
    ]);
    const defaultColDef = ref<ColDef>({
      flex: 1,
      minWidth: 150,
    });
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      minWidth: 200,
    });
    const groupDisplayType = ref<RowGroupingDisplayType>("multipleColumns");
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      autoGroupColumnDef,
      groupDisplayType,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Hide Open Parents](https://www.ag-grid.com/examples/grouping-multiple-group-columns/hide-open-parents/vue3/)

> **Note**
>
> When `groupHideOpenParents` is enabled the grid no longer sticks expanded group rows to the top of the viewport.

The example above demonstrates the following configuration to hide open parents:

```ts
<ag-grid-vue
    :groupHideOpenParents="groupHideOpenParents"
    /* other grid options ... */>
</ag-grid-vue>

this.groupHideOpenParents = true;
```

## Hiding Group Columns Until Expanded

By default all group columns are visible at all times. Setting `groupHideColumnsUntilExpanded` to `true` hides group columns for levels that have not yet been reached through expansion. Only the top-level group column is initially visible; each subsequent level's column becomes visible when at least one group at the preceding level is expanded.

Try expanding a Country row to reveal the Year group column, then expand a Year row to reveal the Sport group column. Collapsing all rows at a given level will hide the corresponding group column again.

#### Hide Group Columns Until Expanded

```ts
import {
  createApp,
  defineComponent,
  onBeforeMount,
  ref,
  shallowRef,
} from "vue";
import { AgGridVue } from "ag-grid-vue3";
import {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  RowGroupingDisplayType,
  enableDevValidations,
} from "ag-grid-community";
import { RowGroupingModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

ModuleRegistry.registerModules([ClientSideRowModelModule, RowGroupingModule]);

const VueExample = defineComponent({
  template: `
        <div style="height: 100%">
                <ag-grid-vue
      style="width: 100%; height: 100%;"
      @grid-ready="onGridReady"
      :columnDefs="columnDefs"
      :defaultColDef="defaultColDef"
      :autoGroupColumnDef="autoGroupColumnDef"
      :groupDisplayType="groupDisplayType"
      :groupHideColumnsUntilExpanded="true"
      :groupDefaultExpanded="groupDefaultExpanded"
      :rowData="rowData"></ag-grid-vue>
        </div>
    `,
  components: {
    "ag-grid-vue": AgGridVue,
  },
  setup(props) {
    const gridApi = shallowRef<GridApi<IOlympicData> | null>(null);
    const columnDefs = ref<ColDef[]>([
      { field: "country", rowGroup: true, hide: true },
      { field: "year", rowGroup: true, hide: true },
      { field: "sport", rowGroup: true, hide: true },
      { field: "athlete", minWidth: 200, aggFunc: "count" },
      { field: "total", aggFunc: "sum" },
    ]);
    const defaultColDef = ref<ColDef>({
      minWidth: 150,
    });
    const autoGroupColumnDef = ref<AutoGroupColumnDef>({
      minWidth: 200,
    });
    const groupDisplayType = ref<RowGroupingDisplayType>("multipleColumns");
    const groupDefaultExpanded = ref(0);
    const rowData = ref<IOlympicData[]>(null);

    const onGridReady = (params: GridReadyEvent) => {
      gridApi.value = params.api;

      const updateData = (data) => (rowData.value = data);

      fetch("https://www.ag-grid.com/example-assets/olympic-winners.json")
        .then((resp) => resp.json())
        .then((data) => updateData(data));
    };

    return {
      gridApi,
      columnDefs,
      defaultColDef,
      autoGroupColumnDef,
      groupDisplayType,
      groupDefaultExpanded,
      rowData,
      onGridReady,
    };
  },
});

const app = createApp(VueExample);
app.mount("#app");
```

[Live example: Hide Group Columns Until Expanded](https://www.ag-grid.com/examples/grouping-multiple-group-columns/hide-columns-until-expanded/vue3/)

The example above demonstrates the following configuration:

```ts
<ag-grid-vue
    :groupDisplayType="groupDisplayType"
    :groupHideColumnsUntilExpanded="groupHideColumnsUntilExpanded"
    /* other grid options ... */>
</ag-grid-vue>

this.groupDisplayType = 'multipleColumns';
this.groupHideColumnsUntilExpanded = true;
```
