1{% use "bootstrap_base_layout.html.twig" %}
2
3{# Widgets #}
4
5{% block money_widget -%}
6    {%- set prepend = not (money_pattern starts with '{{') -%}
7    {%- set append = not (money_pattern ends with '}}') -%}
8    {%- if prepend or append -%}
9        <div class="input-group{{ group_class|default('') }}">
10            {%- if prepend -%}
11                <div class="input-group-prepend">
12                    <span class="input-group-text">{{ money_pattern|form_encode_currency }}</span>
13                </div>
14            {%- endif -%}
15            {{- block('form_widget_simple') -}}
16            {%- if append -%}
17                <div class="input-group-append">
18                    <span class="input-group-text">{{ money_pattern|form_encode_currency }}</span>
19                </div>
20            {%- endif -%}
21        </div>
22    {%- else -%}
23        {{- block('form_widget_simple') -}}
24    {%- endif -%}
25{%- endblock money_widget %}
26
27{% block datetime_widget -%}
28    {%- if widget != 'single_text' and not valid -%}
29        {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%}
30        {% set valid = true %}
31    {%- endif -%}
32    {{- parent() -}}
33{%- endblock datetime_widget %}
34
35{% block date_widget -%}
36    {%- if widget != 'single_text' and not valid -%}
37        {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%}
38        {% set valid = true %}
39    {%- endif -%}
40    {{- parent() -}}
41{%- endblock date_widget %}
42
43{% block time_widget -%}
44    {%- if widget != 'single_text' and not valid -%}
45        {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%}
46        {% set valid = true %}
47    {%- endif -%}
48    {{- parent() -}}
49{%- endblock time_widget %}
50
51{% block dateinterval_widget -%}
52    {%- if widget != 'single_text' and not valid -%}
53        {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control is-invalid')|trim}) -%}
54        {% set valid = true %}
55    {%- endif -%}
56    {%- if widget == 'single_text' -%}
57        {{- block('form_widget_simple') -}}
58    {%- else -%}
59        {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%}
60        <div {{ block('widget_container_attributes') }}>
61            {%- if with_years -%}
62            <div class="col-auto">
63                {{ form_label(form.years) }}
64                {{ form_widget(form.years) }}
65            </div>
66            {%- endif -%}
67            {%- if with_months -%}
68            <div class="col-auto">
69                {{ form_label(form.months) }}
70                {{ form_widget(form.months) }}
71            </div>
72            {%- endif -%}
73            {%- if with_weeks -%}
74            <div class="col-auto">
75                {{ form_label(form.weeks) }}
76                {{ form_widget(form.weeks) }}
77            </div>
78            {%- endif -%}
79            {%- if with_days -%}
80            <div class="col-auto">
81                {{ form_label(form.days) }}
82                {{ form_widget(form.days) }}
83            </div>
84            {%- endif -%}
85            {%- if with_hours -%}
86            <div class="col-auto">
87                {{ form_label(form.hours) }}
88                {{ form_widget(form.hours) }}
89            </div>
90            {%- endif -%}
91            {%- if with_minutes -%}
92            <div class="col-auto">
93                {{ form_label(form.minutes) }}
94                {{ form_widget(form.minutes) }}
95            </div>
96            {%- endif -%}
97            {%- if with_seconds -%}
98            <div class="col-auto">
99                {{ form_label(form.seconds) }}
100                {{ form_widget(form.seconds) }}
101            </div>
102            {%- endif -%}
103            {%- if with_invert %}{{ form_widget(form.invert) }}{% endif -%}
104        </div>
105    {%- endif -%}
106{%- endblock dateinterval_widget %}
107
108{% block percent_widget -%}
109    <div class="input-group">
110        {{- block('form_widget_simple') -}}
111        <div class="input-group-append">
112            <span class="input-group-text">%</span>
113        </div>
114    </div>
115{%- endblock percent_widget %}
116
117{% block form_widget_simple -%}
118    {% if type is not defined or type != 'hidden' %}
119        {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control' ~ (type|default('') == 'file' ? '-file' : ''))|trim}) -%}
120    {% endif %}
121    {%- if type is defined and (type == 'range' or type == 'color') %}
122        {# Attribute "required" is not supported #}
123        {%- set required = false -%}
124    {% endif %}
125    {{- parent() -}}
126{%- endblock form_widget_simple %}
127
128{%- block widget_attributes -%}
129    {%- if not valid %}
130        {% set attr = attr|merge({class: (attr.class|default('') ~ ' is-invalid')|trim}) %}
131    {% endif -%}
132    {{ parent() }}
133{%- endblock widget_attributes -%}
134
135{% block button_widget -%}
136    {%- set attr = attr|merge({class: (attr.class|default('btn-secondary') ~ ' btn')|trim}) -%}
137    {{- parent() -}}
138{%- endblock button_widget %}
139
140{% block submit_widget -%}
141    {%- set attr = attr|merge({class: (attr.class|default('btn-primary'))|trim}) -%}
142    {{- parent() -}}
143{%- endblock submit_widget %}
144
145{% block checkbox_widget -%}
146    {%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%}
147    {%- if 'checkbox-custom' in parent_label_class -%}
148        {%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) -%}
149        <div class="custom-control custom-checkbox{{ 'checkbox-inline' in parent_label_class ? ' custom-control-inline' }}">
150            {{- form_label(form, null, { widget: parent() }) -}}
151        </div>
152    {%- else -%}
153        {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
154        <div class="form-check{{ 'checkbox-inline' in parent_label_class ? ' form-check-inline' }}">
155            {{- form_label(form, null, { widget: parent() }) -}}
156        </div>
157    {%- endif -%}
158{%- endblock checkbox_widget %}
159
160{% block radio_widget -%}
161    {%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%}
162    {%- if 'radio-custom' in parent_label_class -%}
163        {%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) -%}
164        <div class="custom-control custom-radio{{ 'radio-inline' in parent_label_class ? ' custom-control-inline' }}">
165            {{- form_label(form, null, { widget: parent() }) -}}
166        </div>
167    {%- else -%}
168        {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
169        <div class="form-check{{ 'radio-inline' in parent_label_class ? ' form-check-inline' }}">
170            {{- form_label(form, null, { widget: parent() }) -}}
171        </div>
172    {%- endif -%}
173{%- endblock radio_widget %}
174
175{% block choice_widget_expanded -%}
176    <div {{ block('widget_container_attributes') }}>
177        {%- for child in form %}
178            {{- form_widget(child, {
179                parent_label_class: label_attr.class|default(''),
180                translation_domain: choice_translation_domain,
181                valid: valid,
182            }) -}}
183        {% endfor -%}
184    </div>
185{%- endblock choice_widget_expanded %}
186
187{# Labels #}
188
189{% block form_label -%}
190    {% if label is not same as(false) -%}
191        {%- if compound is defined and compound -%}
192            {%- set element = 'legend' -%}
193            {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' col-form-label')|trim}) -%}
194        {%- else -%}
195            {%- set label_attr = label_attr|merge({for: id}) -%}
196        {%- endif -%}
197        {% if required -%}
198            {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
199        {%- endif -%}
200        {% if label is empty -%}
201            {%- if label_format is not empty -%}
202                {% set label = label_format|replace({
203                    '%name%': name,
204                    '%id%': id,
205                }) %}
206            {%- else -%}
207                {% set label = name|humanize %}
208            {%- endif -%}
209        {%- endif -%}
210        <{{ 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') }}>
211    {%- else -%}
212        {%- if errors|length > 0 -%}
213        <div id="{{ id }}_errors" class="mb-2">
214            {{- form_errors(form) -}}
215        </div>
216        {%- endif -%}
217    {%- endif -%}
218{%- endblock form_label %}
219
220{% block checkbox_radio_label -%}
221    {#- Do not display the label if widget is not defined in order to prevent double label rendering -#}
222    {%- if widget is defined -%}
223        {% set is_parent_custom = parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class) %}
224        {% set is_custom = label_attr.class is defined and ('checkbox-custom' in label_attr.class or 'radio-custom' in label_attr.class) %}
225        {%- if is_parent_custom or is_custom -%}
226            {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' custom-control-label')|trim}) -%}
227        {%- else %}
228            {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-check-label')|trim}) -%}
229        {%- endif %}
230        {%- if not compound -%}
231            {% set label_attr = label_attr|merge({'for': id}) %}
232        {%- endif -%}
233        {%- if required -%}
234            {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) -%}
235        {%- endif -%}
236        {%- if parent_label_class is defined -%}
237            {%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|replace({'checkbox-inline': '', 'radio-inline': '', 'checkbox-custom': '', 'radio-custom': ''})|trim}) -%}
238        {%- endif -%}
239        {%- if label is not same as(false) and label is empty -%}
240            {%- if label_format is not empty -%}
241                {%- set label = label_format|replace({
242                    '%name%': name,
243                    '%id%': id,
244                }) -%}
245            {%- else -%}
246                {%- set label = name|humanize -%}
247            {%- endif -%}
248        {%- endif -%}
249
250        {{ widget|raw }}
251        <label{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}>
252            {{- label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}}
253            {{- form_errors(form) -}}
254        </label>
255    {%- endif -%}
256{%- endblock checkbox_radio_label %}
257
258{# Rows #}
259
260{% block form_row -%}
261    {%- if compound is defined and compound -%}
262        {%- set element = 'fieldset' -%}
263    {%- endif -%}
264    <{{ element|default('div') }} class="form-group">
265        {{- form_label(form) -}}
266        {{- form_widget(form) -}}
267    </{{ element|default('div') }}>
268{%- endblock form_row %}
269
270{# Errors #}
271
272{% block form_errors -%}
273    {%- if errors|length > 0 -%}
274        <span class="{% if form is not rootform %}invalid-feedback{% else %}alert alert-danger{% endif %} d-block">
275            {%- for error in errors -%}
276                <span class="d-block">
277                    <span class="form-error-icon badge badge-danger text-uppercase">{{ 'Error'|trans({}, 'validators') }}</span> <span class="form-error-message">{{ error.message }}</span>
278                </span>
279            {%- endfor -%}
280        </span>
281    {%- endif %}
282{%- endblock form_errors %}
283