Skip to content

Instantly share code, notes, and snippets.

@ttskch
Last active January 26, 2020 01:06
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ttskch/297328a5cd6f50052852eb814c1e777e to your computer and use it in GitHub Desktop.
Save ttskch/297328a5cd6f50052852eb814c1e777e to your computer and use it in GitHub Desktop.
Symfony Form Theme for Bootstrap4
$color-danger: #dc3545;
$color-success: #28a745;
.form-group > label {
&.required {
&:after {
content: " *";
color: $color-danger;
}
}
}
.form-control.form-control-unstyled {
padding: 0;
border: none;
.form-check.form-check-inline {
margin-bottom: 0;
margin-top: 0.2rem;
}
&.is-invalid {
color: $color-danger;
}
&.is-valid {
color: $color-success;
}
}
{% extends 'my-form-layout.html.twig' %}
{% block form_row -%}
<div class="form-group row">
{{- form_label(form, null, { label_attr: { class: label_attr.class|default('') ~ ' col-form-label col-sm-3' } }) -}}
<div class="col-sm-9">
{{- form_widget(form, { attr: { class: errors|length ? 'form-control is-invalid': 'form-control' } }) -}}
{{- form_errors(form) -}}
</div>
</div>
{%- endblock form_row %}
{% extends 'form_div_layout.html.twig' %}
{% block form_row -%}
<div class="form-group">
{{- form_label(form) -}}
{{- form_widget(form, { attr: { class: errors|length ? 'form-control is-invalid': 'form-control' } }) -}}
{{- form_errors(form) -}}
</div>
{%- endblock form_row %}
{% block form_errors -%}
{%- for error in errors|default([]) -%}
<div class="invalid-feedback">{{ error.message|trans }}</div>
{%- endfor -%}
{%- endblock form_errors %}
{% block choice_widget_expanded -%}
<div {% with { attr: attr|merge({ class: attr.class|default('') ~ ' form-control form-control-unstyled' }) } %}{{ block('widget_container_attributes') }}{% endwith %}>
{%- for child in form %}
<div {% with { attr: child.vars.attr|merge({ class: child.vars.attr.class|default('') ~ ' form-check' }) } %}{{ block('attributes') }}{% endwith %}>
<label class="form-check-label">
{{- form_widget(child, { attr: { class: 'form-check-input' } }) }}
{{ child.vars.label }}
</label>
</div>
{% endfor -%}
</div>
{% endblock choice_widget_expanded %}
{% block form_end -%}
{% if not render_rest is defined or render_rest %}
{{- form_rest(form) -}}
{% endif -%}
<button class="btn btn-primary">{{ 'Send'|trans }}</button>
</form>
{%- endblock form_end %}
<?php
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Validator\Constraints as Assert;
$form = $app['form.factory']->createBuilder(FormType::class)
->add('name', TextType::class, [
'attr' => [
'autofocus' => true,
],
'constraints' => [
new Assert\NotBlank(),
],
])
->add('email', EmailType::class, [
'constraints' => [
new Assert\NotBlank(),
new Assert\Email(),
],
])
->add('gender', ChoiceType::class, [
'choices' => $genderChoices = [
'male' => 'male',
'female' => 'female',
'other' => 'other',
],
'choice_attr' => function ($value, $key, $index) {
return [
'class' => 'form-check-inline',
];
},
'data' => 'male',
'expanded' => true,
'multiple' => false,
'constraints' => [
new Assert\NotBlank(),
new Assert\Choice(array_keys($genderChoices)),
],
])
->add('interesting_services', ChoiceType::class, [
'required' => false,
'choices' => [
'Service A' => 'Service A',
'Service B' => 'Service B',
'Service C' => 'Service C',
],
'expanded' => true,
'multiple' => true,
])
->add('message', TextareaType::class, [
'attr' => [
'rows' => 5,
],
'constraints' => [
new Assert\NotBlank(),
],
])
->getForm()
;
return $form;
@ttskch
Copy link
Author

ttskch commented Oct 15, 2017

my-form-layout.html.twig

normal invalid
image image

my-form-horizontal-layout.html.twig

normal invalid
image image

@ttskch
Copy link
Author

ttskch commented Oct 15, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment