Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from Dec 2, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
91 changes: 81 additions & 10 deletions src/Symfony/Component/DomCrawler/Field/ChoiceFormField.php
Expand Up @@ -41,6 +41,22 @@ public function hasValue()
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.
*
Expand Down Expand Up @@ -101,20 +117,20 @@ public function setValue($value)
$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) {
throw new \InvalidArgumentException(sprintf('The value for "%s" cannot be an array.', $this->name));
}

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) {
Expand Down Expand Up @@ -144,10 +160,11 @@ public function addChoice(\DOMNode $node)
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'];
}
}

Expand Down Expand Up @@ -192,10 +209,11 @@ protected function initialize()

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';
Expand All @@ -207,7 +225,7 @@ protected function initialize()

$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;
Expand All @@ -226,4 +244,57 @@ protected function initialize()
}
}
}

/**
* 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;
}
}
Expand Up @@ -168,6 +168,22 @@ public function testRadioButtons()
}
}

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'));
Expand Down