Skip to content

Commit

Permalink
[Form] Unified rendering of errors for nested elements
Browse files Browse the repository at this point in the history
  • Loading branch information
webmozart committed Jul 9, 2012
1 parent 7f9fd11 commit df5bb4a
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 99 deletions.
Expand Up @@ -20,6 +20,9 @@
{% block form_widget_compound %}
{% spaceless %}
<div {{ block('widget_container_attributes') }}>
{% if form.parent is empty %}
{{ form_errors(form) }}
{% endif %}
{{ block('form_rows') }}
{{ form_rest(form) }}
</div>
Expand Down Expand Up @@ -236,6 +239,10 @@

{% block repeated_row %}
{% spaceless %}
{#
No need to render the errors here, as all errors are mapped
to the first child (see RepeatedTypeValidatorExtension).
#}
{{ block('form_rows') }}
{% endspaceless %}
{% endblock repeated_row %}
Expand All @@ -244,13 +251,7 @@
{% spaceless %}
<div>
{{ form_label(form, label|default(null)) }}
{#
If the child is a compound form, the errors are rendered inside
the container. See also block form_rows.
#}
{% if not compound %}
{{ form_errors(form) }}
{% endif %}
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endspaceless %}
Expand Down Expand Up @@ -298,7 +299,6 @@

{% block form_rows %}
{% spaceless %}
{{ form_errors(form) }}
{% for child in form %}
{{ form_row(child) }}
{% endfor %}
Expand Down
Expand Up @@ -7,31 +7,13 @@
{{ form_label(form, label|default(null)) }}
</td>
<td>
{% if not compound %}
{{ form_errors(form) }}
{% endif %}
{{ form_errors(form) }}
{{ form_widget(form) }}
</td>
</tr>
{% endspaceless %}
{% endblock form_row %}

{% block form_errors %}
{% spaceless %}
{% if not compound %}
{{ parent() }}
{% else %}
{% if errors|length > 0 %}
<tr>
<td colspan="2">
{{ parent() }}
</td>
</tr>
{% endif %}
{% endif %}
{% endspaceless %}
{% endblock form_errors %}

{% block hidden_row %}
{% spaceless %}
<tr style="display: none">
Expand All @@ -45,6 +27,13 @@
{% block form_widget_compound %}
{% spaceless %}
<table {{ block('widget_container_attributes') }}>
{% if form.parent is empty and errors|length > 0 %}
<tr>
<td colspan="2">
{{ form_errors(form) }}
</td>
</tr>
{% endif %}
{{ block('form_rows') }}
{{ form_rest(form) }}
</table>
Expand Down
@@ -1,7 +1,5 @@
<div>
<?php echo $view['form']->label($form, isset($label) ? $label : null) ?>
<?php if (!$compound): ?>
<?php echo $view['form']->errors($form) ?>
<?php endif ?>
<?php echo $view['form']->errors($form) ?>
<?php echo $view['form']->widget($form) ?>
</div>
@@ -1,4 +1,3 @@
<?php echo $view['form']->errors($form) ?>
<?php foreach ($form as $child) : ?>
<?php echo $view['form']->row($child) ?>
<?php endforeach; ?>
@@ -1,4 +1,11 @@
<div <?php echo $view['form']->renderBlock('widget_container_attributes') ?>>
<?php if (!$form->hasParent() && $errors): ?>
<tr>
<td colspan="2">
<?php echo $view['form']->errors($form) ?>
</td>
</tr>
<?php endif ?>
<?php echo $view['form']->renderBlock('form_rows') ?>
<?php echo $view['form']->rest($form) ?>
</div>
@@ -1,51 +1,21 @@
<?php if (!$compound): ?>
<?php if ($errors): ?>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php
if (null === $error->getMessagePluralization()) {
echo $view['translator']->trans(
$error->getMessageTemplate(),
$error->getMessageParameters(),
'validators'
);
} else {
echo $view['translator']->transChoice(
$error->getMessageTemplate(),
$error->getMessagePluralization(),
$error->getMessageParameters(),
'validators'
);
}?></li>
<?php endforeach; ?>
</ul>
<?php endif ?>
<?php else: ?>
<?php if (count($errors) > 0): ?>
<tr>
<td colspan="2">
<?php if ($errors): ?>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php
if (null === $error->getMessagePluralization()) {
echo $view['translator']->trans(
$error->getMessageTemplate(),
$error->getMessageParameters(),
'validators'
);
} else {
echo $view['translator']->transChoice(
$error->getMessageTemplate(),
$error->getMessagePluralization(),
$error->getMessageParameters(),
'validators'
);
}?></li>
<?php endforeach; ?>
</ul>
<?php endif ?>
</td>
</tr>
<?php endif; ?>
<?php endif;
<?php if ($errors): ?>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php
if (null === $error->getMessagePluralization()) {
echo $view['translator']->trans(
$error->getMessageTemplate(),
$error->getMessageParameters(),
'validators'
);
} else {
echo $view['translator']->transChoice(
$error->getMessageTemplate(),
$error->getMessagePluralization(),
$error->getMessageParameters(),
'validators'
);
}?></li>
<?php endforeach; ?>
</ul>
<?php endif ?>
Expand Up @@ -3,9 +3,7 @@
<?php echo $view['form']->label($form, isset($label) ? $label : null) ?>
</td>
<td>
<?php if (!$compound): ?>
<?php echo $view['form']->errors($form) ?>
<?php endif ?>
<?php echo $view['form']->errors($form) ?>
<?php echo $view['form']->widget($form) ?>
</td>
</tr>
@@ -1,4 +1,7 @@
<table <?php echo $view['form']->renderBlock('widget_container_attributes') ?>>
<?php if (!$form->hasParent()): ?>
<?php echo $view['form']->errors($form) ?>
<?php endif ?>
<?php echo $view['form']->renderBlock('form_rows') ?>
<?php echo $view['form']->rest($form) ?>
</table>
1 change: 1 addition & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Expand Up @@ -141,3 +141,4 @@ CHANGELOG
* FormBuilder now implements \IteratorAggregate
* [BC BREAK] compound forms now always need a data mapper
* FormBuilder now maintains the order when explicitely adding form builders as children
* [BC BREAK] fixed rendering of errors for DateType, BirthdayType and similar ones
6 changes: 6 additions & 0 deletions src/Symfony/Component/Form/Extension/Core/Type/FormType.php
Expand Up @@ -175,6 +175,11 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
return false !== $options['property_path'];
};

// Compound forms are not displayed inline
$inline = function (Options $options) {
return !$options['compound'];
};

$resolver->setDefaults(array(
'data' => null,
'data_class' => $dataClass,
Expand All @@ -195,6 +200,7 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
'virtual' => false,
'compound' => true,
'translation_domain' => null,
'inline' => $inline,
));

$resolver->setAllowedTypes(array(
Expand Down
13 changes: 8 additions & 5 deletions src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php
Expand Up @@ -57,11 +57,13 @@ public function testRepeatedRow()
$view = $form->createView();
$html = $this->renderRow($view);

// The errors of the form are not rendered by intention!
// In practice, repeated fields cannot have errors as all errors
// on them are mapped to the first child.
// (see RepeatedTypeValidatorExtension)

$this->assertMatchesXpath($html,
'/ul
[./li[.="[trans]Error![/trans]"]]
[count(./li)=1]
/following-sibling::div
'/div
[
./label[@for="name_first"]
/following-sibling::input[@id="name_first"]
Expand Down Expand Up @@ -373,7 +375,8 @@ public function testNestedFormError()
$this->assertWidgetMatchesXpath($form->createView(), array(),
'/div
[
./div/div[@id="name_child"][./ul/li[.="[trans]Error![/trans]"]]
./div/label
/following-sibling::ul[./li[.="[trans]Error![/trans]"]]
]
[count(.//li[.="[trans]Error![/trans]"])=1]
'
Expand Down
18 changes: 9 additions & 9 deletions src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php
Expand Up @@ -59,12 +59,12 @@ public function testRepeatedRow()
/following-sibling::td
[./input[@id="name_second"]]
]
[count(../tr)=3]
/following-sibling::tr[@style="display: none"]
[./td[@colspan="2"]/input
[@type="hidden"]
[@id="name__token"]
]
[count(../tr)=3]
'
);
}
Expand All @@ -76,12 +76,13 @@ public function testRepeatedRowWithErrors()
$view = $form->createView();
$html = $this->renderRow($view);

// The errors of the form are not rendered by intention!
// In practice, repeated fields cannot have errors as all errors
// on them are mapped to the first child.
// (see RepeatedTypeValidatorExtension)

$this->assertMatchesXpath($html,
'/tr
[./td[@colspan="2"]/ul
[./li[.="[trans]Error![/trans]"]]
]
/following-sibling::tr
[
./td
[./label[@for="name_first"]]
Expand All @@ -95,12 +96,12 @@ public function testRepeatedRowWithErrors()
/following-sibling::td
[./input[@id="name_second"]]
]
[count(../tr)=4]
/following-sibling::tr[@style="display: none"]
[./td[@colspan="2"]/input
[@type="hidden"]
[@id="name__token"]
]
[count(../tr)=3]
'
);
}
Expand Down Expand Up @@ -235,9 +236,8 @@ public function testNestedFormError()
$this->assertWidgetMatchesXpath($form->createView(), array(),
'/table
[
./tr/td/table
[@id="name_child"]
[./tr/td/ul/li[.="[trans]Error![/trans]"]]
./tr/td/ul[./li[.="[trans]Error![/trans]"]]
/following-sibling::table[@id="name_child"]
]
[count(.//li[.="[trans]Error![/trans]"])=1]
'
Expand Down

0 comments on commit df5bb4a

Please sign in to comment.