jspizziri
jspizziri

Reputation: 793

Symfony Form Label Rendering

I want to convert all my labels for to placeholders for that input:

Ex:

This is standard:

<div>
  <label>FooBar</label>
  <input type="text"/>
</div>
<div>
  <label>FooBar2</label>
  <input type="checkbox"/>
</div>

This is what I want:

<div>
  <input type="text" placeholder="FooBar"/>
</div>
<div>
  <label>FooBar2</label>
  <input type="checkbox"/>
</div>

I have attempted to to this by overriding parts of the twig form template, but have been unsuccessful. Here is one attempt:

{% block form_widget_simple %}
    {% set type = type|default('text') %}

        {% if type == 'text' %}
                    {% block form_label %}{% endblock %}
        {% endif %}

    <input placeholder="{{ label|trans({}, translation_domain) }}" data-test="formtest" type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% endblock form_widget_simple %}

Thanks!

Upvotes: 3

Views: 3685

Answers (7)

Henry
Henry

Reputation: 7891

If you are using the new bootstrap theme:

{% extends 'bootstrap_3_layout.html.twig' %}

{% block form_row -%}
    <div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
        {% if form.vars.block_prefixes[1] != 'text' %}
            {{ form_label(form) }}
        {% endif %}
        {{ form_widget(form) }}
        {{ form_errors(form) }}
    </div>
{%- endblock form_row %}

{% block form_widget_simple -%}
    {% if attr.placeholder is not defined or attr.placeholder == '' %}
        {% set attr = attr|merge({placeholder: label|trans({}, translation_domain)|trim(':')|trim}) %}
    {% endif %}

    {% if type is not defined or 'file' != type %}
        {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) %}
    {% endif %}
    {{- parent() -}}
{%- endblock form_widget_simple %}

{% block textarea_widget -%}

    {% if attr.placeholder is not defined or attr.placeholder == '' %}
        {% set attr = attr|merge({placeholder: label|trans({}, translation_domain)|trim(':')|trim}) %}
    {% endif %}

    {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) %}
    {{- parent() -}}
{%- endblock textarea_widget %}

Note: I added |trim(':') to remove the colons from the end of the labels produced by FOSUserBundle.

Also for my project I wanted large inputs so I added input-lg here (both simple and textarea):

{% set attr = attr|merge({class: (attr.class|default('') ~ ' input-lg form-control')|trim}) %}

Upvotes: 0

L&#233;o Benoist
L&#233;o Benoist

Reputation: 2541

Shorter way and keeping the original block code (to still have update).

{% use 'form_div_layout.html.twig' with widget_attributes as base_widget_attributes %}
{% block widget_attributes %}
    {% set attr = {'placeholder': label|trans({}, translation_domain)} %}
    {{- block('base_widget_attributes') -}}
{% endblock widget_attributes %}

Upvotes: 0

jspizziri
jspizziri

Reputation: 793

After leaving this sit for a while and learning more twig I finally came back to it and did it the right way.

IMO, this is how it should be done:

{% extends 'form_div_layout.html.twig' %}


{# override label creation, remove all labels from inputs and text areas #}

{% block form_row %}
{% spaceless %}
    <div>
    {% if form.vars.block_prefixes[1] != 'text' %}
        {{ form_label(form) }}
    {% endif %}
    {{ form_errors(form) }}
    {{ form_widget(form) }}
    </div>
{% endspaceless %}
{% endblock form_row %}


{# widgets #}
{% block form_widget_simple %}
    {% set type = type|default('text') %}
    <input placeholder="{{ label|trans({}, translation_domain) }}" type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% endblock form_widget_simple %}

{% block textarea_widget %}
{% spaceless %}
    <textarea placeholder="{{ label|trans({}, translation_domain) }}" {{ block('widget_attributes') }}>{{ value }}</textarea>
{% endspaceless %}
{% endblock textarea_widget %}

Works like a charm!

Upvotes: 1

Elnur Abdurrakhimov
Elnur Abdurrakhimov

Reputation: 44851

I created a Bootstrap bundle that has a dedicated option for that. You can search the form theme for the labels_to_placeholders term to see how it's implemented.

Or, if your using Bootstrap yourself, just use my bundle. ;)

Upvotes: 0

ncrocfer
ncrocfer

Reputation: 2570

Perhaps in the widget_attributes block :

{% block widget_attributes %}
  {% spaceless %}

    {% set type = type|default('text') %}

    {% for attrname,attrvalue in attr %}{{attrname}}="{{attrvalue}}" {% endfor %} 

    {% if type == 'text' %}
        placeholder="{{ label|trans }}"
    {% endif %}

  {% endspaceless %}
{% endblock widget_attributes %}

Upvotes: 0

Johann
Johann

Reputation: 758

Have you told Twig to use your custom template to theme the forms? You can do this in each page which contains a form by adding this line:

{% form_theme form 'AcmeDemoBundle:Form:fields.html.twig' %}

Or do it once for all your forms in your config.yml file:

twig:
    form:
        resources:
            - 'AcmeCoreBundle::fields.html.twig'

Upvotes: 0

ILikeTacos
ILikeTacos

Reputation: 18696

Would something like this work?

{{ form_widget(form.yourFormField, {'attr': {'placeholder': twigVariableYouWantToUseAsPlaceHolder}}) }}

I usually use the form_widget function to have complete control over the HTML element that is being created by Symfony Forms.

There's a more complete example here: http://symfony.com/doc/current/cookbook/form/form_customization.html

Upvotes: 0

Related Questions