Skip to content

Commit

Permalink
API Removed keyed arrays for title/value setting in SelectionGroup
Browse files Browse the repository at this point in the history
Use SelectionGroup_Item class instead. Necessary because
of removal of array key support from ArrayList (see d12b497).
  • Loading branch information
chillu committed Dec 11, 2012
1 parent 9d74c99 commit 548ad50
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 28 deletions.
3 changes: 2 additions & 1 deletion docs/en/changelogs/3.1.0.md
Expand Up @@ -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
* 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)).
129 changes: 103 additions & 26 deletions forms/SelectionGroup.php
@@ -1,9 +1,25 @@
<?php
/**
* SelectionGroup represents a number of fields which are selectable by a radio
* Represents a number of fields which are selectable by a radio
* button that appears at the beginning of each item. Using CSS, you can
* configure the field to only display its contents if the corresponding radio
* button is selected.
* button is selected. Each item is defined through {@link SelectionGroup_Item}.
*
* @example <code>
* $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);
* </code>
*
* @package forms
* @subpackage fields-structural
Expand All @@ -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');
}
Expand All @@ -34,33 +61,39 @@ public function FieldSet() {

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" => "<input class=\"selector\" type=\"radio\" id=\"$itemID\" name=\"$this->name\""
. " value=\"$key\"$checked />",
"RadioLabel" => "<label for=\"$itemID\">$title</label>",
"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);
Expand All @@ -81,3 +114,47 @@ public function FieldHolder($properties = array()) {
}
}

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;
}

}
2 changes: 1 addition & 1 deletion 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');
Expand Down
69 changes: 69 additions & 0 deletions tests/forms/SelectionGroupTest.php
@@ -0,0 +1,69 @@
<?php
class SelectionGroupTest extends SapphireTest {

function testFieldHolder() {
$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);
$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]);

$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]);
}

}

0 comments on commit 548ad50

Please sign in to comment.