I'm trying to remove the Export to CSV button in the top of a GridField in ModelAdmin.
I can't seem to find the class that creates the button (GridFieldExportButton right?). I'm guessing there is a function that populates the GridField with buttons / "actions" which I'm not familiar with.
To remove the scaffolded GridField for relationships...
class MyDataObject extends DataObject {
...
private static $has_many= array(
'OtherDataObjects' => 'OtherDataObject'
);
...
function getCMSFields() {
$fields = parent::getCMSFields();
if($grid = $fields->dataFieldByName('OtherDataObjects'))
$grid->getConfig()
->removeComponentsByType('SilverStripe\Forms\GridField\GridFieldExportButton');
return $fields;
}
...
}
If you are making the GridField then just add this when you create the field...
$gridField->getConfig()->removeComponentsByType('SilverStripe\Forms\GridField\GridFieldExportButton');
If you are looking for a gridfield that isn't within a data object edit form and is actually...
class MyAdmin extends ModelAdmin {
...
function getEditForm($id = null, $fields = null) {
$form = parent::getEditForm($id, $fields);
if($this->modelClass == 'MyDataObjectName') {
$form->Fields()
->fieldByName($this->sanitiseClassName($this->modelClass))
->getConfig()
->removeComponentsByType('SilverStripe\Forms\GridField\GridFieldExportButton');
}
return $form;
}
...
}
Setting model_importers to empty will do the reverse and remove the import ...
class MyAdmin extends ModelAdmin {
...
static $model_importers = array();
...
}
Related
In DataObjects, the getCMSFields method creates all the appropriate CMS Fields automatically (it is called scaffolding). However, in classes that extend SiteTree (i.e. Pages) this does not happen.
How can I use this form field scaffolding in Pages?
Besides calling DataObject::getCMSFields() as you already suggested in your own answer, it is also possible to instantiate a scafolder directly:
public function getCMSFields() {
// with tabs
$scaffolder = new FormScaffolder($this);
$scaffolder->restrictFields = ['Title', 'Content'];
$scaffolder->tabbed = true;
$fields = $scaffolder->getFieldList();
$fields->addFieldToTab('Root.Main', [
new MySpecialFieldWithCustomOptions('Links', 'My Links', $foobar),
]);
return $fields;
}
public function getCMSFields() {
// without tabs
$scaffolder = new FormScaffolder($this);
$scaffolder->restrictFields = ['Title', 'Content'];
$fields = $scaffolder->getFieldList();
$fields->push(
new MySpecialFieldWithCustomOptions('Links', 'My Links', $foobar)
);
return $fields;
}
This will work with any DataObject ($this has to be an instace of DataObject). Pages a subclass of DataObjects.
restrictFields is optional, if not provided, it will do all fields it can find.
We go back to DataObject and get the scaffolded fields:
use SilverStripe\ORM\DataObject;
use Page;
class MyPage extends Page
{
private static $db = [
'MyField' => 'Varchar',
];
private static $has_one = [
'MyRelation' => 'MyClass',
];
public function getCMSFields()
{
// fields from Page class
$fields = parent::getCMSFields();
// fields from DataObject class.
$fieldRepository = DataObject::getCMSFields();
$fields->addFieldsToTab(
'Root.MyExtraFields',
[
$fieldRepository->dataFieldByName('MyField'),
$fieldRepository->dataFieldByName('MyRelationID'),
]
);
return $fields;
}
}
I have custom data object with predefined entries. I don't want user to delete or add any new entries from GridField's edit form. Is there a way to remove those two buttons form ModelAdmins GridField edit form?
Using: Silverstripe 3.6
To remove actions from a GridField "globally", eg. for all records managed by the GridField, it's best to modify the GridFieldConfig instance.
In a ModelAdmin context, this is possible by overriding getEditForm:
public function getEditForm($id = null, $fields = null)
{
$form = parent::getEditForm($id, $fields);
// make sure to check if the modelClass matches the object you want to edit
// otherwise, the config will get applied to all models managed
// by this ModelAdmin instance
if ($this->modelClass === Translation::class) {
$fieldName = $this->sanitiseClassName($this->modelClass);
/** #var GridField $grid */
if ($grid = $form->Fields()->dataFieldByName($fieldName)) {
$grid->getConfig()->removeComponentsByType([
GridFieldDeleteAction::class,
GridFieldAddNewButton::class
]);
}
}
return $form;
}
However, the user might still be able to delete a record in the detail-view. But since both, GridField and detail-view respect DataObject permissions, you should make use of them… this also prevents that a user can delete the object via other means.
A simplistic solution would be (these methods should be implemented in your DataObject):
public function canDelete($member = null)
{
return Permission::check('ADMIN');
}
public function canCreate($member = null)
{
return Permission::check('ADMIN');
}
public function canView($member = null)
{
return true;
}
public function canEdit($member = null)
{
return Permission::check('CMS_ACCESS_TranslationAdmin');
}
That way, only administrators can create/delete these objects. They can be viewed by all users and edited by users that have access to your ModelAdmin section (here named "TranslationAdmin").
Ok, i got it my self. If you want to remove Add and Delete buttons from managed model's ModelAdmin you need to add this code
class Translation extends DataObject {
// ...
public function canDelete($member = null) {
return false;
}
}
class TranslationAdmin extends ModelAdmin {
public static $managed_models = ['Translation'];
static $url_segment = 'translations';
static $menu_title = 'Translations';
public function getEditForm($id = null, $fields = null) {
$form = parent::getEditForm($id, $fields);
$form
->Fields()
->fieldByName($this->sanitiseClassName($this->modelClass))
->getConfig()
->removeComponentsByType('GridFieldDeleteAction')
->removeComponentsByType('GridFieldAddNewButton');
return $form;
}
}
Hope this helps for someone in future.
Is it possible to change or add custom summary_fields into a listing from a ModelAdmin extends? Actually I'm able to filter a custom field named Type but I don't know how to customize the summary_fields. This is my actual code:
class Profiles3ModelAdmin extends ModelAdmin {
public static $menu_icon = 'mysite/images/peoples.png';
public static $managed_models = array('Member');
public static $url_segment = 'membres';
public static $menu_title = 'Membres';
public function getList() {
$group = Group::get()->filter('Code', array('Membres'))->first();
$list = $group->Members()->filter('Type', 1 );
return $list;
}
}
Your current query should be able to use $list = Member::get()->filter(array('Groups.Code' => 'Membres', 'Type' => 1)); if I recall correctly. Just gets it down to one line.
Usually to add to the summary you would add it to your class's model. So in this case on Member you would apply a DataExtension that had:
<?php
class MyMemberDataExtension extends DataExtension{
private static $summary_fields = array(
'Type'
);
}
Wondering if it was possible to add additional actions when editing a page to the More options menu in Silverstripe 3.1
Using the below sample, I have added an additional FormAction which I can see when editing an page. But where do I actually add the "custom_action" method?
class CustomPage extends SiteTree {
function getCMSActions(){
$actions = parent::getCMSActions();
$actions->addFieldToTab(
'ActionMenus.MoreOptions',
new FormAction('custom_action', 'Custom Action')
);
return $actions;
}
}
class CustomPage_Controller extends ContentController {
public function init() {
parent::init();
if(!Member::currentUserID()) {
die();
}
}
}
I would like to use GridField to view and create new child pages. Parent is DocumentHolder, child is Document. Both extend SiteTree. When I click to "Add Document" (button generated by grid), fill in the fields and confirm the form, the parent page is ignored and the page is created in root. It works well when I use DataObject. The code looks like this:
class DocumentHolder extends SiteTree
{
private static $allowed_children = array(
'Document'
);
private static $default_child = "Document";
public function getCMSFields()
{
$fields = parent::getCMSFields();
$gridField = new GridField('Documents', 'Documents', SiteTree::get('Document')->filter('ParentID', $this->ID), GridFieldConfig_RecordEditor::create());
$fields->addFieldToTab("Root.Uploads", $gridField);
return $fields;
}
}
class Document extends SiteTree
{
private static $db = array(
);
private static $has_one = array(
);
}
Thanks for help.
Since SiteTree already has a relationship to its Children pages set up, you may as well use it! Since allowed_children will only ever be documents, try this instead:
$gridField = new GridField('Documents', 'Documents', $this->Children(), GridFieldConfig_RecordEditor::create());
I ran into this problem earlier working on my holderpage module. You need to set the ParentID by default. Here's two strategies;
You can use populateDefaults on the child class. E.g.
class Document extends SiteTree
{
private static $default_parent = 'DocumentHolder';
private static $can_be_root = false;
public function populateDefaults(){
parent::populateDefaults();
$this->ParentID = DataObject::get_one(self::$default_parent)->ID;
}
...
Or you can manipulate the record in the gridfield with a custom GridFieldDetailForm implementation or via the updateItemEditForm callback.
<?php
class MyGridFieldDetailForm_ItemRequest extends GridFieldDetailForm_ItemRequest
{
public function ItemEditForm()
{
$form = parent::ItemEditForm();
if (! $this->record->exists() && $this->record->is_a('SiteTree')) {
$parent_page = $this->getController()->currentPage();
if ($parent_page && $parent_page->exists()) {
$this->record->ParentID = $parent_page->ID;
// update URLSegment #TODO perhaps more efficiently?
$field = $this->record->getCMSFields()->dataFieldByName('URLSegment');
$form->Fields()->replaceField('URLSegment', $field);
}
}
return $form;
}
}
This is more complicated although it allowed me to create an effortless module / addon ( https://github.com/briceburg/silverstripe-holderpage )