nyluje nyluje - 6 months ago 71
Javascript Question

Symfony form_widget() in Twig gives <input> wrapped in a <div> (with jQuery and jQuery-mobile)

For this case, let's pretend I implement a form with the official example: http://symfony.com/doc/current/book/forms.html

At the "Rendering each Field by Hand" title, I want to add some attribute in the twig file so all my fields are evenly placed on a row by using "col-* css" manner to occupy space on a row.

{{ form_start(form) }}
<div class="col-12">
{{ form_label(form.task,null,{'label_attr': {'class':'col-3'}}) }}
{{ form_widget(form.task, {'attr': {'class': 'col-4' }}) }}
{{ form_errors(form.task, {'attr': {'class': 'col-5'}}) }}
</div>

{{ form_end(form) }}


With that example, the rendering of form_widget will be:

<div class="ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset">
<input type="text" id="task_task" name="task[task]" required="required" class="col-4">
</div>


One notices that "col-4" class attribute is in the
input
tag but since this tag is surrounded by a
div
the display is not as expected and the "col-4" should be indeed in the
div
tag which is the parent of the
input
tag
so as to have the "col-4" rule applying on the screen.

So I wonder if there is a way with the symfony form to transfer the class attribute of the
input
set with Twig function form_widget() to its parent
div
instead of going with the jQuery javascript function to fix the DOM display?

Answer

I did a workaround by creating a template file that redefines the form input_inline_template.twig.html.

As one can see it edits the form_div_layout.html.twig which can be found in the main form themes file.

The block {% block form-widget %} can be substituted with various cases depending on the widget wanted.

You can then use this file by entering: {% form_theme form 'YourBundle:[folder to file]:input_inline_template.html.twig' %}.

{% extends 'form_div_layout.html.twig' %} 
{% block form_row  %}
    <div class='col-12' id={{ id ~ '_div_row_id'}}>
    {% block form_label   %}
        <div class='col-3' id={{ id ~ '_div_label_id' }}>
            {{ parent() }}
        </div>
    {% endblock %}

        {% block form-widget %}
            <div class='col-4'>
                {{ parent() }}  
            </div>
        {% endblock %}

    {% block form_errors %}
        <div class='col-5'>

            {%- if errors|length > 0 -%} 
                {%- for error in errors -%}
                    <div id={{ id ~ "_error_msg_id" }}>{{ error.message }}</div>
                {%- endfor -%}
            {%- endif -%} 
        </div>
    {% endblock %}

    </div>
{% endblock %}
Comments