In my form I have some checkboxes, but by default, I have :
In Symfony 2.4, this doesn't work quite as expected.
{% block checkbox_widget %}
{% spaceless %}
<label for="{{ id }}"><input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock checkbox_widget %}
...the label is not available. You need to add the following:
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
So a complete solution is:
{% block checkbox_widget %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
{% spaceless %}
<label for="{{ id }}"><input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock checkbox_widget %}
When a label is rendered it will include a for
attribute - this links the label
to the input
- see the docs on label here changing the output to what you suggested is just another way of linking the label
and the input
If you want the label to display to the left of the input you need to change your template to :
{% for child in form %}
<div>
{{ form_label(child) }} {{ form_widget(child) }}
</div>
{% endfor %}
Which renders the label
before the input
and then this creates the following output
<div>
<div>
<label ...></label>
<input ...>
</div>
<div>
<label ...></label>
<input ...>
</div>
</div>
You can then apply some CSS styling to make it display inline :
div label {
display: inline-block;
width: 200px;
}
By default - without any CSS the label
would line up before the input
with this HTML layout - but the inline-block
allows you to also use the width
attribute to ensure all fields are lined up correctly - irrespective of the length of label text
Working example here
With help from Alberto Gaona and James, Symfony 2.4 correct solution to integrate BS3 radio AND checkboxes is as follow :
In your view you have :
{% form_theme form 'AcmeDemoBundle:Form:fields.html.twig' %}
// A radio or checkbox input
{{ form_widget(form.example) }}
Then in your fields.html.twig (which overrides https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig ; see http://symfony.com/doc/current/cookbook/form/form_customization.html)
{# src/Acme/DemoBundle/Resources/views/Form/fields.html.twig #}
{% block choice_widget_expanded %}
{% spaceless %}
<div {{ block('widget_container_attributes') }}>
{% for child in form %}
{% if multiple %}
<div class="checkbox">
{% else %}
<div class="radio">
{% endif %}
{{ form_widget(child) }}
</div>
{% endfor %}
</div>
{% endspaceless %}
{% endblock choice_widget_expanded %}
{% block checkbox_widget %}
{% spaceless %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
<label for="{{ id }}">
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans({}, translation_domain) }}
</label>
{% endspaceless %}
{% endblock checkbox_widget %}
{% block radio_widget %}
{% spaceless %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
<label for="{{ id }}">
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans({}, translation_domain) }}
</label>
{% endspaceless %}
{% endblock radio_widget %}
NOTE: Updated Bob F solution for Symfony 2.3 (see https://github.com/symfony/symfony/blob/2.3/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig):
Override choice_widget_expanded:
{% block choice_widget_expanded %}
{% spaceless %}
<div {{ block('widget_container_attributes') }}>
{% for child in form %}
{{ form_widget(child) }}
{% endfor %}
</div>
{% endspaceless %}
{% endblock choice_widget_expanded %}
Override checkbox (bootstrap style):
{% block checkbox_widget %}
{% spaceless %}
<label for="{{ id }}" class="checkbox {% if checked %}checked{% endif %}" ><span class="icons"><span class="first-icon fui-checkbox-unchecked"></span><span class="second-icon fui-checkbox-checked"></span></span><input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock checkbox_widget %}
Override radiobutton
{% block radio_widget %}
{% spaceless %}
<label for="{{ id }}"><input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />{{ label|trans }}</label>
{% endspaceless %}
{% endblock radio_widget %}
Putting the form input inside the label tag would result in broken HTML.
What is your goal? If you are simply looking to make the label and input show on the same line in the browser, then you could use css:
input, label {
display: inline;
}
You can overide the form_row function like that (modified to fit the temple label / checkbox of twitter bootstrap ) : (in that exemple it's "checkbox" but i think with "radio" it works the same)
{% extends 'form_div_layout.html.twig' %}
{% block field_row %}
{% spaceless %}
{% if 'checkbox' in types %}
{% if not compound %}
{% set label_attr = label_attr|merge({'for': id}) %}
{% endif %}
{% if required %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{% endif %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
<label class="checkbox" {% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}
{{ block('checkbox_widget') }}
</label>
{% else %}
{{ parent() }}
{% endif %}
{% endspaceless %}
{% endblock field_row %}