3
votes

I have a DataObject called ContentSection that has 2 has_one relationships: to a page type LandingPage and another DataObject Person.

class ContentSection extends DataObject {
    protected static $has_one = array(
        'Person'        => 'Person',
        'LandingPage'   => 'LandingPage'
    );
}

Both LandingPage and Person define a has_many relationship to ContentSection.

class LandingPage extends Page {
    protected static $has_many = array(
        'ContentSections'   => 'ContentSection'
    );
}

class Person extends DataObject {
    protected static $has_many = array(
        'ContentSections'   => 'ContentSection'
    );
}

ContentSections are editable through the LandingPage and Person with the GridFieldConfig_RelationEditor e.g.:

function getCMSFields() {
    $fields = parent::getCMSFields();
    $config = GridFieldConfig_RelationEditor::create(10);
    $fields->addFieldToTab('Root.Content', new GridField('ContentSections', 'Content Sections', $this->ContentSections(), $config));
    return $fields;
}

My question is how can you hide/remove irrelevant has_one fields in the CMS editor tab? The Person and LandingPage relationship dropdown fields both display when you are editing a ContentSection, whether it is for a Person or LandingPage. I only want to show the relevant has_one relationship field. I've tried using dot notation on the has_many relationships:

class Person extends DataObject {
    protected static $has_many = array(
        'ContentSections'   => 'ContentSection.Person'
    );
}

I've also tried using the removeFieldFromTab method in the getCMSFields method of the ContentSection class, where I define the other CMS fields for the ContentSection:

$fields->removeFieldFromTab('Root.Main', 'Person');
1

1 Answers

7
votes

Instead of removeFieldFromTab use the removeByName function. removeFieldFromTab will not work if there is no 'Root.Main' tab.

Also we remove PersonID, not Person. has_one variables have ID appended to the end of their variable name.

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

    $fields->removeByName('PersonID');
    $fields->removeByName('LandingPageID');

    return $fields;
}

If you would like to selectively hide or display these fields you can put in some if statements in your getCMSFields function.

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

    if (!$this->PersonID) {
        $fields->removeByName('PersonID');
    }

    if (!$this->LandingPageID) {
        $fields->removeByName('LandingPageID');
    }

    return $fields;
}