API Removed keyed arrays for title/value setting in SelectionGroup

Use SelectionGroup_Item class instead. Necessary because
of removal of array key support from ArrayList (see d12b49702).
This commit is contained in:
Ingo Schommer 2012-11-30 15:06:49 +01:00
parent 9d74c99e08
commit 548ad503ed
4 changed files with 175 additions and 28 deletions

View File

@ -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)).

View File

@ -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
@ -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" => "<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);
@ -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;
}
}

View File

@ -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');

View File

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