FieldtypeFieldsetOpen
Opens a collapsible, bordered group of fields in the page editor
Fields placed between the open and its paired close field are visually grouped together.
None — stores no data.
Close fields are created, renamed, and deleted automatically alongside their paired open
field. The close field is always named {opener_name}_END.
You only interact with close fields to position them within a template's field order — drag them to wherever you want the group to end.
Create the opener with $fields->new() or $fields->newField(). Do not manually create
the close field as an independent field unless you are repairing old data; let the opener
fieldtype create the paired close field.
// Create and save a fieldset opener named "details"
/** @var Field $open */
$open = $fields->new('FieldsetOpen', 'details', 'Details');
// Saving the opener creates/repairs the paired close field: details_END
/** @var Field $close */
$close = $fields->get('details_END');The same pattern works for tabs:
/** @var Field $tab */
$tab = $fields->new('FieldsetTabOpen', 'seo', [
'label' => 'SEO',
'modal' => false,
]);
/** @var Field $tabClose */
$tabClose = $fields->get('seo_END');If you use $fields->newField() because you need to configure before saving, save the
opener before expecting the close field to exist:
$open = $fields->newField('FieldsetOpen', 'details', 'Details');
$open->collapsed = Inputfield::collapsedYes;
$fields->save($open);
$close = $fields->get('details_END');Adding to a fieldgroup
When adding a fieldset to a template or fieldgroup in code, add fields in the exact visual order you want:
- Add the open field.
- Add the content fields that belong inside the fieldset.
- Add the close field.
$fieldgroup = $templates->get('product')->fieldgroup;
$open = $fields->get('details');
$close = $fields->get('details_END');
$fieldgroup->add($open);
$fieldgroup->add('summary');
$fieldgroup->add('body');
$fieldgroup->add($close);
$fieldgroup->save();Do not add only the opener and assume the close field will be positioned correctly for a programmatic fieldgroup change. The admin UI has convenience hooks for this, but migration code should add the opener, inner fields, and closer explicitly.
Repairing a missing close field
If a previous migration or partial failure left an opener without its {name}_END field,
saving the opener repairs it:
$open = $fields->get('details');
$fields->save($open);
$close = $fields->get('details_END');You can also call the fieldtype helper directly when you need the close field immediately:
/** @var FieldtypeFieldsetOpen $fieldtype */
$fieldtype = $open->type;
$close = $fieldtype->getFieldsetCloseField($open, true); After repairing a missing close field, make sure the fieldgroup contains the close field in the correct position. A valid fieldgroup order is always opener, inner fields, closer.
Deleting programmatically
When deleting a fieldset in code, remove both fields yourself. Remove them from any fieldgroups before deleting the field definitions.
$open = $fields->get('details');
$close = $fields->get('details_END');
foreach([ $open, $close ] as $field) {
if(!$field || !$field->id) continue;
foreach($field->getFieldgroups() as $fieldgroup) {
$fieldgroup->remove($field);
$fieldgroup->save();
}
}
if($open && $open->id) $fields->delete($open);
if($close && $close->id) $fields->delete($close);- Close fields appear under the "Advanced" filter in the Fields list.
- In the admin UI, do not rename or delete close fields directly — manage them via the open field. In migration code, you may need to reference the close field directly for ordering, repair, or explicit cleanup.
| Property | Type | Description |
|---|---|---|
modal | bool | Open the tab in its own modal window. Useful for large forms where loading all tabs at once is slow. Default: false. |
The collapsed option for tab fieldsets is limited to: always visible, or AJAX-loaded
(the tab content loads only when the tab is clicked).
Click any linked item for full usage details and examples. Hookable methods are indicated with the icon. In addition to those shown below, the FieldtypeFieldsetClose class also inherits all the methods and properties of: Fieldtype
Common
Additional methods and properties
In addition to the methods and properties above, FieldtypeFieldsetClose also inherits the methods and properties of these classes:
API reference based on ProcessWire core version 3.0.265