Using one DataObject as a category for another DataObject with many_many

Silverstripe Version: 4.2.1

Still new to Silverstripe, and can’t figure this one out. I’m creating a resources section (for PDFs, white papers, etc) as a DataObject and using another DataObject for categories for those resources. I have it setup so I can add individual resources and categories in the admin. My code is below, the important bit is probably CheckboxSetField::create('Categories', 'Categories', $this->Categories()->map('ID','Title')),. Haven’t learned how to fully use the docs yet (they’re overwhelming) so I’m sorta guessing the syntax based on the lessons. I get a section for categories in the resources but instead of checkboxes I get “No options available”. I’ve removed a few non-important sections of the code.

Resource.php

<?php
use SilverStripe\ORM\DataObject;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\HtmlEditor\HtmlEditorField;
use SilverStripe\Forms\OptionsetField;
use SilverStripe\Forms\CheckboxSetField;

class Resource extends DataObject
{
	private static $db = [
		'Title' => 'Varchar',
		'Description' => 'HTMLText',
		'ResourceType' => 'Enum(array("File","Link"))',
		'Link' => 'Varchar',
	];

	private static $many_many = [
		'Categories' => ResourceCategory::class,
	];

	private static $summary_fields = [
		'Title'
	];

	public function getCMSFields()
	{
		$fields = FieldList::create(
			TextField::create('Title'),
			HtmlEditorField::create('Description'),
			OptionsetField::create('ResourceType', 'Resource Type',
				$this->dbObject('ResourceType')->enumValues(), 'File'),
			CheckboxSetField::create('Categories', 'Categories',
				$this->Categories()->map('ID','Title')),
			TextField::create('Link')
		);

		return $fields;
	}

}

ResourceCategory.php

<?php
use SilverStripe\ORM\DataObject;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;

class ResourceCategory extends DataObject {

	private static $db = [
		'Title' => 'Varchar',
	];

	private static $belongs_many_many = [
		'Resource' => Resource::class,
	];

	public function getCMSFields()
	{
		return FieldList::create(
			TextField::create('Title')
		);
	}
}

If I’ve understood what you’re trying to do, then you’re in the right area.
The CheckboxSetField::create('Categories', 'Categories', $this->Categories()->map('ID','Title')) is probably where the issue lies.

Currently, that line says “create a checkbox field set, and use the categories attached to the dataobject as the source for the options”. Trouble is, at this point there are no categories attached to the dataobject, so there’s nothing to choose.

If you change it for CheckboxSetField::create('Categories', 'Categories', ResourceCategories::get()->map()) then you’ll be getting all the possible options as the source.

That did it, and thanks for the explanation!

1 Like