Skip to content

Instantly share code, notes, and snippets.

@patrickbussmann
Created July 23, 2017 14:56
Show Gist options
  • Save patrickbussmann/76f3a285b0d4ddf15e3dbb46523430ac to your computer and use it in GitHub Desktop.
Save patrickbussmann/76f3a285b0d4ddf15e3dbb46523430ac to your computer and use it in GitHub Desktop.
Bootstrap 4 layout for Symfony3
{% use "form_div_layout.html.twig" %}
{# Widgets #}
{% block form_widget_simple -%}
{% if type is not defined or type not in ['file', 'hidden'] %}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) -%}
{% endif %}
{{- parent() -}}
{%- endblock form_widget_simple %}
{% block textarea_widget -%}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) %}
{{- parent() -}}
{%- endblock textarea_widget %}
{% block button_widget -%}
{% set attr = attr|merge({class: (attr.class|default('btn-default') ~ ' btn')|trim}) %}
{{- parent() -}}
{%- endblock %}
{% block money_widget -%}
<div class="input-group">
{% set append = money_pattern starts with '{{' %}
{% if not append %}
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
{% endif %}
{{- block('form_widget_simple') -}}
{% if append %}
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
{% endif %}
</div>
{%- endblock money_widget %}
{% block percent_widget -%}
<div class="input-group">
{{- block('form_widget_simple') -}}
<span class="input-group-addon">%</span>
</div>
{%- endblock percent_widget %}
{% block datetime_widget -%}
{% if widget == 'single_text' %}
{{- block('form_widget_simple') -}}
{% else -%}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%}
<div {{ block('widget_container_attributes') }}>
{{- form_errors(form.date) -}}
{{- form_errors(form.time) -}}
{{- form_widget(form.date, { datetime: true } ) -}}
{{- form_widget(form.time, { datetime: true } ) -}}
</div>
{%- endif %}
{%- endblock datetime_widget %}
{% block date_widget -%}
{% if widget == 'single_text' %}
{{- block('form_widget_simple') -}}
{% else -%}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%}
{% if datetime is not defined or not datetime -%}
<div {{ block('widget_container_attributes') -}}>
{%- endif %}
{{- date_pattern|replace({
'{{ year }}': form_widget(form.year),
'{{ month }}': form_widget(form.month),
'{{ day }}': form_widget(form.day),
})|raw -}}
{% if datetime is not defined or not datetime -%}
</div>
{%- endif -%}
{% endif %}
{%- endblock date_widget %}
{% block time_widget -%}
{% if widget == 'single_text' %}
{{- block('form_widget_simple') -}}
{% else -%}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%}
{% if datetime is not defined or false == datetime -%}
<div {{ block('widget_container_attributes') -}}>
{%- endif -%}
{{- form_widget(form.hour) }}{% if with_minutes %}:{{ form_widget(form.minute) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second) }}{% endif %}
{% if datetime is not defined or false == datetime -%}
</div>
{%- endif -%}
{% endif %}
{%- endblock time_widget %}
{%- block dateinterval_widget -%}
{%- if widget == 'single_text' -%}
{{- block('form_widget_simple') -}}
{%- else -%}
{%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%}
<div {{ block('widget_container_attributes') }}>
{{- form_errors(form) -}}
<div class="table-responsive">
<table class="table {{ table_class|default('table-bordered table-condensed table-striped') }}">
<thead>
<tr>
{%- if with_years %}<th>{{ form_label(form.years) }}</th>{% endif -%}
{%- if with_months %}<th>{{ form_label(form.months) }}</th>{% endif -%}
{%- if with_weeks %}<th>{{ form_label(form.weeks) }}</th>{% endif -%}
{%- if with_days %}<th>{{ form_label(form.days) }}</th>{% endif -%}
{%- if with_hours %}<th>{{ form_label(form.hours) }}</th>{% endif -%}
{%- if with_minutes %}<th>{{ form_label(form.minutes) }}</th>{% endif -%}
{%- if with_seconds %}<th>{{ form_label(form.seconds) }}</th>{% endif -%}
</tr>
</thead>
<tbody>
<tr>
{%- if with_years %}<td>{{ form_widget(form.years) }}</td>{% endif -%}
{%- if with_months %}<td>{{ form_widget(form.months) }}</td>{% endif -%}
{%- if with_weeks %}<td>{{ form_widget(form.weeks) }}</td>{% endif -%}
{%- if with_days %}<td>{{ form_widget(form.days) }}</td>{% endif -%}
{%- if with_hours %}<td>{{ form_widget(form.hours) }}</td>{% endif -%}
{%- if with_minutes %}<td>{{ form_widget(form.minutes) }}</td>{% endif -%}
{%- if with_seconds %}<td>{{ form_widget(form.seconds) }}</td>{% endif -%}
</tr>
</tbody>
</table>
</div>
{%- if with_invert %}{{ form_widget(form.invert) }}{% endif -%}
</div>
{%- endif -%}
{%- endblock dateinterval_widget -%}
{% block choice_widget_collapsed -%}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) %}
{{- parent() -}}
{%- endblock %}
{% block choice_widget_expanded -%}
{% if '-inline' in label_attr.class|default('') -%}
{%- for child in form %}
{{- form_widget(child, {
parent_label_class: label_attr.class|default(''),
translation_domain: choice_translation_domain,
}) -}}
{% endfor -%}
{%- else -%}
<div {{ block('widget_container_attributes') }}>
{%- for child in form %}
{{- form_widget(child, {
parent_label_class: label_attr.class|default(''),
translation_domain: choice_translation_domain,
}) -}}
{% endfor -%}
</div>
{%- endif %}
{%- endblock choice_widget_expanded %}
{% block checkbox_widget -%}
{%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%}
{% if 'checkbox-inline' in parent_label_class %}
{{- form_label(form, null, { widget: parent() }) -}}
{% else -%}
<div class="checkbox">
{{- form_label(form, null, { widget: parent() }) -}}
</div>
{%- endif %}
{%- endblock checkbox_widget %}
{% block radio_widget -%}
{%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%}
{% if 'radio-inline' in parent_label_class %}
{{- form_label(form, null, { widget: parent() }) -}}
{% else -%}
<div class="radio">
{{- form_label(form, null, { widget: parent() }) -}}
</div>
{%- endif %}
{%- endblock radio_widget %}
{# Labels #}
{% block form_label -%}
{%- set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' form-control-label')|trim}) -%}
{{- parent() -}}
{%- endblock form_label %}
{% block choice_label -%}
{# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #}
{%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': ''})|trim}) -%}
{{- block('form_label') -}}
{% endblock %}
{% block checkbox_label -%}
{{- block('checkbox_radio_label') -}}
{%- endblock checkbox_label %}
{% block radio_label -%}
{{- block('checkbox_radio_label') -}}
{%- endblock radio_label %}
{% block checkbox_radio_label %}
{# Do not display the label if widget is not defined in order to prevent double label rendering #}
{% if widget is defined %}
{% if required %}
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
{% endif %}
{% if parent_label_class is defined %}
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %}
{% endif %}
{% if label is not same as(false) and label is empty %}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{% endif %}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
{{- widget|raw }} {{ label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans({}, translation_domain)) -}}
</label>
{% endif %}
{% endblock checkbox_radio_label %}
{# Rows #}
{% block form_row -%}
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-danger{% endif %}">
{{- form_label(form) -}}
{{- form_widget(form) -}}
{{- form_errors(form) -}}
</div>
{%- endblock form_row %}
{% block button_row -%}
<div class="form-group">
{{- form_widget(form) -}}
</div>
{%- endblock button_row %}
{% block choice_row -%}
{% set force_error = true %}
{{- block('form_row') }}
{%- endblock choice_row %}
{% block date_row -%}
{% set force_error = true %}
{{- block('form_row') }}
{%- endblock date_row %}
{% block time_row -%}
{% set force_error = true %}
{{- block('form_row') }}
{%- endblock time_row %}
{% block datetime_row -%}
{% set force_error = true %}
{{- block('form_row') }}
{%- endblock datetime_row %}
{% block checkbox_row -%}
<div class="form-group{% if not valid %} has-danger{% endif %}">
{{- form_widget(form) -}}
{{- form_errors(form) -}}
</div>
{%- endblock checkbox_row %}
{% block radio_row -%}
<div class="form-group{% if not valid %} has-danger{% endif %}">
{{- form_widget(form) -}}
{{- form_errors(form) -}}
</div>
{%- endblock radio_row %}
{# Errors #}
{% block form_errors -%}
{% if errors|length > 0 -%}
{% if form.parent %}<div class="form-control-feedback">{% else %}<div class="alert alert-danger">{% endif %}
<ul class="list-unstyled">
{%- for error in errors -%}
<li>{{ error.message }}</li>
{%- endfor -%}
</ul>
{% if form.parent %}</div>{% else %}</div>{% endif %}
{%- endif %}
{%- endblock form_errors %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment