mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
ENHANCEMENT Allowing array values in ListboxField->setValue(), serialising into comma-separated list of values (AIR-35)
This commit is contained in:
parent
007eb259e0
commit
4d31ac65a0
@ -122,7 +122,7 @@ class DropdownField extends FormField {
|
||||
* Argument is deprecated in 2.3, please use {@link setHasEmptyDefault()} and {@link setEmptyString()} instead.
|
||||
*/
|
||||
function __construct($name, $title = null, $source = array(), $value = "", $form = null, $emptyString = null) {
|
||||
$this->source = $source;
|
||||
$this->setSource($source);
|
||||
|
||||
if($emptyString) $this->setHasEmptyDefault(true);
|
||||
if(is_string($emptyString)) $this->setEmptyString($emptyString);
|
||||
|
@ -116,5 +116,63 @@ class ListboxField extends DropdownField {
|
||||
$this->multiple = $bool;
|
||||
}
|
||||
|
||||
function setSource($source) {
|
||||
if($source) {
|
||||
$hasCommas = array_filter(array_keys($source), create_function('$key', 'return strpos($key, ",") !== FALSE;'));
|
||||
if($hasCommas) {
|
||||
throw new InvalidArgumentException('No commas allowed in $source keys');
|
||||
}
|
||||
}
|
||||
|
||||
parent::setSource($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String
|
||||
*/
|
||||
function dataValue() {
|
||||
if($this->value && $this->multiple && is_array($this->value)) {
|
||||
return implode(',', $this->value);
|
||||
} else {
|
||||
return parent::dataValue();
|
||||
}
|
||||
}
|
||||
|
||||
function setValue($val) {
|
||||
if($val) {
|
||||
if(!$this->multiple && is_array($val)) {
|
||||
throw new InvalidArgumentException('No array values allowed with multiple=false');
|
||||
}
|
||||
|
||||
if($this->multiple) {
|
||||
$parts = (is_array($val)) ? $val : preg_split("/ *, */", trim($val));
|
||||
if(ArrayLib::is_associative($parts)) {
|
||||
throw new InvalidArgumentException('No associative arrays allowed multiple=true');
|
||||
}
|
||||
|
||||
if($diff = array_diff($parts, array_keys($this->source))) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Invalid keys "%s" in value array for multiple=true',
|
||||
Convert::raw2xml(implode(',', $diff))
|
||||
));
|
||||
}
|
||||
|
||||
parent::setValue($parts);
|
||||
} else {
|
||||
if(!in_array($val, array_keys($this->source))) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Invalid value "%s" for multiple=true',
|
||||
Convert::raw2xml($val)
|
||||
));
|
||||
}
|
||||
|
||||
parent::setValue($val);
|
||||
}
|
||||
} else {
|
||||
parent::setValue($val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
145
tests/forms/ListboxFieldTest.php
Normal file
145
tests/forms/ListboxFieldTest.php
Normal file
@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/**
|
||||
* @package sapphire
|
||||
* @subpackage tests
|
||||
*/
|
||||
|
||||
class ListboxFieldTest extends SapphireTest {
|
||||
|
||||
protected $extraDataObjects = array('ListboxFieldTest_DataObject');
|
||||
|
||||
function testSaveIntoNullValueWithMultipleOff() {
|
||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
$field->multiple = true;
|
||||
|
||||
$obj = new ListboxFieldTest_DataObject();
|
||||
$field->setValue('a');
|
||||
$field->saveInto($obj);
|
||||
$field->setValue(null);
|
||||
$field->saveInto($obj);
|
||||
$this->assertNull($obj->Choices);
|
||||
}
|
||||
|
||||
function testSaveIntoNullValueWithMultipleOn() {
|
||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
$field->multiple = true;
|
||||
|
||||
$obj = new ListboxFieldTest_DataObject();
|
||||
$field->setValue('a,c');
|
||||
$field->saveInto($obj);
|
||||
$field->setValue('');
|
||||
$field->saveInto($obj);
|
||||
$this->assertEquals('', $obj->Choices);
|
||||
}
|
||||
|
||||
function testSaveInto() {
|
||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
$field->multiple = false;
|
||||
|
||||
$obj = new ListboxFieldTest_DataObject();
|
||||
$field->setValue('a');
|
||||
$field->saveInto($obj);
|
||||
$this->assertEquals('a', $obj->Choices);
|
||||
}
|
||||
|
||||
function testSaveIntoMultiple() {
|
||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
$field->multiple = true;
|
||||
|
||||
// As array
|
||||
$obj1 = new ListboxFieldTest_DataObject();
|
||||
$field->setValue(array('a', 'c'));
|
||||
$field->saveInto($obj1);
|
||||
$this->assertEquals('a,c', $obj1->Choices);
|
||||
|
||||
// As string
|
||||
$obj2 = new ListboxFieldTest_DataObject();
|
||||
$field->setValue('a,c');
|
||||
$field->saveInto($obj2);
|
||||
$this->assertEquals('a,c', $obj2->Choices);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
function testSetValueFailsOnArrayIfMultipleIsOff() {
|
||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
$field->multiple = false;
|
||||
|
||||
// As array (type error)
|
||||
$failsOnArray = false;
|
||||
$obj = new ListboxFieldTest_DataObject();
|
||||
$field->setValue(array('a', 'c'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
function testSetValueFailsOnStringIfChoiceInvalidAndMultipleIsOff() {
|
||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
$field->multiple = false;
|
||||
|
||||
// As string (invalid choice as comma is regarded literal)
|
||||
$obj = new ListboxFieldTest_DataObject();
|
||||
$field->setValue('invalid');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
function testSetValueFailsOnInvalidArrayKeyIfChoiceInvalidAndMultipleIsOn() {
|
||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
$field->multiple = true;
|
||||
|
||||
$obj = new ListboxFieldTest_DataObject();
|
||||
$field->setValue(array('a', 'invalid'));
|
||||
}
|
||||
|
||||
function testFieldRenderingMultipleOff() {
|
||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
$field->multiple = true;
|
||||
$field->setValue('a');
|
||||
$parser = new CSSContentParser($field->Field());
|
||||
$optEls = $parser->getBySelector('option');
|
||||
$this->assertEquals(3, count($optEls));
|
||||
$this->assertEquals('selected', (string)$optEls[0]['selected']);
|
||||
$this->assertEquals('', (string)$optEls[1]['selected']);
|
||||
$this->assertEquals('', (string)$optEls[2]['selected']);
|
||||
}
|
||||
|
||||
function testFieldRenderingMultipleOn() {
|
||||
$choices = array('a' => 'a value', 'b' => 'b value','c' => 'c value');
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
$field->multiple = true;
|
||||
$field->setValue('a,c');
|
||||
$parser = new CSSContentParser($field->Field());
|
||||
$optEls = $parser->getBySelector('option');
|
||||
$this->assertEquals(3, count($optEls));
|
||||
$this->assertEquals('selected', (string)$optEls[0]['selected']);
|
||||
$this->assertEquals('', (string)$optEls[1]['selected']);
|
||||
$this->assertEquals('selected', (string)$optEls[2]['selected']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException InvalidArgumentException
|
||||
*/
|
||||
function testCommasInSourceKeys() {
|
||||
$choices = array('a' => 'a value', 'b,with,comma' => 'b value,with,comma',);
|
||||
$field = new ListboxField('Choices', 'Choices', $choices);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ListboxFieldTest_DataObject extends DataObject implements TestOnly {
|
||||
static $db = array(
|
||||
'Choices' => 'Text'
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user