# Action Column Toggles

Canonical page: https://www.adaptabletools.com/docs/handbook-action-column-toggle

- A `toggle` Control is bound to a boolean on the row
- Use `field` for automatic read/write (like `command` shortcuts) or `value` / `onChange` for custom behaviour
- `variant` is `switch` (default), `checkbox`, or `button`

A `toggle` Control is for an immediate on/off action — active / suspended, has wiki, starred, and so on.

The simplest form sets `field` to the row data property. AdapTable reads the current value and writes changes back for you — the same shortcut idea as `command: 'edit'`.

Use `value` and `onChange` when you need custom logic (async saves, side effects, writing a different property, and so on).

`field` is the **row data property**, not the Action Column's `columnId`. The Action Column is a separate synthetic column (for example `wiki_toggle`) that displays the control; `field: 'has_wiki'` is the boolean it reads and writes.

`variant` is one of:

| Variant      | Rendering                                      |
| ------------ | ---------------------------------------------- |
| `switch`     | Sliding on/off switch (default)                |
| `checkbox`   | Compact checkbox                               |
| `button`     | Pressed / unpressed toggle button (good with an `icon`) |

### Defining a Toggle Control

Put the Column in `actionColumnOptions.actionColumns`.

Supply `columnId` and an optional `friendlyName`.

Set `type` to `'toggle'`.

Set `field` to the boolean property on the row. AdapTable handles read and write.

`switch` is the default. Use `checkbox` for a compact control, or `button` with an `icon`.

```ts [[1, 1, "actionColumnOptions"], [1, 2, "actionColumns"], [2, 4, "columnId"], [2, 5, "friendlyName"], [3, 8, "type"], [4, 9, "field"], [5, 10, "variant"]]
actionColumnOptions: {
  actionColumns: [
    {
      columnId: 'wiki_toggle',
      friendlyName: 'Wiki',
      controls: [
        {
          type: 'toggle',
          field: 'has_wiki',
          variant: 'switch',
          tooltip: 'Toggle Has Wiki',
        },
      ],
    },
  ],
},
```

## Custom handlers

When you need bespoke behaviour, omit `field` and supply `value` and `onChange` instead.

### Defining a Toggle with Custom Handlers

Put the Column in `actionColumnOptions.actionColumns`.

Supply `columnId` and an optional `friendlyName`.

Set `type` to `'toggle'`.

`value` reads the boolean from the row.

`onChange` receives the new `checked` state. Use `gridApi.setCellValue` to write it back.

`checkbox` suits a labelled control; `button` works well with an `icon`.

```ts [[1, 1, "actionColumnOptions"], [1, 2, "actionColumns"], [2, 4, "columnId"], [2, 5, "friendlyName"], [3, 8, "type"], [4, 12, "value"], [5, 13, "onChange"], [6, 9, "variant"], [6, 10, "label"]]
actionColumnOptions: {
  actionColumns: [
    {
      columnId: 'pages_toggle',
      friendlyName: 'Pages',
      controls: [
        {
          type: 'toggle',
          variant: 'checkbox',
          label: 'Pages',
          tooltip: 'Toggle Has Pages',
          value: (context) => Boolean(context.data.has_pages),
          onChange: (checked, context) => {
            context.adaptableApi.gridApi.setCellValue({
              columnId: 'has_pages',
              newValue: checked,
              primaryKeyValue: context.primaryKeyValue,
              rowNode: context.rowNode,
            });
          },
        },
      ],
    },
  ],
},
```

**Example: Action Columns: Toggle**

Three toggle variants — field shortcut, checkbox, and icon button

- **Wiki** — `switch` with `field: 'has_wiki'`; the **Has Wiki** data column is in the layout so you can see both update together
- **Pages** — `checkbox` with custom `value` / `onChange` via `gridApi.setCellValue` (no **Has Pages** column shown)
- **Projects** — `button` variant with a `folder` icon and custom handlers (no **Has Projects** column shown)

- Flip the **Wiki** switch — **Has Wiki** in the adjacent column updates immediately
- Tick the **Pages** checkbox — the row value changes even though **Has Pages** is not visible in this layout
- Press the **Projects** folder button — toggles `has_projects` the same way

Demo project (Vanilla); the files without a marker are shown below:

```text
src/
  adaptableOptions.ts
  agGridModules.ts     [template]
  columnDefs.ts        [template]
  gridOptions.ts       [template]
  index.ts             [template]
  onAdaptableReady.ts  [template]
  rowData.ts           [template]
  styles.css           [template]
index.html             [template]
package.json           [template]
tsconfig.json          [template]
```

Files marked `[template]` are the same in every demo; see the [demo template](https://www.adaptabletools.com/llms/demo-template.md#vanilla).

**`src/adaptableOptions.ts`**

```ts
import {
  ActionColumnContext,
  AdaptableOptions,
} from '@adaptabletools/adaptable';
import {WebFramework} from './rowData';

const setBooleanField = (
  context: ActionColumnContext<WebFramework>,
  columnId: 'has_pages' | 'has_projects',
  newValue: boolean
) => {
  context.adaptableApi.gridApi.setCellValue({
    columnId,
    newValue,
    primaryKeyValue: context.primaryKeyValue,
    rowNode: context.rowNode,
  });
};

export const adaptableOptions: AdaptableOptions<WebFramework> = {
  primaryKey: 'id',
  adaptableId: 'Action Column Toggle',
  actionColumnOptions: {
    actionColumns: [
      {
        columnId: 'wiki_toggle',
        friendlyName: 'Wiki',
        settings: {width: 80, suppressMenu: true, resizable: false},
        controls: [
          {
            type: 'toggle',
            variant: 'switch',
            field: 'has_wiki',
            tooltip: 'Toggle Has Wiki',
          },
        ],
      },
      {
        columnId: 'pages_toggle',
        friendlyName: 'Pages',
        settings: {width: 100, suppressMenu: true, resizable: false},
        controls: [
          {
            type: 'toggle',
            variant: 'checkbox',
            label: 'Pages',
            tooltip: 'Toggle Has Pages',
            value: context => Boolean(context.data?.has_pages),
            onChange: (checked, context) =>
              setBooleanField(context, 'has_pages', checked),
          },
        ],
      },
      {
        columnId: 'projects_toggle',
        friendlyName: 'Projects',
        settings: {width: 72, suppressMenu: true, resizable: false},
        controls: [
          {
            type: 'toggle',
            variant: 'button',
            icon: {name: 'folder'},
            tooltip: 'Toggle Has Projects',
            value: context => Boolean(context.data?.has_projects),
            onChange: (checked, context) =>
              setBooleanField(context, 'has_projects', checked),
          },
        ],
      },
    ],
  },
  initialState: {
    Theme: {CurrentTheme: 'dark'},
    Layout: {
      CurrentLayout: 'Standard Layout',
      Layouts: [
        {
          Name: 'Standard Layout',
          TableColumns: [
            'name',
            'language',
            'has_wiki',
            'wiki_toggle',
            'pages_toggle',
            'projects_toggle',
            'github_stars',
            'license',
          ],
          AutoSizeColumns: true,
        },
      ],
    },
  },
};
```
