Symfony2 - How to put label and input for checkboxes/radios in a same line?

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 %}

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 %}

I had the same problem, and I was unable to find a solution so I worked it out on my own. You are correct that you do need to override the {% block choice_widget %} block. The first step is to remove the {{ form_label(child) }} line from the {% if expanded %} section that prints out a separate label.

{% block choice_widget %}
{% spaceless %}
    {% if expanded %}
        <div {{ block('widget_container_attributes') }}>
        {% for child in form %}
            {{ form_widget(child) }}
        {#  {{ form_label(child) }} <--------------------- remove this line #}  
        {% endfor %}
        </div>
    {% else %}
    <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
        {% if empty_value is not none %}
            <option value="">{{ empty_value|trans }}</option>
        {% endif %}
        {% if preferred_choices|length > 0 %}
            {% set options = preferred_choices %}
            {{ block('widget_choice_options') }}
            {% if choices|length > 0 and separator is not none %}
                <option disabled="disabled">{{ separator }}</option>
            {% endif %}
        {% endif %}
        {% set options = choices %}
        {{ block('widget_choice_options') }}
    </select>
    {% endif %}
{% endspaceless %}
{% endblock choice_widget %}

Now you will just need to handle printing the label in the {% block checkbox_widget %} block.

{% 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 %}

You will need to do the same for {% block radio_widget %} since it would not otherwise have a label now.

{% 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 %}

Tags:

Php

Twig

Symfony