4

I'm trying to customize Symfony2 form rendering to add a class to every select that is generated. I thought that having a custom form_div_layout.html.twig with:

{% block choice_widget_collapsed %}
{% spaceless %}
    <select class='myclass' {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
    {% if empty_value is not none %}
        <option value="">{{ empty_value|trans({}, translation_domain) }}</option>
    {% endif %}
    {% if preferred_choices|length > 0 %}
        {% set options = preferred_choices %}
        {{ block('choice_widget_options') }}
        {% if choices|length > 0 and separator is not none %}
            <option disabled="disabled">{{ separator }}</option>
        {% endif %}
    {% endif %}
    {% set options = choices %}
    {{ block('choice_widget_options') }}
</select>
{% endspaceless %}
{% endblock choice_widget_collapsed %}

and using it with

{% form_theme form 'YOPYourOwnPoetBundle:Form:form_div_layout.html.twig' %}

would do the trick.

However, the class 'myclass' isn't added to the select. What am I doing wrong?

1
  • Are you passing any additional classes by chance? It would help if you also pasted the generated html here. Commented Jul 6, 2012 at 6:21

2 Answers 2

4

You should first make sure the theme file you're trying to use has the same name as the name you're using in the form_theme expression and that the file really is there. I can't remember off top of my head whether Twig throws an exception or not in case these do not match.

In addition, you might be accidentally passing a class attribute either when building a form or rendering it. What happens is that your element now has two class attributes.

A workaround is to actually add your new class to the collection of existing ones.

{% block choice_widget_collapsed %}
{% spaceless %}
{% set label_attr = label_attr|merge({class: label_attr.class|default('') ~ ' required'}) %}
    {% set attr = attr|merge({class: (attr.class|default('') ~ ' myclass')|trim}) %}
    <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
    {# ... #}
</select>
{% endspaceless %}
{% endblock choice_widget_collapsed %}

This allows you to add any optional class you might need for specific elements later on.

EDIT

Looking at the Sf2 Github repsitory it seems that the theme file has been recently changed. In versions 2.0.* you should be overriding choice_widget, in versions 2.1.* the correct block is choice_widget_collapsed.

Sign up to request clarification or add additional context in comments.

1 Comment

You got that right! I'm using Symfony2.0.14 so I was looking at the wrong version of the file form_div_layout.html.twig. Adding a class='myclass' to choice_widget instead of choice_widget_collapsed works. Besides, your solution to use {% set attr = attr|merge({class: 'myclass' ~ (attr.class is defined ? ' ' ~ attr.class : '')}) %} works too, that's what i'm gonna use. Thanks a lot.
0

I suppose you should either change the form theme line to:

{% form_theme form 'YOPYourOwnPoetBundle:Form:form_div_layout.html.twig' %}

or you need to change the name of your twig file into fields.html.twig

Both have to match.

6 Comments

The template name is irrelevant.
@gilden If you try to "load" a new twig template via form_theme the name of the template file should match the name you want to load shouldn't it, otherwise there will be no file to load
Not a single time have I had to name my form theme template form_div_layout.html.twig. Even the cookbook article uses a different template name in the example.
The only thing I said was that the name of your template file must match the name you use when you load it via form_theme. Thats exactly as described in the documentation you have linked. Both (the name of the template file and the name in form_theme) are the same (fields.html.twig)
Ah, sorry, my bad. Guess I'm still sleeping :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.