[Form] Individual rows of CollectionType cannot be styled anymore for performance reasons

This commit is contained in:
Bernhard Schussek 2012-07-14 12:08:26 +02:00
parent cf41bf8776
commit 69e5e58629
10 changed files with 118 additions and 16 deletions

View File

@ -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

View File

@ -245,7 +245,7 @@ class FormExtension extends \Twig_Extension
$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),

View File

@ -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 %}

View File

@ -246,7 +246,7 @@ class FormHelper extends Helper
$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;

View File

@ -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>

View File

@ -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.

View File

@ -16,6 +16,7 @@ use Symfony\Component\Form\FormBuilderInterface;
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
@ -73,6 +74,12 @@ class CollectionType extends AbstractType
*/
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,
@ -81,6 +88,10 @@ class CollectionType extends AbstractType
'type' => 'text',
'options' => array(),
));
$resolver->setFilters(array(
'options' => $optionsFilter,
));
}
/**

View File

@ -59,6 +59,7 @@ class FormType extends AbstractType
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'];
@ -67,23 +68,30 @@ class FormType extends AbstractType
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.
@ -105,6 +113,7 @@ class FormType extends AbstractType
'id' => $id,
'name' => $name,
'full_name' => $fullName,
'full_block_name' => $fullBlockName,
'read_only' => $readOnly,
'errors' => $form->getErrors(),
'valid' => $form->isBound() ? $form->isValid() : true,
@ -177,7 +186,14 @@ class FormType extends AbstractType
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,
@ -198,12 +214,6 @@ class FormType extends AbstractType
'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',

View File

@ -557,6 +557,27 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
]
/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]"]]
]
'
);
}

View File

@ -338,6 +338,27 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest
]
]
[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]"]]
]
'
);
}