Sometimes you want to have multiple views of the same DataObject
in the same ModelAdmin
, just using different tabs. GridField
allows you to filter based on the currently active model (determined via the new modelTab
alias, rather than the full class name).
This can cause usability issues as users bookmark or share item URLs, but those items stop matching the filter for a specific tab. For example, an item moving from “active” to “inactive”. You can fix this by using the new GridField->setRedirectMissingRecords()
functionality, and defining a (conditional) CMSEditLink()
method on your DataObject
.
<?php
namespace MyNamespace\Models;
use SilverStripe\ORM\DataObject;
use MyNamespace\Admin\MyAdmin;
class MyItem extends DataObject
{
private static $db = [
'IsActive' => 'Boolean',
];
public function CMSEditLink()
{
$slug = $this->IsActive ? 'active' : 'inactive';
return Director::baseUrl() . implode('/', [
'admin',
Config::inst()->get(MyAdmin::class, 'url_segment'),
$slug,
'EditForm/field',
$slug,
'item',
$object->ID
]);
}
}
<?php
namespace MyNamespace\Admin;
use SilverStripe\Admin\ModelAdmin;
use MyNamespace\Models\MyItem;
use SilverStripe\Forms\GridField\GridFieldDetailForm;
class MyAdmin extends ModelAdmin {
private static $managed_models = [
'active' => ['title' => 'Active', 'dataClass' => MyItem::class],
'inactive' => ['title' => 'Inactive', 'dataClass' => MyItem::class],
];
private static $menu_title = 'MyItems';
private static $url_segment = 'items';
public function getList()
{
$list = parent::getList();
return $list->filter([
'IsActive' => $this->modelTab == 'active',
]);
}
public function getEditForm($id = null, $fields = null)
{
$form = parent::getEditForm($id, $fields);
/** @var GridField $grid */
$grid = $form->Fields()->dataFieldByName($this->modelTab);
/** @var GridFieldConfig $config */
$config = $grid->getConfig();
// Customise external link formatting
if ($this->modelClass == MyItem::class) {
// Allow redirection to risks in other sections
/** @var GridFieldDetailForm */
$component = $config->getComponentByType(GridFieldDetailForm::class);
$component->setRedirectMissingRecords(true);
}
return $form;
}
}