Merge pull request #400 from creative-commoners/pulls/4/nested-gridfield-docs

DOC Updated Nested GridField docs
This commit is contained in:
Guy Sartorelli 2024-05-28 13:54:53 +12:00 committed by GitHub
commit 11e9c3c3e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -159,39 +159,265 @@ Nested GridFields
The `GridFieldNestedForm` component allows you to nest GridFields in the UI. It can be used with `DataObject` subclasses
with the `Hierarchy` extension, or by specifying the relation used for nesting.
```php
// Basic usage, defaults to the Children-method for Hierarchy objects.
$grid->getConfig()->addComponent(GridFieldNestedForm::create());
Here is a small example of basic use of Nested GridField.
// Usage with custom relation
$grid->getConfig()->addComponent(GridFieldNestedForm::create()->setRelationName('MyRelation'));
```
You can define your own custom GridField config for the nested GridField configuration by implementing a `getNestedConfig`
on your nested model (should return a `GridField_Config` object).
```php
class NestedObject extends DataObject
namespace App\Admin;
use MyObject;
use SilverStripe\Admin\ModelAdmin;
use Symbiote\GridFieldExtensions\GridFieldNestedForm;
class MyAdmin extends ModelAdmin
{
private static $has_one = [
'Parent' => ParentObject::class
];
//...
public function getNestedConfig(): GridFieldConfig
{
$config = new GridFieldConfig_RecordViewer();
return $config;
}
public function getEditForm($id = null, $fields = null)
{
$form = parent::getEditForm($id, $fields);
$grid = $form->Fields()->dataFieldByName(MyObject::class);
// Add Nested GridField to main GridField
$grid->getConfig()->addComponent(GridFieldNestedForm::create());
return $form;
}
}
```
You can also modify the default config (a `GridFieldConfig_RecordEditor`) via an extension to the nested model class, by implementing
`updateNestedConfig`, which will get the config object as the first parameter.
There are several ways to use Nested GridField. The implementation depends on the type of data you will be using in your GridField.
For instance, if there is a `DataObject` that has the `Hierarchy` extension, you can use the following approach.
As an example, here we can use a typical hierarchy of the `Group` model, where another `Group` can serve as a parent.
```php
class NestedObjectExtension extends DataExtension
namespace App\Extensions;
use SilverStripe\Core\Extension;
use SilverStripe\Security\Group;
use Symbiote\GridFieldExtensions\GridFieldNestedForm;
class MySecurityAdminExtension extends Extension
{
public function updateNestedConfig(GridFieldConfig &$config)
{
$config->removeComponentsByType(GridFieldPaginator::class);
}
public function updateGridFieldConfig($config)
{
if ($this->owner->getModelClass() === Group::class) {
$config->addComponent(GridFieldNestedForm::create());
}
}
}
```
Or also view a list of all members of a given group. Notice we call `setRelationName()` to explicitly state the relation which should be displayed in the Nested GridField.
```php
namespace App\Extensions;
use SilverStripe\Core\Extension;
use SilverStripe\Security\Group;
use Symbiote\GridFieldExtensions\GridFieldNestedForm;
class MySecurityAdminExtension extends Extension
{
public function updateGridFieldConfig($config)
{
if ($this->owner->getModelClass() === Group::class) {
$config->addComponent(GridFieldNestedForm::create()->setRelationName('Members'));
}
}
}
```
```yml
SilverStripe\Admin\SecurityAdmin:
extensions:
- App\Extensions\MySecurityAdminExtension
```
Another way to use Nested GridField together with `DataObjects` that do not have the `Hierarchy` extension but have `has_many` relationships with other objects.
Let's say you have the following `DataObject` that has multiple levels of relationships, and an admin section where the data of this object will be displayed.
You want the user to be able to view information regarding this object and all nested objects on the same page, without the need to navigate to each object individually.
In this case, you can use the following approach.
```php
namespace App\Models;
use SilverStripe\ORM\DataObject;
class ParentNode extends DataObject
{
//...
private static $has_many = [
'ChildNodes' => BranchNode::class,
];
}
```
You can define your own custom GridField config for the nested GridField configuration by implementing a `getNestedConfig()` method on your nested model. Notice this method should return a `GridFieldConfig` object.
```php
namespace App\Models;
use SilverStripe\Forms\GridField\GridFieldConfig;
use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor;
use SilverStripe\ORM\DataObject;
use Symbiote\GridFieldExtensions\GridFieldNestedForm;
class ChildNode extends DataObject
{
//...
private static $has_one = [
'ParentNode' => ParentNode::class,
];
private static $has_many = [
'GrandChildNodes' => GrandChildNode::class,
];
public function getNestedConfig(): GridFieldConfig
{
$config = new GridFieldConfig_RecordEditor();
$config->addComponent(GridFieldNestedForm::create()->setRelationName('GrandChildNodes'));
return $config;
}
}
```
```php
namespace App\Models;
use SilverStripe\ORM\DataObject;
class GrandChildNode extends DataObject
{
//...
private static $has_one = [
'ChildNode' => ChildNode::class,
];
}
```
```php
namespace App\Admin;
use App\Models\ParentNode;
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\Forms\GridField\GridFieldConfig;
use Symbiote\GridFieldExtensions\GridFieldNestedForm;
class MyAdminSection extends ModelAdmin
{
private static string $url_segment = 'my-admin-section';
private static string $menu_title = 'My Admin Section';
private static array $managed_models = [
ParentNode::class
];
protected function getGridFieldConfig(): GridFieldConfig
{
$config = parent::getGridFieldConfig();
$config->addComponent(GridFieldNestedForm::create()->setRelationName('ChildNodes'));
return $config;
}
}
```
There is also the possibility to use Nested GridField with the data structure ArrayList. To do this, you can use the following approach.
```php
namespace App\Models;
use MyDataObject;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
class MyDataSet extends DataObject
{
//...
public function getMyArrayList() {
$list = ArrayList::create();
$data = MyDataObject::get();
foreach ($data as $value) {
$list->push($value);
}
return $list;
}
}
```
```php
namespace App\Admin;
use App\Models\MyDataSet;
use SilverStripe\Admin\ModelAdmin;
use SilverStripe\Forms\GridField\GridFieldConfig;
use Symbiote\GridFieldExtensions\GridFieldNestedForm;
class MyAdminSection extends ModelAdmin
{
//...
private static array $managed_models = [
MyDataSet::class
];
protected function getGridFieldConfig(): GridFieldConfig
{
$config = parent::getGridFieldConfig();
$config->addComponent(GridFieldNestedForm::create()->setRelationName('getMyArrayList'));
return $config;
}
}
```
Notice that instead of the name of a relation, we're passing a method name into `getMyArrayList()`. That method must return an instance of `SS_List` to be used in the GridField.
#### Additional features and settings
1. You can set the maximum number of nested levels using a `$default_max_nesting_level` configuration property. The default value is 10 levels.
```yml
Symbiote\GridFieldExtensions\GridFieldNestedForm:
default_max_nesting_level: 5
```
You can also set this limit for a specific nested GridField using the `setMaxNestingLevel()` method.
```php
public function getNestedConfig(): GridFieldConfig
{
$config = new GridFieldConfig_RecordEditor();
$config->addComponent(GridFieldNestedForm::create()->setMaxNestingLevel(5));
return $config;
}
```
1. You can also modify the default config (a `GridFieldConfig_RecordEditor`) via an extension to the nested model class, by implementing
`updateNestedConfig`, which will get the config object as the parameter.
```php
namespace App\Extensions;
use SilverStripe\Core\Extension;
class NestedObjectExtension extends Extension
{
public function updateNestedConfig(GridFieldConfig &$config)
{
$config->removeComponentsByType(GridFieldPaginator::class);
}
}
```