Skip to content

[Form] Individual rows of CollectionType cannot be styled anymore #4909

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

Merged
merged 1 commit into from
Jul 14, 2012
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions UPGRADE-2.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,30 @@
{% endblock %}
````

* Custom styling of individual rows of a collection form has been removed for
performance reasons. Instead, all rows now have the same block name, where
the word "entry" replaces the previous occurence of the row index.

Before:

```
{% block _author_tags_0_label %}
{# ... #}
{% endblock %}

{% block _author_tags_1_label %}
{# ... #}
{% endblock %}
```

After:

```
{% block _author_tags_entry_label %}
{# ... #}
{% endblock %}
```

#### Other BC Breaks

* The order of the first two arguments of the methods `createNamed` and
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bridge/Twig/Extension/FormExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ protected function render(FormView $view, $section, array $variables = array())
$this->varStack[$rendering]['variables'] = array_replace_recursive($this->varStack[$rendering]['variables'], $variables);
} else {
$types = $view->getVar('types');
$types[] = $custom;
$types[] = $view->getVar('full_block_name');
$typeIndex = count($types) - 1;
$this->varStack[$rendering] = array(
'variables' => array_replace_recursive($view->getVars(), $variables),
Expand Down
17 changes: 14 additions & 3 deletions src/Symfony/Bridge/Twig/Tests/Extension/custom_widgets.html.twig
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
{% block _text_id_widget %}
<div id="container">
{{ form_widget(form) }}
</div>
{% spaceless %}
<div id="container">
{{ form_widget(form) }}
</div>
{% endspaceless %}
{% endblock _text_id_widget %}

{% block _name_entry_label %}
{% spaceless %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
<label>Custom label: {{ label|trans({}, translation_domain) }}</label>
{% endspaceless %}
{% endblock _name_entry_label %}
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ protected function renderSection(FormView $view, $section, array $variables = ar
$variables = array_replace_recursive($this->varStack[$rendering]['variables'], $variables);
} else {
$types = $view->getVar('types');
$types[] = $custom;
$types[] = $view->getVar('full_block_name');
$typeIndex = count($types) - 1;
$variables = array_replace_recursive($view->getVars(), $variables);
$this->varStack[$rendering]['types'] = $types;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php if (!$label) { $label = $view['form']->humanize($name); } ?>
<label>Custom label: <?php echo $view->escape($view['translator']->trans($label, array(), $translation_domain)) ?></label>
2 changes: 2 additions & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,5 @@ CHANGELOG
* `getExtensions`
* `setExtensions`
* ChoiceType now caches its created choice lists to improve performance
* [BC BREAK] Rows of a collection field cannot be themed individually anymore. All rows in the collection
field now have the same block names, which contains "entry" where it previously contained the row index.
11 changes: 11 additions & 0 deletions src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Symfony\Component\Form\FormViewInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CollectionType extends AbstractType
Expand Down Expand Up @@ -73,6 +74,12 @@ public function finishView(FormViewInterface $view, FormInterface $form, array $
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$optionsFilter = function (Options $options, $value) {
$value['block_name'] = 'entry';

return $value;
};

$resolver->setDefaults(array(
'allow_add' => false,
'allow_delete' => false,
Expand All @@ -81,6 +88,10 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
'type' => 'text',
'options' => array(),
));

$resolver->setFilters(array(
'options' => $optionsFilter,
));
}

/**
Expand Down
32 changes: 21 additions & 11 deletions src/Symfony/Component/Form/Extension/Core/Type/FormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
public function buildView(FormViewInterface $view, FormInterface $form, array $options)
{
$name = $form->getName();
$blockName = $options['block_name'] ?: $form->getName();
$readOnly = $options['read_only'];
$translationDomain = $options['translation_domain'];

Expand All @@ -67,23 +68,30 @@ public function buildView(FormViewInterface $view, FormInterface $form, array $o
throw new FormException('Form node with empty name can be used only as root form node.');
}

if ('' !== ($parentFullName = $view->getParent()->getVar('full_name'))) {
$id = sprintf('%s_%s', $view->getParent()->getVar('id'), $name);
$parentView = $view->getParent();

if ('' !== ($parentFullName = $parentView->getVar('full_name'))) {
$id = sprintf('%s_%s', $parentView->getVar('id'), $name);
$fullName = sprintf('%s[%s]', $parentFullName, $name);
$fullBlockName = sprintf('%s_%s', $parentView->getVar('full_block_name'), $blockName);
} else {
$id = $name;
$fullName = $name;
$fullBlockName = '_' . $blockName;
}

// Complex fields are read-only if themselves or their parent is.
$readOnly = $readOnly || $view->getParent()->getVar('read_only');
// Complex fields are read-only if they themselves or their parents are.
if (!$readOnly) {
$readOnly = $parentView->getVar('read_only');
}

if (!$translationDomain) {
$translationDomain = $view->getParent()->getVar('translation_domain');
$translationDomain = $parentView->getVar('translation_domain');
}
} else {
$id = $name;
$fullName = $name;
$fullBlockName = '_' . $blockName;

// Strip leading underscores and digits. These are allowed in
// form names, but not in HTML4 ID attributes.
Expand All @@ -105,6 +113,7 @@ public function buildView(FormViewInterface $view, FormInterface $form, array $o
'id' => $id,
'name' => $name,
'full_name' => $fullName,
'full_block_name' => $fullBlockName,
'read_only' => $readOnly,
'errors' => $form->getErrors(),
'valid' => $form->isBound() ? $form->isValid() : true,
Expand Down Expand Up @@ -177,7 +186,14 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
return false !== $options['property_path'];
};

// If data is given, the form is locked to that data
// (independent of its value)
$resolver->setOptional(array(
'data',
));

$resolver->setDefaults(array(
'block_name' => null,
'data_class' => $dataClass,
'empty_data' => $emptyData,
'trim' => true,
Expand All @@ -198,12 +214,6 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
'translation_domain' => null,
));

// If data is given, the form is locked to that data
// (independent of its value)
$resolver->setOptional(array(
'data',
));

$resolver->setAllowedTypes(array(
'attr' => 'array',
'label_attr' => 'array',
Expand Down
21 changes: 21 additions & 0 deletions src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,27 @@ public function testThemeInheritance($parentTheme, $childTheme)
]
/following-sibling::input[@type="hidden"]
]
'
);
}

/**
* The block "_name_child_label" should be overridden in the theme of the
* implemented driver.
*/
public function testCollectionRowWithCustomBlock()
{
$collection = array('one', 'two', 'three');
$form = $this->factory->createNamedBuilder('name', 'collection', $collection)
->getForm();

$this->assertWidgetMatchesXpath($form->createView(), array(),
'/div
[
./div[./label[.="Custom label: [trans]0[/trans]"]]
/following-sibling::div[./label[.="Custom label: [trans]1[/trans]"]]
/following-sibling::div[./label[.="Custom label: [trans]2[/trans]"]]
]
'
);
}
Expand Down
21 changes: 21 additions & 0 deletions src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,27 @@ public function testRepeatedWithCustomOptions()
]
]
[count(.//input)=3]
'
);
}

/**
* The block "_name_child_label" should be overridden in the theme of the
* implemented driver.
*/
public function testCollectionRowWithCustomBlock()
{
$collection = array('one', 'two', 'three');
$form = $this->factory->createNamedBuilder('name', 'collection', $collection)
->getForm();

$this->assertWidgetMatchesXpath($form->createView(), array(),
'/table
[
./tr[./td/label[.="Custom label: [trans]0[/trans]"]]
/following-sibling::tr[./td/label[.="Custom label: [trans]1[/trans]"]]
/following-sibling::tr[./td/label[.="Custom label: [trans]2[/trans]"]]
]
'
);
}
Expand Down