Trabajando con formularios complejos en Symfony2 nos encontramos muchas veces con la necesidad de integrar colecciones de formularios que mantienen relaciones entre sí. En la documentación oficial de Symfony, encontramos un excelente artículo en el que se explica perfectamente cómo embeber una colección de formularios. En ese caso, se explica cómo embeber formularios de una entidad Tag con un campo name en el formulario de una entidad Task con la que existe una relación N:M.
En ese mismo artículo se explica igualmente cómo añadir múltiples formularios embebidos usando "prototye". Pero qué ocurre si nos encontramos con la necesidad de tener que mostrar ese formulario de una forma personalizada, de acceder a cada uno de los campos del formulario, a su form_widget, etc.
En nuestras plantillas twig tenemos disponible el prototype del formulario en form.collection.vars.prototype
, por lo que si queremos acceder, por ejemplo, a un campo nombre de ese formulario embebido, lo encontraremos en form.collection.vars.prototype.nombre
. Conociendo esto, podremos crear plantillas twig en las que acceder a cada uno de los elementos del formulario embebido y personalizar su visualización.
Por tanto, necesitaremos el prototype del formulario para poderlo embeber tantas veces como queramos, tal y como se explica en el artículo de la documentación oficial de Symfony que comentábamos al principio, aunque en este caso, con alguna diferencia ya que incluimos enl atributo data-prototype una plantilla a la que le pasamos como variable elem el form.collection.vars.prototype
de nuestro formulario embebido:
<ul class="tags" data-prototype="{% filter escape %}{% include 'formembed.twig' with { 'elem': form.collection.vars.prototype } %}{% endfilter %}">
...
</ul>
Hecho esto, solo faltará crear la plantilla formembed.twig a la que se hace referencia en el prototype y personalizar la forma en la que mostramos todos los campos, según las necesidades que tengamos en nuestro proyecto Symfony, como con cualquier formulario normal, por ejemplo, mostrando los campos como registros de una tabla:
<tr>
<td>{{ form_row(elem.campo_1) }}</td>
<td>{{ form_row(elem.campo_2) }}</td>
<td>{{ form_row(elem.campo_3) }}</td>