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.

Value type

None — stores no data.

How it works

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.

Creating fields programmatically

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:

  1. Add the open field.
  2. Add the content fields that belong inside the fieldset.
  3. 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);
Notes
  • 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.
Settings
PropertyTypeDescription
modalboolOpen 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).

API reference: methods, hooks

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: FieldtypeFieldsetOpen, Fieldtype, WireData and Wire.

Show class?     Show args?       Only hookable?    

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