diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig
index 2a4d83ede2..c6122862ff 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig
@@ -233,6 +233,15 @@
{% endspaceless %}
{% endblock field_row %}
+{% block form_row %}
+{% spaceless %}
+
+ {{ form_label(form, label|default(null)) }}
+ {{ form_widget(form) }}
+
+{% endspaceless %}
+{% endblock form_row %}
+
{% block hidden_row %}
{{ form_widget(form) }}
{% endblock hidden_row %}
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig
index d15bbcf9f6..1046c3de36 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_table_layout.html.twig
@@ -14,6 +14,19 @@
{% endspaceless %}
{% endblock field_row %}
+{% block form_row %}
+{% spaceless %}
+
+
+ {{ form_label(form, label|default(null)) }}
+ |
+
+ {{ form_widget(form) }}
+ |
+
+{% endspaceless %}
+{% endblock form_row %}
+
{% block form_errors %}
{% spaceless %}
{% if errors|length > 0 %}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php
new file mode 100644
index 0000000000..0a79a0cc53
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/form_row.html.php
@@ -0,0 +1,4 @@
+
+ label($form, isset($label) ? $label : null) ?>
+ widget($form) ?>
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php
new file mode 100644
index 0000000000..d1bbbb1b2a
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/FormTable/form_row.html.php
@@ -0,0 +1,8 @@
+
+
+ label($form, isset($label) ? $label : null) ?>
+ |
+
+ widget($form) ?>
+ |
+
diff --git a/tests/Symfony/Tests/Component/Form/AbstractDivLayoutTest.php b/tests/Symfony/Tests/Component/Form/AbstractDivLayoutTest.php
index 8227d2ff35..8c6f4bdf1d 100644
--- a/tests/Symfony/Tests/Component/Form/AbstractDivLayoutTest.php
+++ b/tests/Symfony/Tests/Component/Form/AbstractDivLayoutTest.php
@@ -344,6 +344,25 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
);
}
+ // https://github.com/symfony/symfony/issues/2308
+ public function testNestedFormError()
+ {
+ $form = $this->factory->createNamedBuilder('form', 'name')
+ ->add('child', 'form', array('error_bubbling' => false))
+ ->getForm();
+
+ $form->get('child')->addError(new FormError('Error!'));
+
+ $this->assertWidgetMatchesXpath($form->createView(), array(),
+'/div
+ [
+ ./div/div[@id="name_child"][./ul/li[.="[trans]Error![/trans]"]]
+ ]
+ [count(.//li[.="[trans]Error![/trans]"])=1]
+'
+ );
+ }
+
public function testRepeated()
{
$form = $this->factory->createNamed('repeated', 'name', 'foobar', array(
diff --git a/tests/Symfony/Tests/Component/Form/AbstractTableLayoutTest.php b/tests/Symfony/Tests/Component/Form/AbstractTableLayoutTest.php
index 86e82ed9d1..aab8c1e940 100644
--- a/tests/Symfony/Tests/Component/Form/AbstractTableLayoutTest.php
+++ b/tests/Symfony/Tests/Component/Form/AbstractTableLayoutTest.php
@@ -196,6 +196,27 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest
);
}
+ // https://github.com/symfony/symfony/issues/2308
+ public function testNestedFormError()
+ {
+ $form = $this->factory->createNamedBuilder('form', 'name')
+ ->add('child', 'form', array('error_bubbling' => false))
+ ->getForm();
+
+ $form->get('child')->addError(new FormError('Error!'));
+
+ $this->assertWidgetMatchesXpath($form->createView(), array(),
+'/table
+ [
+ ./tr/td/table
+ [@id="name_child"]
+ [./tr/td/ul/li[.="[trans]Error![/trans]"]]
+ ]
+ [count(.//li[.="[trans]Error![/trans]"])=1]
+'
+ );
+ }
+
public function testRepeated()
{
$form = $this->factory->createNamed('repeated', 'name', 'foobar', array(