2
votes

I've run into a very bizarre issue while creating 2 TreeDropdownFields for a DataObject. For some reason, only 1 of the 2 TreeDropdownFields render correctly in the SilverStripe admin. The other doesn't render as a TreeDropdownField at all but just as a label:

enter image description here

Here is the code:

class HomeBanner extends DataObject {

    public static $db = array(
        'SortOrder' => 'Int',
        'Title' => 'Varchar'
    );

    public static $has_one = array(
        'Image' => 'Image',
        'SecondaryImage' => 'Image',
        'FirstLink' => 'SiteTree',
        'SecondLink' => 'SiteTree'
    );

    public function getCMSFields() {
        $fields = parent::getCMSFields();
        $fields->removeFieldFromTab('Root.Main', 'PageID');
        $fields->removeFieldFromTab('Root.Main', 'SortOrder');

        $fields->addFieldToTab('Root.Main', new TreeDropdownField('FirstLinkID', 'First Link', 'SiteTree'));
        $fields->addFieldToTab('Root.Main', new TreeDropdownField('SecondLinkID', 'Second Link', 'SiteTree'));

        return $fields;
    }

    public static $summary_fields = array(
        'ID' => 'ID',
        'Title' => 'Title',
        'Thumbnail' => 'Thumbnail'
    );

    public function getThumbnail() {
        return $this->Image()->CMSThumbnail();
    }
}

Here is what I have tried so far:

  • running dev/build/?flush=true
  • running ?flush=all and ?flush=1
  • logging out and logging back in after the dev/build + flushes
  • logging into the admin in another browser (I typically use Chrome but logged into the site's admin on FireFox and saw the same problem)
  • The error logs report nothing -- they're clear
  • There are no errors in the console for Chrome's dev tools
  • Adding a third TreeDropdownField will allow the first 2 to render properly but the third one will just show a label instead of a TreeDropdownField
  • This format works, but doesn't save whatever is selected--it clears your choice as soon as you leave the page. Also, it deletes all that was saved already in the admin unless I remove it. I can't make changes or else the items saved get removed.):

    $fields->addFieldToTab('Root.Main', new TreeDropdownField('SecondLink', 'Second Link', 'SiteTree', 'ID'));

Does anyone have any ideas as to why this could be happening? It doesn't seem to make sense that you can't have multiple TreeDropdownFields.

1
The name “HomeBanner” suggests to me that there should also be a has_one pointing back to HomePage or similar? The cause of this is probably that SilverStripe is automatically trying to set one of the has_one relations to point back to the page that the banner belongs to. - kinglozzer
Crap...that is actually what I was missing. I can't believe I didn't realize it before! I think it's because I've been out of SilverStripe for a couple months and forgot some things. Thanks! - Dejsa Cocan

1 Answers

3
votes

Reposting as this turned out to be the answer:

The name “HomeBanner” suggests to me that there should also be a has_one pointing back to HomePage or similar? The cause of this is probably that SilverStripe is automatically trying to set one of the has_one relations to point back to the page that the banner belongs to.

Similar conflicts can also happen when using code like this:

class Page extends SiteTree {
    private static $has_many = [
        'Banners' => 'Banner'
    ];
}

class Banner extends DataObject {
    private static $has_one = [
        'Page' => 'Page',
        'LinkedPage' => 'Page'
    ];
}

As SilverStripe doesn't know whether it should use PageID or LinkedPageID to auto-populate that side of the has_many relation (GridField will try to automatically assign the correct has_one ID).

In these cases, you can use dot-notation to distinguish between them - you’d change it to $has_many = ['Banners' => 'Banner.Page'];. See https://docs.silverstripe.org/en/3/developer_guides/model/relations/#has-many for more info.