[Form] Individual rows of CollectionType cannot be styled anymore for performance reasons
This commit is contained in:
parent
cf41bf8776
commit
69e5e58629
@ -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
|
||||
|
@ -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),
|
||||
|
@ -1,5 +1,16 @@
|
||||
{% block _text_id_widget %}
|
||||
{% 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 %}
|
||||
|
@ -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;
|
||||
|
@ -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>
|
@ -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.
|
||||
|
@ -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,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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',
|
||||
|
@ -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]"]]
|
||||
]
|
||||
'
|
||||
);
|
||||
}
|
||||
|
@ -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]"]]
|
||||
]
|
||||
'
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user