Checkbox group (many-many)

Features: using a CheckboxSetField for a many-many relation

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 %>
...

Comments

  • Basically the same way, I guess. You'd create a front-end form, just like any contact form, then add the CheckboxSetField to the fieldset, just like you would in GetCMSFields().

    Verstuurd door Martine, 22/02/2012 11:10am (5 jaar geleden)

  • I'd like to be able to edit the checkboxes on the front end. How can I do that?

    Verstuurd door dan, 22/02/2012 6:53am (5 jaar geleden)

  • Hi, I'd rather you didn't duplicate my page, instead a link would be nice :-)

    Martine

    Verstuurd door Martine, 14/10/2011 5:22pm (5 jaar geleden)

  • This article has great reference value, thank you very much for sharing, I would like to reproduced your article, so that more people would see it.

    Verstuurd door cell phone spyware , 12/10/2011 11:48am (5 jaar geleden)

Het versturen van reacties is uitgeschakeld.

RSS feed voor reacties op deze pagina