Skip to content

Commit

Permalink
check for the correct field type
Browse files Browse the repository at this point in the history
HTML allow to define different form fields with the same name.
Imagine the following form:

    <html>
        <body>
            <form action="/">
                <input type="hidden" name="option" value="default">
                <input type="radio" name="option" value="A">
                <input type="radio" name="option" value="B">
                <input type="hidden" name="settings[1]" value="0">
                <input type="checkbox" name="settings[1]" value="1" id="setting-1">
                <button>klickme</button>
            </form>
        </body>
    </html>

Since the `FormFieldRegistry` can only handle one field per name, the
hidden field option is registered first before the radio field with
the same name is evaluated. Thus, the `FormFieldRegistry` returns an
`InputFormField` instance on which the `addChoices()` method can not
be called.
  • Loading branch information
xabbuh committed Aug 18, 2014
1 parent 65862c9 commit 169b397
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/Symfony/Component/DomCrawler/Form.php
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\DomCrawler;

use Symfony\Component\DomCrawler\Field\ChoiceFormField;
use Symfony\Component\DomCrawler\Field\FormField;

/**
Expand Down Expand Up @@ -444,7 +445,9 @@ private function addField(\DOMNode $node)
if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == strtolower($node->getAttribute('type'))) {
$this->set(new Field\ChoiceFormField($node));
} elseif ('input' == $nodeName && 'radio' == strtolower($node->getAttribute('type'))) {
if ($this->has($node->getAttribute('name'))) {
// there may be other fields with the same name that are no choice
// fields already registered (see https://github.com/symfony/symfony/issues/11689)
if ($this->has($node->getAttribute('name')) && $this->get($node->getAttribute('name')) instanceof ChoiceFormField) {
$this->get($node->getAttribute('name'))->addChoice($node);
} else {
$this->set(new Field\ChoiceFormField($node));
Expand Down
22 changes: 22 additions & 0 deletions src/Symfony/Component/DomCrawler/Tests/FormTest.php
Expand Up @@ -782,6 +782,28 @@ public function testFormRegistrySetValues()
));
}

public function testDifferentFieldTypesWithSameName()
{
$dom = new \DOMDocument();
$dom->loadHTML('
<html>
<body>
<form action="/">
<input type="hidden" name="option" value="default">
<input type="radio" name="option" value="A">
<input type="radio" name="option" value="B">
<input type="hidden" name="settings[1]" value="0">
<input type="checkbox" name="settings[1]" value="1" id="setting-1">
<button>klickme</button>
</form>
</body>
</html>
');
$form = new Form($dom->getElementsByTagName('form')->item(0), 'http://example.com');

$this->assertInstanceOf('Symfony\Component\DomCrawler\Field\ChoiceFormField', $form->get('option'));
}

protected function getFormFieldMock($name, $value = null)
{
$field = $this
Expand Down

0 comments on commit 169b397

Please sign in to comment.