merged branch proofek/domcrawlerform-radiodisabled (PR #2768)

Commits
-------

36c7d03 Fixed GH-2720 - Fix disabled atrribute handling for radio form elements

Discussion
----------

Fixed GH-2720 - Fix disabled atrribute handling for radio form elements

Bug fix: yes
Feature addition: no
Backwards compatibility break: no
Symfony2 tests pass: yes
Fixes the following tickets: - GH-2720

I wasn't really sure about the correct approach. This one is very minimalistic and following the existing concept of not duplicating nodes of the same name, but only storing multiple values for the same node. If you think that should be changed, let me know. Hints appreciated.

Thanks
This commit is contained in:
Fabien Potencier 2011-12-02 13:26:19 +01:00
commit 648fae7746
2 changed files with 97 additions and 10 deletions

View File

@ -41,6 +41,22 @@ class ChoiceFormField extends FormField
return true;
}
/**
* Check if the current selected option is disabled
*
* @return bool
*/
public function isDisabled()
{
foreach ($this->options as $option) {
if ($option['value'] == $this->value && $option['disabled']) {
return true;
}
}
return false;
}
/**
* Sets the value of the field.
*
@ -101,7 +117,7 @@ class ChoiceFormField extends FormField
$this->value = null;
} elseif ('checkbox' == $this->type && true === $value) {
// check
$this->value = $this->options[0];
$this->value = $this->options[0]['value'];
} else {
if (is_array($value)) {
if (!$this->multiple) {
@ -109,12 +125,12 @@ class ChoiceFormField extends FormField
}
foreach ($value as $v) {
if (!in_array($v, $this->options)) {
throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $v, implode(', ', $this->options)));
if (!$this->containsOption($v, $this->options)) {
throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $v, implode(', ', $this->availableOptionValues())));
}
}
} elseif (!in_array($value, $this->options)) {
throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $value, implode(', ', $this->options)));
} elseif (!$this->containsOption($value, $this->options)) {
throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: %s).', $this->name, $value, implode(', ', $this->availableOptionValues())));
}
if ($this->multiple) {
@ -144,10 +160,11 @@ class ChoiceFormField extends FormField
throw new \LogicException(sprintf('Unable to add a choice for "%s" as it is not multiple or is not a radio button.', $this->name));
}
$this->options[] = $value = $node->hasAttribute('value') ? $node->getAttribute('value') : '1';
$option = $this->buildOptionValue($node);
$this->options[] = $option;
if ($node->getAttribute('checked')) {
$this->value = $value;
$this->value = $option['value'];
}
}
@ -192,10 +209,11 @@ class ChoiceFormField extends FormField
if ('input' == $this->node->nodeName) {
$this->type = $this->node->getAttribute('type');
$this->options[] = $value = $this->node->hasAttribute('value') ? $this->node->getAttribute('value') : '1';
$optionValue = $this->buildOptionValue($this->node);
$this->options[] = $optionValue;
if ($this->node->getAttribute('checked')) {
$this->value = $value;
$this->value = $optionValue['value'];
}
} else {
$this->type = 'select';
@ -207,7 +225,7 @@ class ChoiceFormField extends FormField
$found = false;
foreach ($this->xpath->query('descendant::option', $this->node) as $option) {
$this->options[] = $option->hasAttribute('value') ? $option->getAttribute('value') : $option->nodeValue;
$this->options[] = $this->buildOptionValue($option);
if ($option->getAttribute('selected')) {
$found = true;
@ -226,4 +244,57 @@ class ChoiceFormField extends FormField
}
}
}
/**
* Returns option value with associated disabled flag
*
* @param type $node
*
* @return array
*/
private function buildOptionValue($node)
{
$option = array();
$defaultValue = (isset($node->nodeValue) && !empty($node->nodeValue)) ? $node->nodeValue : '1';
$option['value'] = $node->hasAttribute('value') ? $node->getAttribute('value') : $defaultValue;
$option['disabled'] = ($node->hasAttribute('disabled') && $node->getAttribute('disabled') == 'disabled');
return $option;
}
/**
* Checks whether given vale is in the existing options
*
* @param string $optionValue
* @param array $options
*
* @return bool
*/
public function containsOption($optionValue, $options)
{
foreach ($options as $option) {
if ($option['value'] == $optionValue) {
return true;
}
}
return false;
}
/**
* Returns list of available field options
*
* @return array
*/
public function availableOptionValues()
{
$values = array();
foreach ($this->options as $option) {
$values[] = $option['value'];
}
return $values;
}
}

View File

@ -168,6 +168,22 @@ class ChoiceFormFieldTest extends FormFieldTestCase
}
}
public function testRadioButtonIsDisabled()
{
$node = $this->createNode('input', '', array('type' => 'radio', 'name' => 'name', 'value' => 'foo', 'disabled' => 'disabled'));
$field = new ChoiceFormField($node);
$node = $this->createNode('input', '', array('type' => 'radio', 'name' => 'name', 'value' => 'bar'));
$field->addChoice($node);
$field->select('foo');
$this->assertEquals('foo', $field->getValue(), '->getValue() returns the value attribute of the selected radio button');
$this->assertTrue($field->isDisabled());
$field->select('bar');
$this->assertEquals('bar', $field->getValue(), '->getValue() returns the value attribute of the selected radio button');
$this->assertFalse($field->isDisabled());
}
public function testCheckboxes()
{
$node = $this->createNode('input', '', array('type' => 'checkbox', 'name' => 'name'));