I've got a collection of hidden fields in my form.
<ul id="user_roles">
<li><hidden field value="role1"></li>
<li><hidden field value="role2"></li>
(...)
</ul>
I use jQuery (and data-prototype) to add new roles.
The problem is that I would like to render something like this:
<ul id="user_roles">
<li>role1 <hidden field value="role1"></li>
<li>role2 <hidden field value="role2"></li>
(...)
</ul>
No problem with the initial rendering: i just put:
{% for role in roles %}
<li> {{ role }} {{ form_row(role) }} </li>
{% endfor %}
But the default data-prototype will render only {{ form_row(role) }} (a hidden field).
Where am I supposed to change the default data-prototype?
There is no {% block prototype %} in form_div_layout.html that i could customize....
The collection widget is defined as follows:
{% block collection_widget %}
{% spaceless %}
{% if prototype is defined %}
{% set attr = attr|merge({'data-prototype': form_row(prototype) }) %}
{% endif %}
{{ block('form_widget') }}
{% endspaceless %}
{% endblock collection_widget %}
So you can override this to gain control on how you want to rendre the prototype.
You can also access prototype from inside template by calling roles.vars.prototype and use it later in your JS. If you want to put it into data-prototype attribute of div (as it is normally rendered) you have to remember to escape it:
<div data-prototype="{{ form_row(roles.vars.prototype) | escape }}">
{% for role in roles %}
<li> {{ role }} {{ form_row(role) }} </li>
{% endfor %}
</div>
The method recommended in the docs allows you to easily customize each collection independently inside your app, all within the same file.
Create a file prototype_layout.html.twig
:
{% block _myform_mycollection_entry_row %}
<div class="row">
<div class="col-sm-6">{{ form_row(form.title) }}</div>
<div class="col-sm-6">{{ form_row(form.author) }}</div>
</div>
{% endblock %}
The name of the block is important. The first part will be _myform
if your parent form is called MyformType
and the second part _mycollection
if your form field owning the collection is called so. The third part must always be _entry_row
in order for this to work.
For example, if you have a UserType
form with a collection of 'books'
the block name might be _user_books_entry_row
To make sure you got the name right, add a subform (by clicking the add button adding subforms with javascript) and inspect the id of the corresponding select html element using the inspector tool of your browser.
If it looks like user_books_0_title
, then the block name will be _user_books_entry_row
Declare this file as a global form theme in the twig section of config.yml
:
twig:
form_themes:
- 'AppBundle:Form:prototype_layout.html.twig' #adapt this path if you saved your file elsewhere
You can also use the file directly in your form view:
{% use "AppBundle:Form:prototype_layout.html.twig" %}