Steven Brown

Symfony 2 Bootstrap CSS Form Templates

by on Aug.26, 2011, under CSS, PHP, Symfony

I have been playing around a bit with the Twitter Bootstrap CSS toolkit and I wanted to style the forms in a Symfony 2 project accordingly. On its own this is not a difficult task, you can do the following:

<form>
    <div class="clearfix">
        {{ form_label(form.email, 'Email Address') }}
        <div class="input">
            {{ form_widget(form.email) }}
            <span class="help-inline">{{ form_errors(form.email) }}</span>
        </div>
    </div>
    {{ form_rest(form) }}
    <input type="submit" />
</form>

This is fine enough, but it would be great to be able to do all of this using {{ form_row(form.email) }} instead of having to copy and paste the code for every field in every form.

As it turns out, creating your own templates for this stuff is pretty easy. One thing to note is if we want to mark the row as an “error” we need to add that class to the main div as well as the field itself. I also wanted to get rid of the bullet list, though you could probably achieve something similar with CSS modifications. The end result was:

{% extends 'form_div_layout.html.twig' %}
 
{% block field_errors %}
{% spaceless %}
    <span class="help-inline">
        {% if errors|length > 0 %}
            {% for error in errors %}
                {{ error.messageTemplate|trans(error.messageParameters, 'validators') }}<br />
            {% endfor %}
        {% endif %}
    </span>
{% endspaceless %}
{% endblock field_errors %}
 
{% block field_row %}
    <div class="clearfix {% if errors|length > 0 %}error{% endif %}">
        {{ form_label(form, label) }}
        <div class="input">
            {% set class = '' %}
            {% if errors|length > 0 %}
                {% set class = 'error' %}
            {% endif %}
            {{ form_widget(form, { 'attr': { 'class': class } }) }}
            {{ form_errors(form) }}
        </div>
    </div>
{% endblock field_row %}

One additional trick I added here is to be able to specify the field label in the form_row() call, something that doesn’t seem to be possible by default. Now you can add a Bootstrap ready form field row with:

{% form_theme form 'BootstrapCssBundle:Form:fields.html.twig' %}
<form>
    {{ form_row(form.email, { 'label': 'Email Address' }) }}
    {{ form_rest(form) }}
    <input type="submit" />
</form>

That’s all you need! You can put the form theme command before your form and do {{ form_widget(form) }} if you want to output the entire form in one go, as usual.

I actually broke out the styles into a few files in my Github repository.

:, , , , , , ,

4 Comments for this entry

  • Jay

    Hi Steven,
    Thanks for these snippets.

    i’m also trying to adapt the Symfony’s form to Twitter’s bootstrap convension.

    I’m trying to adapt the expanded choices (radios or checkboxes) without success.

    I want to wrap checkboxes in ul > li > label
    Any ideas ?

  • Steven Brown

    Hi Jay,

    I think what you need is something like this:

    {% block choice_widget %}
        {% if expanded %}
            <ul class="inputs-list">
                {% for child in form %}
                    <li>
                        <label>
                            {{ form_widget(child) }}
                            {{ form_label(child) }}
                        </label>
                    </li>
                {% endfor %}
            </ul>
        {% else %}
            {{ parent() }}
        {% endif %}
    {% endblock choice_widget %}
     
    {% block checkbox_label %}
        <span>{{ label }}</span>
    {% endblock checkbox_label %}
     
    {% block radio_label %}
        <span>{{ label }}</span>
    {% endblock radio_label %}

    I haven’t catered for all of the attributes etc. but this worked for a list of checkboxes for me.

  • Jay

    Thanks Steven!
    It works perfectly.
    :)

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!