---
product: "AG Grid"
title: "Column Chooser"
description: "The Column Chooser is a dialog that displays the grid's columns, allowing users to show, hide and reorder them. When column definitions contain groups, these are displayed as expandable rows containing their child columns."
enterprise: true
framework: react
version: "36.2.0"
related:
    - title: "Tool Panels"
      url: "https://www.ag-grid.com/react-data-grid/tool-panel/"
    - title: "Quick Access Toolbar"
      url: "https://www.ag-grid.com/react-data-grid/toolbar/"
    - title: "Column Menu"
      url: "https://www.ag-grid.com/react-data-grid/column-menu/"
    - title: "Context Menu"
      url: "https://www.ag-grid.com/react-data-grid/context-menu/"
    - title: "Menu Item Component"
      url: "https://www.ag-grid.com/react-data-grid/component-menu-item/"
    - title: "Status Bar"
      url: "https://www.ag-grid.com/react-data-grid/status-bar/"
llms: "https://www.ag-grid.com/llms.txt"
---

# Column Chooser

The Column Chooser is a dialog that displays the grid's columns, allowing users to show, hide and reorder them. When column definitions contain groups, these are displayed as expandable rows containing their child columns.

Open the Column Chooser by selecting **Choose Columns** from the [Column Menu](https://www.ag-grid.com/react-data-grid/column-menu/) or by calling `api.showColumnChooser()`. The same column selection panel is also available docked to the side of the grid as part of the [Columns Tool Panel](https://www.ag-grid.com/react-data-grid/tool-panel-columns/).

![AG Grid Column Chooser](https://www.ag-grid.com/_astro/screenshot.CGZfpizc.png)

## Customising the Column Chooser

The behaviour and appearance of the Column Chooser can be customised with `ColumnChooserParams`. Set `colDef.columnChooserParams` to configure the chooser opened from that column, or set `defaultColDef.columnChooserParams` to apply the same configuration to every column. When opening the chooser through the Grid API, the same options can instead be passed to `api.showColumnChooser(params)`. These options are unset by default.

`ColumnChooserParams` extends the shared `IColumnSelectionPanelParams` interface, so the same column selection options apply to the [Columns Tool Panel](https://www.ag-grid.com/react-data-grid/tool-panel-columns/#column-selection-panel-configuration), where they are set through `toolPanelParams` instead.

Properties available on the `ColumnChooserParams` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `columnLayout` | `(ColDef \| ColGroupDef)[]` |  |  |  |
| `suppressSyncLayoutWithGrid` | `boolean` |  |  |  |
| `suppressColumnFilter` | `boolean` |  |  |  |
| `suppressColumnSelectAll` | `boolean` |  |  |  |
| `suppressColumnExpandAll` | `boolean` |  |  |  |
| `contractColumnSelection` | `boolean` |  |  |  |
| `columnLabelRenderer` | `any` |  |  |  |
| `columnLabelRendererParams` | `any` |  |  |  |
| `columnLabelRendererSelector` | `ColumnSelectionLabelRendererSelectorFunc` |  |  |  |

The following example demonstrates the suppression and `contractColumnSelection` options above; the column label renderer options and `columnLayout` are covered in the sections below. Note the following:

- Launch the Column Chooser by selecting **Choose Columns** from any column menu.
- The Column Chooser opened from any column ignores column moves in the grid because `suppressSyncLayoutWithGrid=true` is set on the default column definition.
- The **Name** column's chooser does not show the column search, Select / Unselect All or Expand / Collapse All controls because `suppressColumnFilter`, `suppressColumnSelectAll` and `suppressColumnExpandAll` are all set to `true`.
- The **Age** column's chooser starts with column groups collapsed because `contractColumnSelection=true`.

#### Customising Column Chooser

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ColumnsToolPanelModule,
  ContextMenuModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      groupId: "athleteGroupId",
      headerName: "Athlete",
      children: [
        {
          headerName: "Name",
          field: "athlete",
          minWidth: 200,
          columnChooserParams: {
            // hides the Column Filter section
            suppressColumnFilter: true,
            // hides the Select / Un-select all widget
            suppressColumnSelectAll: true,
            // hides the Expand / Collapse all widget
            suppressColumnExpandAll: true,
          },
        },
        {
          field: "age",
          minWidth: 200,
          columnChooserParams: {
            // contracts all column groups
            contractColumnSelection: true,
          },
        },
      ],
    },
    {
      groupId: "medalsGroupId",
      headerName: "Medals",
      children: [{ field: "gold" }, { field: "silver" }, { field: "bronze" }],
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      columnChooserParams: {
        // suppresses updating the layout of columns as they are rearranged in the grid
        suppressSyncLayoutWithGrid: true,
      },
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Customising Column Chooser](https://www.ag-grid.com/examples/column-chooser/customising-column-chooser/reactFunctionalTs/)

## Custom Column Labels

Use `columnLabelRenderer` in `ColumnChooserParams` to replace the text shown for columns and column groups. The checkbox, drag handle and group expand controls remain grid managed. Additional properties can be supplied through `columnLabelRendererParams`.

Use `columnLabelRendererSelector` to select different renderers for individual columns or column groups. The selector can also provide renderer-specific `params`; returning `undefined` falls back to `columnLabelRenderer`.

```jsx
const components = {
    customColumnLabel: CustomColumnLabel,
};
const defaultColDef = useMemo(() => { 
	return {
        columnChooserParams: {
            columnLabelRenderer: 'customColumnLabel',
            columnLabelRendererParams: {
                columnIcon: '●',
                columnGroupIcon: '◆',
            },
        },
    };
}, []);

<AgGridReact
    components={components}
    defaultColDef={defaultColDef}
/>
```

For each label in the Column Chooser, the renderer receives the resolved `displayName` and either `column` or `columnGroup`, depending on the item being rendered. The `source` is always `'columnChooser'`. Setting these options on `defaultColDef.columnChooserParams` applies them to the chooser regardless of which column it is opened from. They can also be supplied when calling `api.showColumnChooser(params)`.

The Column Chooser does not automatically inherit a renderer configured for the [Columns Tool Panel](https://www.ag-grid.com/react-data-grid/tool-panel-columns/#custom-column-labels). To use the same presentation in both places, register the component once and reference its name from both configurations. Both `ColumnChooserParams` and `IToolPanelColumnCompParams` extend the shared `IColumnSelectionPanelParams` interface.

> **Note**
>
> Column search and accessibility announcements continue to use `displayName`, rather than text extracted from the renderer. Column selection rows have a fixed height, so renderer content should remain inline and fit within the configured list item height.

#### Custom Column Labels

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  Components,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { ColumnMenuModule, ColumnsToolPanelModule } from "ag-grid-enterprise";
import CustomColumnLabel from "./customColumnLabel.tsx";

if (process.env.NODE_ENV !== "production") {
  enableDevValidations();
}

const modules = [
  ClientSideRowModelModule,
  ColumnMenuModule,
  ColumnsToolPanelModule,
];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [rowData, setRowData] = useState<any[]>([
    {
      athlete: "Michael Phelps",
      country: "United States",
      sport: "Swimming",
      gold: 8,
      silver: 0,
      bronze: 0,
    },
  ]);
  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      headerName: "Athlete Details",
      groupId: "athleteDetails",
      children: [
        { field: "athlete" },
        { field: "country" },
        { field: "sport" },
      ],
    },
    {
      headerName: "Results",
      groupId: "results",
      children: [{ field: "gold" }, { field: "silver" }, { field: "bronze" }],
    },
  ]);
  const components = useMemo<Components>(() => {
    return {
      customColumnLabel: CustomColumnLabel,
    };
  }, []);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 120,
      columnChooserParams: {
        columnLabelRenderer: "customColumnLabel",
        columnLabelRendererParams: {
          columnIcon: "●",
          columnGroupIcon: "◆",
        },
      },
    };
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="example-wrapper">
          <div style={gridStyle}>
            <AgGridReact
              rowData={rowData}
              columnDefs={columnDefs}
              components={components}
              defaultColDef={defaultColDef}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Custom Column Labels](https://www.ag-grid.com/examples/column-chooser/custom-column-labels/reactFunctionalTs/)

### Renderer Parameters

Properties available on the `IColumnSelectionLabelRendererParams&lt;TData = any, TContext = any&gt;` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `displayName` | `string \| null` |  |  |  |
| `column` | `Column \| null` |  |  |  |
| `columnGroup` | `ProvidedColumnGroup \| null` |  |  |  |
| `source` | `ColumnSelectionPanelSource` |  |  |  |
| `api` | `GridApi` |  |  |  |
| `context` | `TContext` |  |  |  |

## Custom Column Layout

By default, the order of columns in the Column Chooser is derived from the `columnDefs` supplied in the grid options and is kept in sync when columns are moved in the grid.

A custom layout can instead be provided through `colDef.columnChooserParams.columnLayout`.

```jsx
// original column definitions supplied to the grid
const [columnDefs, setColumnDefs] = useState([
    {
        columnChooserParams: {
            columnLayout: [{
                headerName: 'Group 1', // group doesn't appear in grid
                children: [
                    { field: 'c' }, // custom column order with column "b" omitted
                    { field: 'a' }
                ]
            }]
        }
    },
    { field: 'b' },
    { field: 'c' }
]);

<AgGridReact columnDefs={columnDefs} />
```

> **Note**
>
> Providing `columnLayout` automatically enables `suppressSyncLayoutWithGrid`. Reordering columns in the grid therefore does not reorder the custom layout displayed in the Column Chooser.

The following example demonstrates custom Column Chooser layouts. Note the following:

- Open the Column Chooser for the **Name** column and note that it uses the order specified by `columnLayout`.
- Open the Column Chooser for the **Age** column and note that it uses the current column order from the grid.
- Drag the **Age** column to the left of the **Name** column in the grid.
- Open the Column Chooser for the **Age** column and note that **Age** now appears before **Name**.
- Open the Column Chooser for the **Name** column and note that its custom layout remains unchanged.

#### Customising Columns Layout

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ColumnsToolPanelModule,
  ContextMenuModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      groupId: "athleteGroupId",
      headerName: "Athlete",
      children: [
        {
          headerName: "Name",
          field: "athlete",
          minWidth: 150,
          columnChooserParams: {
            columnLayout: [
              {
                headerName: "Group 1", // Athlete group renamed to "Group 1"
                children: [
                  // custom column order with columns "gold", "silver", "bronze" omitted
                  { field: "sport" },
                  { field: "athlete" },
                  { field: "age" },
                ],
              },
            ],
          },
        },
        {
          field: "age",
          minWidth: 120,
        },
        {
          field: "sport",
          minWidth: 150,
          columnChooserParams: {
            // contracts all column groups
            contractColumnSelection: true,
          },
        },
      ],
    },
    {
      groupId: "medalsGroupId",
      headerName: "Medals",
      children: [{ field: "gold" }, { field: "silver" }, { field: "bronze" }],
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Customising Columns Layout](https://www.ag-grid.com/examples/column-chooser/customising-columns-layout/reactFunctionalTs/)

## Column Chooser API

The Column Chooser can be opened and closed through the Grid API.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `showColumnChooser` | `Function` |  |  |  |
| `hideColumnChooser` | `Function` |  |  |  |

The following example demonstrates opening and closing the Column Chooser through the Grid API.

#### Column Chooser API

```tsx
"use client";

import React, {
  useCallback,
  useMemo,
  useRef,
  useState,
  StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { ColumnMenuModule } from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [ClientSideRowModelModule, ColumnMenuModule];

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete", minWidth: 200 },
    { field: "age" },
    { field: "country", minWidth: 200 },
    { field: "year" },
    { field: "sport", minWidth: 200 },
    { field: "gold" },
    { field: "silver" },
    { field: "bronze" },
    { field: "total" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  const showColumnChooser = useCallback(() => {
    gridRef.current!.api.showColumnChooser();
  }, []);

  const hideColumnChooser = useCallback(() => {
    gridRef.current!.api.hideColumnChooser();
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="example-wrapper">
          <div className="button-group">
            <button onClick={showColumnChooser}>Show Column Chooser</button>
            <button onClick={hideColumnChooser}>Hide Column Chooser</button>
          </div>

          <div style={gridStyle}>
            <AgGridReact<IOlympicData>
              ref={gridRef}
              rowData={data}
              loading={loading}
              columnDefs={columnDefs}
              defaultColDef={defaultColDef}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Column Chooser API](https://www.ag-grid.com/examples/column-chooser/column-chooser-api/reactFunctionalTs/)

## Legacy Tabbed Column Menu

With the [Legacy Tabbed Column Menu](https://www.ag-grid.com/react-data-grid/column-menu/#legacy-tabbed-column-menu), a column selection panel is displayed within the `columnsMenuTab` instead of a separate dialog. It supports the same customisation options through `columnChooserParams`, but columns cannot be dragged to reorder them or to move them between sections.
