A module for editing multiple records in a single interface.

Installs: 3 675

Dependents: 1

Suggesters: 0

Security: 0

Stars: 3

Watchers: 1

Forks: 2

Open Issues: 0


dev-master / 2.0.x-dev 2019-08-14 11:06 UTC

This package is auto-updated.

Last update: 2024-05-14 21:26:09 UTC


A field for editing multiple fields in a single editing interface.


  • SilverStripe ^4.1



See License

Problem being solved

In some sites, it is desirable to remove some complexity from the editing process around managing objects related to pages, and only allow editing of those objects instead of full control over adding and removing them.

By making a gridfield available for power users to add, re-order and remove objects, and then presenting just the editable fields for the objects to content, both usage models can be catered for.


private static $has_many = array('Elements' => 'BaseElement');

$editor = MultiRecordEditingField::create('Elements', 'Content Cells', $this->Elements());
$fields->addFieldToTab('Root.Elements', $editor);


class Page extends SiteTree {

	private static $has_many = array(
        'Cells'      => 'BasicContent',

    public function getCMSFields()
        $fields = parent::getCMSFields();

        $editor = MultiRecordEditingField::create('ContentCellEditor', 'Content Cells', $this->Cells());
        $fields->addFieldToTab('Root.ContentCells', $editor);

        if (Permission::check('ADMIN')) {
            $config = GridFieldConfig_RecordEditor::create();
            $grid = GridField::create('Cells', 'Cells', $this->Cells(), $config);
            $fields->addFieldToTab('Root.ContentCells', $grid);

        return $fields;

class Page_Controller extends ContentController {}

class BasicContent extends DataObject
    private static $db = array(
        'Title'     => 'Varchar(255)',
        'Description'   => 'Text',
        'Content'       => 'HTMLText',

    private static $has_one = array(
        'Parent'        => 'Page',

    private static $many_many = array(
        'Images'        => 'Image',

    public function getCMSFields()
        $fields = parent::getCMSFields();

        $uploadField = UploadField::create('Images', 'Images', $this->Images());
        $fields->replaceField('Images', $uploadField);

        return $fields;

Alternatively, the top level items may be inserted on separate tabs

		// in Page::getCMSFields()
		$i = 0;
        foreach ($this->Cells() as $cell) {
            $editor = MultiRecordEditingField::create('ContentCellEditor' . (++$i), $cell->Title, ArrayList::create(array($cell)));
            $fields->addFieldToTab('Root.' . $cell->Title, $editor);


The MultiRecordEditingField supports nesting of other MultiRecordEditingFields. When the field detects a MultiRecordEditingField in the set of fields to edit, that field is added as another nested toggle field inside the parent set of fields for editing.

Custom fields

The MultiRecordEditingField uses the output of getCMSFields when building the fieldlist used for editing. To provide an alternate set of fields, define a multiEditFields method that returns a FieldList object.

Additionally, the MultiRecordEditingField calls the updateMultiEditFields extension hook on the record being edited to allow extensions a chance to change the fields.

Frontend usage

Pass in a boolean flag during construction

MultiRecordEditingField::create('ContentCellEditor', 'Content Cells', $this->Cells(), $frontend = true);

This will trigger the lookup of fields using getFrontEndFields() instead of getCMSFields().


The above allows admin users to control what elements are available in the page for editing.

Admin view

While content authors are provided an in-page view for editing items.

Expanded editing view

Or set on different tabs.

Tabbed editing view