# Groupstart and groupend

> A collapsible section in the edit form. A pair: groupstart opens, groupend closes.

Source: CBX documentation, version 3.x (released). Canonical page: https://docs.configbox.at/docs/technical/property-types/group. Last updated 2026-07-27.

---
A collapsible section in the edit form. A pair: `groupstart` opens, `groupend` closes.

**Storage kind:** `layout` · **Column:** none

Use them to break a long form into sections an operator can scan — "General", "Pricing",
"Visualization". For a sentence of guidance inside a section, use [`note`](https://docs.configbox.at/docs/technical/property-types/note).

## Settings — `groupstart`

| Setting | Meaning |
|---|---|
| `title` | The section heading |
| `toggle` | Whether it can be collapsed |
| `defaultState` | `'opened'` or `'closed'`. Default `'closed'` |
| `notes` / `noteHeading` | Explanatory text shown inside the section |

`groupend` takes no settings of its own — it only needs `name` and `positionForm`.

Both need a `name` even though nothing is stored under it: the name keys the property array and, for
`groupstart`, the session key that remembers the open/closed state.

## The open/closed state is remembered per operator

With `'toggle' => true`, the rendered state is read back from the request and stored in the session
under `toggles.<modelName>.<propertyName>`. So a section the operator collapsed stays collapsed on
their next visit to that form — it is per-session, not per-record and not global.

`defaultState` only decides what happens before they have touched it, and it defaults to `'closed'`.
A section you expect people to use immediately should say `'opened'` explicitly.

## They are not fields

Storage kind `layout` means they never reach a record and appear in **no** generated artifact — no
column, no record key, no schema property. `getDataKeysForBaseTable()` and
`getSelectsForGetRecord()` both return empty arrays, and `usesWrapper()` is false so they render
without the surrounding field markup.

The pair is matched by `positionForm` order, not by name, so:

- a `groupstart` with no `groupend` after it leaves the section open to the end of the form;
- a `groupend` whose `positionForm` puts it before its intended `groupstart` closes the wrong
  section, or nothing.

Give each pair positions with room between them, and keep the fields in between inside that range —
form order comes from `positionForm` alone, never from declaration order.

@see note.md
