Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to wrap label around input in symfony2?

Question about symfony2 form component and its templating:

I've got a bunch of checkboxes to style (about 10 in one form row). Usually I use <label> tag this way: <label><input/> some text</label> but I can't find a way to change it in the form template (form_div_layout.html.twig). I can't even find a way to wrap any tag around input widget and its label and I always end up with markup like this: <input/> <some_tag><label>some text</label></some_tag> or <some_tag><input/></some_tag> <label>some text</label> which is not very useful, to say the least...

Googled quite a bit, but couldn't find an answer.

like image 314
heliogabal Avatar asked May 30 '12 11:05

heliogabal


2 Answers

Whistlegreg is correct that you will need to override the twig form templates. However, you do not need to remove the {% block generic_label %} block. See his answer if you need help on how to override the templates.

In order to wrap the checkbox input tags with a label, the first step will be to override the {% block choice_widget %} block and 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 %}
like image 67
Bob F. Avatar answered Sep 21 '22 23:09

Bob F.


I think this is what you are looking for: http://symfony.com/doc/current/book/templating.html#overriding-bundle-templates

You can override any of the default twig templates by creating another file with the same name in your app/resources folder.

In your case you want to override the form_div_layout.html.twig template, copy it from the bundle to app/Resources/TwigBundle/views/Form/form_div_layout.html.twig, customize away and symfony will use that rather than the default.

EDIT: Once you have overridden the template you could modify the {% block checkbox_widget %} to have the input wrapped with the label tags using the twig vars

<label{% for attrname,attrvalue in attr %} {{attrname}}="{{attrvalue}}"{% endfor %}>
  {{label|trans }} 
  <input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} /> 
</label> 

You will also need to remove the 'generic_label' definition, meaning every other block requires modifications.

like image 20
greg Avatar answered Sep 24 '22 23:09

greg