Last updated: 31/01/2012 1:11pm

New website!

Check out the new website for a new or updated article on this topic:
www.balbuss.com/checkbox-group-many-many/

Features: using a many many CheckboxSetField

Case: you need a lookuptable for, let's say, 'features' that you can add to and edit from within the CMS. Next you want to make it easy for your user to select one ore more features on any given page. So you'd like to add a separate tab to the page, with a checkbox for each available feature. Nice and clean... What do we need:

  • A Feature DataObject
  • A FeatureAdmin, that will let us manage Features from within the CMS
  • A FeaturePage, that can show the selected Features for this page

The Feature DataObject

This is a simple DataObject called 'Feature'. Each feature will have a name and a description. We could even leave out the getCMSFields() method, to let SilverStripe scaffold the form, but hey, I like to keep some control.

mysite/code/Feature.php

<?php
class Feature extends DataObject {

	public static $db = array(
		'Name' => 'Varchar(255)',
		'Description' => 'HTMLText'
	);

	public function getCMSFields() {

		$fields = new FieldSet();

		$fields->push(new TextField('Name', 'Name of the feature'));
		$fields->push(new TextareaField('Description', 'Short description'));

		return $fields;
	}
}

The Feature admin

Before we can go and create some features, we need to enable the ModelAdmin for the Feature DataObject:

mysite/code/FeatureAdmin.php

<?php
class FeatureAdmin extends ModelAdmin {

	public static $managed_models = array(
		'Feature'
	);

	static $url_segment = 'features';
	static $menu_title = 'Features';
}

Make sure you do a /dev/build/?flush=1 after you upload the code. Now, when you reload the CMS, you'll find a new menu-item called 'Features'.

The Feature page

So now for the Page. Again, this is a very simple page that lets you select features using a set of checkboxes:

mysite/code/FeaturePage.php

<?php
class FeaturePage extends Page {

	// pages can have many features
	public static $many_many = array(
		'Features' => 'Feature'
	);

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

		// get all existing features
		$features= DataObject::get('Feature');

		if (!empty($features)) {

			// create an array('ID'=>'Name')
			$map = $features->toDropdownMap('ID', 'Name');

			// create a Checkbox group based on the array
			$fields->addFieldToTab('Root.Content.Features',
				new CheckboxSetField(
					$name = "Features",
					$title = "Select Features",
					$source = $map
			));
			return $fields;
		}
	}
}

class FeaturePage_Controller extends Page_Controller {
}

As each page can have many features, we've defined a $many-many relation. The reason we can't use a $has_many relation here, is that each Feature in turn can also belong to multiple pages. We still have to confirm this relation in the Feature DataObject as a $belongs_many_many relation:

mysite/code/Feature.php

<?php
class Feature extends DataObject {

	...

	public static $belongs_many_many = array(
		'FeaturePages' => 'FeaturePage'
	);

	...
}

Extra table FeaturePage_Features...

This relation will automatically create an extra table in the database, called FeaturePage_Features, that will provide the links between Features and FeaturePages.

Again, after uploading the code do a /dev/build/?flush = 1. After reloading the CMS you can now create a FeaturePage and find the extra tab that contains the checkboxes.

Show the features

Simple!! You just needs something like this in your template:

/themes/../Templates/Layout/Page.ssĀ  (or FeaturePage.ss if you wish):

...
<% if Features %>
<ul>
	<% control Features %>
		<li>$Name</li>
	<% end_control %>
</ul>
<% end_if %>
...

10 Most recently updated pages

Post your comment

Comments

No one has commented on this page yet.

RSS feed for comments on this page | RSS feed for all comments