diff --git a/docs/en/changelogs/3.1.0.md b/docs/en/changelogs/3.1.0.md
index f5935c4db..08a883616 100644
--- a/docs/en/changelogs/3.1.0.md
+++ b/docs/en/changelogs/3.1.0.md
@@ -15,4 +15,5 @@
* `SiteTree::$nested_urls` enabled by default. To disable, call `SiteTree::disable_nested_urls()`.
* Removed CMS permission checks from `File->canEdit()` and `File->canDelete()`. If you have unsecured controllers relying on these permissions, please override them through a `DataExtension`.
* Deprecated global email methods `htmlEmail()` and `plaintextEmail`, as well as various email helper methods like `encodeMultipart()`. Use the `Email` API, or the `Mailer` class where applicable.
- * Removed non-functional `$inlineImages` option for sending emails
\ No newline at end of file
+ * Removed non-functional `$inlineImages` option for sending emails * Removed support for keyed arrays in `SelectionGroup`, use new `SelectionGroup_Item` object
+ to populate the list instead (see [API docs](api:SelectionGroup)).
\ No newline at end of file
diff --git a/forms/SelectionGroup.php b/forms/SelectionGroup.php
index b17eee819..19390ce55 100644
--- a/forms/SelectionGroup.php
+++ b/forms/SelectionGroup.php
@@ -1,9 +1,25 @@
+ * $items = array(
+ * new SelectionGroup_Item(
+ * 'one',
+ * new LiteralField('one', 'one view'),
+ * 'one title'
+ * ),
+ * new SelectionGroup_Item(
+ * 'two',
+ * new LiteralField('two', 'two view'),
+ * 'two title'
+ * ),
+ * );
+ * $field = new SelectionGroup('MyGroup', $items);
+ *
*
* @package forms
* @subpackage fields-structural
@@ -12,18 +28,29 @@ class SelectionGroup extends CompositeField {
/**
* Create a new selection group.
- * @param name The field name of the selection group.
- * @param items The list of items to show. This should be a map. The keys will be the radio
- * button option names, and the values should be the associated field to display. If you want,
- * you can make this field a composite field.
*
- * If you want to a have a title that is different from the value of the key, you can express it
- * as "InternalVal//This is the Title"
+ * @param name The field name of the selection group.
+ * @param items The list of {@link SelectionGroup_Item}
*/
public function __construct($name, $items) {
$this->name = $name;
- parent::__construct($items);
+ $selectionItems = array();
+ foreach($items as $key => $item) {
+ if($item instanceof SelectionGroup_Item) {
+ $selectionItems[] = $item;
+ } else {
+ // Convert legacy format
+ if(strpos($key,'//') !== false) {
+ list($key,$title) = explode('//', $key,2);
+ } else {
+ $title = null;
+ }
+ $selectionItems[] = new SelectionGroup_Item($key, $item, $title);
+ }
+ }
+
+ parent::__construct($selectionItems);
Requirements::css(FRAMEWORK_DIR . '/css/SelectionGroup.css');
}
@@ -34,33 +61,39 @@ class SelectionGroup extends CompositeField {
public function FieldList() {
$items = parent::FieldList()->toArray();
-
$count = 0;
- $firstSelected = $checked ="";
$newItems = array();
- foreach($items as $key => $item) {
- if(strpos($key,'//') !== false) {
- list($key,$title) = explode('//', $key,2);
- } else {
- $title = $key;
- }
- if($this->value == $key) {
+ foreach($items as $item) {
+ if($this->value == $item->getValue()) {
$firstSelected = " class=\"selected\"";
- $checked = " checked=\"checked\"";
+ $checked = true;
+ } else {
+ $firstSelected = "";
+ $checked = false;
}
$itemID = $this->ID() . '_' . (++$count);
$extra = array(
- "RadioButton" => "name\""
- . " value=\"$key\"$checked />",
- "RadioLabel" => "",
+ "RadioButton" => FormField::create_tag(
+ 'input',
+ array(
+ 'class' => 'selector',
+ 'type' => 'radio',
+ 'id' => $itemID,
+ 'name' => $this->name,
+ 'value' => $item->getValue(),
+ 'checked' => $checked
+ )
+ ),
+ "RadioLabel" => FormField::create_tag(
+ 'label',
+ array('for' => $itemID),
+ $item->getTitle()
+ ),
"Selected" => $firstSelected,
);
- if(is_object($item)) $newItems[] = $item->customise($extra);
- else $newItems[] = new ArrayData($extra);
-
- $firstSelected = $checked ="";
+ $newItems[] = $item->customise($extra);
}
return new ArrayList($newItems);
@@ -81,3 +114,47 @@ class SelectionGroup extends CompositeField {
}
}
+class SelectionGroup_Item extends CompositeField {
+
+ /**
+ * @var String
+ */
+ protected $value;
+
+ /**
+ * @var String
+ */
+ protected $title;
+
+ /**
+ * @param String $value Form field identifier
+ * @param FormField $field Contents of the option
+ * @param String $title Title to show for the radio button option
+ */
+ function __construct($value, $fields = null, $title = null) {
+ $this->value = $value;
+ $this->title = ($title) ? $title : $value;
+ if($fields && !is_array($fields)) $fields = array($fields);
+
+ parent::__construct($fields);
+ }
+
+ function getTitle() {
+ return $this->title;
+ }
+
+ function setTitle($title) {
+ $this->title = $title;
+ return $this;
+ }
+
+ function getValue() {
+ return $this->value;
+ }
+
+ function setValue($Value) {
+ $this->value = $Value;
+ return $this;
+ }
+
+}
\ No newline at end of file
diff --git a/javascript/SelectionGroup.js b/javascript/SelectionGroup.js
index 733ce99c5..7270d4e11 100644
--- a/javascript/SelectionGroup.js
+++ b/javascript/SelectionGroup.js
@@ -1,7 +1,7 @@
(function($) {
$(document).ready(function() {
$('ul.SelectionGroup input.selector').live('click', function() {
- var li = $(this).parent('li')
+ var li = $(this).closest('li');
li.addClass('selected');
var prev = li.prevAll('li.selected');
diff --git a/tests/forms/SelectionGroupTest.php b/tests/forms/SelectionGroupTest.php
new file mode 100644
index 000000000..0b227e1f9
--- /dev/null
+++ b/tests/forms/SelectionGroupTest.php
@@ -0,0 +1,69 @@
+FieldHolder());
+ $listEls = $parser->getBySelector('li');
+ $listElOne = $listEls[0];
+ $listElTwo = $listEls[1];
+
+ $this->assertEquals('one', (string)$listElOne->input[0]['value']);
+ $this->assertEquals('two', (string)$listElTwo->input[0]['value']);
+
+ $this->assertEquals('one title', $listElOne->label[0]);
+ $this->assertEquals('two title', $listElTwo->label[0]);
+
+ $this->assertContains('one view', (string)$listElOne);
+ $this->assertContains('two view', (string)$listElTwo);
+ }
+
+ function testLegacyItemsFieldHolder() {
+ $items = array(
+ 'one' => new LiteralField('one', 'one view'),
+ 'two' => new LiteralField('two', 'two view'),
+ );
+ $field = new SelectionGroup('MyGroup', $items);
+ $parser = new CSSContentParser($field->FieldHolder());
+ $listEls = $parser->getBySelector('li');
+ $listElOne = $listEls[0];
+ $listElTwo = $listEls[1];
+
+ $this->assertEquals('one', (string)$listElOne->input[0]['value']);
+ $this->assertEquals('two', (string)$listElTwo->input[0]['value']);
+
+ $this->assertEquals('one', $listElOne->label[0]);
+ $this->assertEquals('two', $listElTwo->label[0]);
+ }
+
+ function testLegacyItemsFieldHolderWithTitle() {
+ $items = array(
+ 'one//one title' => new LiteralField('one', 'one view'),
+ 'two//two title' => new LiteralField('two', 'two view'),
+ );
+ $field = new SelectionGroup('MyGroup', $items);
+ $parser = new CSSContentParser($field->FieldHolder());
+ $listEls = $parser->getBySelector('li');
+ $listElOne = $listEls[0];
+ $listElTwo = $listEls[1];
+
+ $this->assertEquals('one', (string)$listElOne->input[0]['value']);
+ $this->assertEquals('two', (string)$listElTwo->input[0]['value']);
+
+ $this->assertEquals('one title', $listElOne->label[0]);
+ $this->assertEquals('two title', $listElTwo->label[0]);
+ }
+
+}
\ No newline at end of file