Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a0b40f5

Browse files
Nyholmnicolas-grekas
authored andcommitted
[Form] Make sure errors are a part of the label on bootstrap 4 - this is a requirement for WCAG2
1 parent 05e9682 commit a0b40f5

File tree

4 files changed

+106
-10
lines changed

4 files changed

+106
-10
lines changed

src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_horizontal_layout.html.twig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ col-sm-2
2828
{{- form_label(form) -}}
2929
<div class="{{ block('form_group_class') }}">
3030
{{- form_widget(form) -}}
31-
{{- form_errors(form) -}}
3231
</div>
3332
{##}</div>
3433
{%- endif -%}
@@ -40,7 +39,6 @@ col-sm-2
4039
{{- form_label(form) -}}
4140
<div class="{{ block('form_group_class') }}">
4241
{{- form_widget(form) -}}
43-
{{- form_errors(form) -}}
4442
</div>
4543
</div>
4644
{##}</fieldset>

src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,41 @@
3939
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%}
4040
{% set valid = true %}
4141
{%- endif -%}
42-
{{- parent() -}}
42+
43+
{%- if widget == 'single_text' -%}
44+
{{- block('form_widget_simple') -}}
45+
{%- else -%}
46+
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%}
47+
<div {{ block('widget_container_attributes') }}>
48+
<div class="table-responsive">
49+
<table class="table {{ table_class|default('table-bordered table-condensed table-striped') }}">
50+
<thead>
51+
<tr>
52+
{%- if with_years %}<th>{{ form_label(form.years) }}</th>{% endif -%}
53+
{%- if with_months %}<th>{{ form_label(form.months) }}</th>{% endif -%}
54+
{%- if with_weeks %}<th>{{ form_label(form.weeks) }}</th>{% endif -%}
55+
{%- if with_days %}<th>{{ form_label(form.days) }}</th>{% endif -%}
56+
{%- if with_hours %}<th>{{ form_label(form.hours) }}</th>{% endif -%}
57+
{%- if with_minutes %}<th>{{ form_label(form.minutes) }}</th>{% endif -%}
58+
{%- if with_seconds %}<th>{{ form_label(form.seconds) }}</th>{% endif -%}
59+
</tr>
60+
</thead>
61+
<tbody>
62+
<tr>
63+
{%- if with_years %}<td>{{ form_widget(form.years) }}</td>{% endif -%}
64+
{%- if with_months %}<td>{{ form_widget(form.months) }}</td>{% endif -%}
65+
{%- if with_weeks %}<td>{{ form_widget(form.weeks) }}</td>{% endif -%}
66+
{%- if with_days %}<td>{{ form_widget(form.days) }}</td>{% endif -%}
67+
{%- if with_hours %}<td>{{ form_widget(form.hours) }}</td>{% endif -%}
68+
{%- if with_minutes %}<td>{{ form_widget(form.minutes) }}</td>{% endif -%}
69+
{%- if with_seconds %}<td>{{ form_widget(form.seconds) }}</td>{% endif -%}
70+
</tr>
71+
</tbody>
72+
</table>
73+
</div>
74+
{%- if with_invert %}{{ form_widget(form.invert) }}{% endif -%}
75+
</div>
76+
{%- endif -%}
4377
{%- endblock dateinterval_widget %}
4478

4579
{% block percent_widget -%}
@@ -125,13 +159,28 @@
125159
{# Labels #}
126160

127161
{% block form_label -%}
128-
{%- if compound is defined and compound -%}
129-
{%- set element = 'legend' -%}
130-
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-legend')|trim}) -%}
131-
{%- else -%}
132-
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%}
162+
{% if label is not same as(false) -%}
163+
{%- if compound is defined and compound -%}
164+
{%- set element = 'legend' -%}
165+
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-legend')|trim}) -%}
166+
{%- else -%}
167+
{%- set label_attr = label_attr|merge({for: id, class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%}
168+
{%- endif -%}
169+
{% if required -%}
170+
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
171+
{%- endif -%}
172+
{% if label is empty -%}
173+
{%- if label_format is not empty -%}
174+
{% set label = label_format|replace({
175+
'%name%': name,
176+
'%id%': id,
177+
}) %}
178+
{%- else -%}
179+
{% set label = name|humanize %}
180+
{%- endif -%}
181+
{%- endif -%}
182+
<{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}{% block form_label_errors %}{{- form_errors(form) -}}{% endblock form_label_errors %}</{{ element|default('label') }}>
133183
{%- endif -%}
134-
{{- parent() -}}
135184
{%- endblock form_label %}
136185

137186
{% block checkbox_radio_label -%}
@@ -169,7 +218,6 @@
169218
<{{ element|default('div') }} class="form-group">
170219
{{- form_label(form) -}}
171220
{{- form_widget(form) -}}
172-
{{- form_errors(form) -}}
173221
</{{ element|default('div') }}>
174222
{%- endblock form_row %}
175223

src/Symfony/Component/Form/Tests/AbstractBootstrap4HorizontalLayoutTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,39 @@
1111

1212
namespace Symfony\Component\Form\Tests;
1313

14+
use Symfony\Component\Form\FormError;
15+
1416
/**
1517
* Abstract class providing test cases for the Bootstrap 4 horizontal Twig form theme.
1618
*
1719
* @author Hidde Wieringa <[email protected]>
1820
*/
1921
abstract class AbstractBootstrap4HorizontalLayoutTest extends AbstractBootstrap4LayoutTest
2022
{
23+
public function testRow()
24+
{
25+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
26+
$form->addError(new FormError('[trans]Error![/trans]'));
27+
$view = $form->createView();
28+
$html = $this->renderRow($view);
29+
30+
$this->assertMatchesXpath($html,
31+
'/div
32+
[
33+
./label[@for="name"]
34+
[
35+
./div[
36+
./ul
37+
[./li[.="[trans]Error![/trans]"]]
38+
[count(./li)=1]
39+
]
40+
]
41+
/following-sibling::div[./input[@id="name"]]
42+
]
43+
'
44+
);
45+
}
46+
2147
public function testLabelOnForm()
2248
{
2349
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType');

src/Symfony/Component/Form/Tests/AbstractBootstrap4LayoutTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,30 @@
2020
*/
2121
abstract class AbstractBootstrap4LayoutTest extends AbstractBootstrap3LayoutTest
2222
{
23+
public function testRow()
24+
{
25+
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\TextType');
26+
$form->addError(new FormError('[trans]Error![/trans]'));
27+
$view = $form->createView();
28+
$html = $this->renderRow($view);
29+
30+
$this->assertMatchesXpath($html,
31+
'/div
32+
[
33+
./label[@for="name"]
34+
[
35+
./div[
36+
./ul
37+
[./li[.="[trans]Error![/trans]"]]
38+
[count(./li)=1]
39+
]
40+
]
41+
/following-sibling::input[@id="name"]
42+
]
43+
'
44+
);
45+
}
46+
2347
public function testLabelOnForm()
2448
{
2549
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\DateType');

0 commit comments

Comments
 (0)