Search code examples
silverstripesilverstripe-4

SilverStripe: Adding the component to GridField grouping them in a div (toolbar)


I am working on a SilverStripe project. In my project, I am adding components to the GridField dynamically. Actually, I am trying to replace the existing components. Since there is no replace method, I have to remove the existing components and add the new components.

Following is my code

 $grid = new GridField('ContentBlocks', 'Content Blocks', $this->owner->ContentBlocks(), $editor);
 $grid->getConfig()
      ->removeComponentsByType(GridFieldAddExistingAutocompleter::class)
      ->addComponent(new CustomGridFieldAddExistingAutocompleter())
      //configuring other components continue here

As you can see in my code, I am removing an existing component and adding a new custom component as a replacement for the one that was removed.

It added the custom component. But there is an issue with that. The issue is that on the front-end, the new component is not added at the exact position as the one that was removed.

See this screenshot:

enter image description here

As you can see in the screenshot, the search box (the custom component added) went out of the container or div that the add content block button resides in. If I did not do that replacement, they stay in the same row as in the screenshot below.

enter image description here

What I am thinking is that I am looking for a way to group them back together in one row. How can I do that? Is it possible?


Solution

  • Instead of removing and adding components of an existing GridFieldConfig, we can create our own GridFieldConfig and add the components that we want.

    $contentBlocksFieldConfig = GridFieldConfig::create();
    $contentBlocksFieldConfig->addComponent(new GridFieldButtonRow('before'));
    $contentBlocksFieldConfig->addComponent(new GridFieldAddNewButton('buttons-before-left'));
    $contentBlocksFieldConfig->addComponent(new CustomGridFieldAddExistingAutocompleter('buttons-before-right'));
    $contentBlocksFieldConfig->addComponent(new GridFieldToolbarHeader());
    $contentBlocksFieldConfig->addComponent(new GridFieldSortableHeader());
    $contentBlocksFieldConfig->addComponent(new GridFieldFilterHeader());
    $contentBlocksFieldConfig->addComponent(new GridFieldDataColumns());
    $contentBlocksFieldConfig->addComponent(new GridFieldEditButton());
    $contentBlocksFieldConfig->addComponent(new GridFieldDeleteAction(true));
    $contentBlocksFieldConfig->addComponent(new GridField_ActionMenu());
    $contentBlocksFieldConfig->addComponent(new GridFieldPageCount('toolbar-header-right'));
    $contentBlocksFieldConfig->addComponent(new GridFieldPaginator(25));
    $contentBlocksFieldConfig->addComponent(new GridFieldDetailForm());
    
    $contentBlocksField = GridField::create(
        'ContentBlocks', 
        'Content Blocks', 
        $this->ContentBlocks(), 
        $contentBlocksFieldConfig
    );
    

    The above config component set up is based on the GridFieldConfig_RelationEditor setup. We could use the components of GridFieldConfig_RecordEditor or any of the other configs instead.

    Also, to align the Autocompleter to the right we pass 'buttons-before-right' as a parameter like so:

    ->addComponent(new CustomGridFieldAddExistingAutocompleter('buttons-before-right'))
    

    This is assuming CustomGridFieldAddExistingAutocompleter has the same constructor as GridFieldAddExistingAutocompleter.