Personalizar el tipo "collection" de un formulario Symfony en una plantilla Twig

Buenas, en un formulario que tiene un CollectionType al mostrar los campos en Twig, me añade un label extra llamado "control-label required" con el index de cada elemento.

Adjunto una captura de pantalla para dar mas detalle

El formulario sería este:

$builder->add('contentsNav', CollectionType::class, array(
   'label' => false,
   'entry_type' => ContentsNavForm::class,
   'allow_add' => true,
   'allow_delete' => true,
));

He intentado aplicar la solución a un error igual en el MopaBootstrapBundle (en mi proyecto no lo utilizo) pero no funciona .... =(

Muchas gracias

Respuestas

#1

¿Y no podrías resolver este problema mediante la opción prototype del CollecitonType?

#2

Gracias por contestar Javier,

Si es tal como lo estoy poniendo, sigue mostrando el número de elementos ...

$builder->add('contentsNav', CollectionType::class, array(
  'label' => false,
  'entry_type' => ContentsNavForm::class,
  'entry_options' => ['contentsNav' => $options['contentsNav']],
  'allow_add' => true,
  'allow_delete' => true,
  'prototype' => false
));

La vista es la siguiente:

{{ form_start(formNavContents) }}
<table class="table table-striped table-hover">
    <thead>
    <tr>
        <th>#</th>
        <th>Name</th>
        <th>Parent</th>
        <th>Sort</th>
        <th>Action</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td colspan="5">{{ form_row(formNavContents.name) }}</td>
    </tr>
    <tr class="success">
        <td colspan="5">Contents</td>
    </tr>
    {% for content in formNavContents.contentsNav %}
        <tr>
            <td>{{ loop.index }}</td>
            <td>{{ content.vars.value.name }}</td>
            <td>{{ form_row(content.parent) }}</td>
            <td>{{ form_row(content.sort) }}</td>
            <td><a href="{{ path('admin_nav_new_remove_element', {'idRemove': content.vars.value.idElement}) }}"
                   class="btn btn-danger btn-md btn-block"><i class="fa fa-trash"></i></a>
            </td>
        </tr>
    {% else %}
        <tr class="active">
            <td colspan="5">There are not contents</td>
        </tr>
    {% endfor %}
    <tr class="active">
        <td colspan="5">
            <button type="submit" class="btn btn-primary btn-xs btn-block"> Add nav</button>
        </td>
    </tr>
    </tbody>
</table>
 
{{ form_end(formNavContents) }}
#3

Hola @JuanluGarciaB, ¿donde exactamente te aparece ese label, al final donde se imprime el {{ form_end(form) }} o es en otra parte?

Si la respuesta es que aparece al final, es muy probable que ocurra debido a que aunque estas recorriendo he imprimiendo cada elemento de la colección, no estas imprimiendo la propia colección, es por ello que symfony intenta imprimirla al llamar a form_end.

Podrias probar a colocar lo siguiente antes de llamar a form_end:

{% do formNavContents.contentsNav.setRendered() %}

Con eso le dices a symfony que ya ese campo fué renderizado, y así symfony no intentará hacer su propio renderizado de dicho colección.


Por otro lado, veo que tienes el siguiente código: <td>{{ form_row(content.parent) }}</td> no se que intentas hacer allí, si imprimir un campo llamado parent o imprimir el formulario padre de content. Lo que si es que debes tener cuidado allí, ya que twig puede estar llamando al campo padre en vez de a un posible hijo con ese nombre, esto debido a que la clase FormView de symfony tiene un atributo público llamado $parent.

Espero haberme explicado bien, Saludos!

#4

Hola @manuel_j555, Efectivamente, con eso no se muestra. Una cosa nueva que he aprendido jeje.

Estoy haciendo un mini CMS multiidioma, y el apartado de este formulario comentado anteriormente es la gestión personalizada de el menú. El {{ form_row(content.parent) }} hace referencia a los SubElementos de el menú.

Ej:

-Deportes (Baloncesto,Balonmano, etc)

Muchas gracias por la ayuda

#5

Hola nuevamente, Al poner en twig {{ do formNavContents.contentsNav.setRendered() }} no se muestran los elementos, pero internamente no carga los campos del formularios aunque estén rellenos ...

A unas últimas de manera "provisional" lo ocultaré con CSS, ya me pica mucho la curiosidad...

#6

Hola @JuanluGarciaB No se si pudiste resolver el problema, sin embargo te dejo la forma en que yo trabajo las colecciones de formularios, podría servirte como idea.

Lo primero es que yo separo la colección en una plantilla twig independiente llamada prototype.html.twg, así puedo tener control de las etiquetas.

<!-- app/Resources/views/default/prototype.html.twig -->
<tr>
    <td>#</td>
    <td>{{ form_widget(form.quantity) }}</td>
    <td>{{ form_widget(form.product) }}</td>
    <td><div id="product_name"></div></td>
    <td>{{ form_widget(form.status) }}</td>
</tr>

Y dentro de la plantilla coloco lo siguiente:

<tbody class="details" data-prototype="{% filter escape %}{% include 'entrancedetail/prototype_edit.html.twig' with {'form': edit_form.details.vars.prototype} %}{% endfilter %}"></tbody>

Ahora, para modificar puntualmente los input de un formulario, puedes ver alguno de los archivos de vendor/symfony/symfony/Bridge/Twig/Resources/views/Form

Espero sirva de algo.

P.D. Esto no es invento mío, todo está en la documentación.

#7

@JuanluGarciaB, como estas? he encontrado este post recientemente. Tengo el inconveniente que necesito mostrar una collection type como una tabla, y no lo logro. En mi plantilla tiwg muestro los compos con la variable prototype como lo dice la documentación y tu ejemplo, pero en vez de aparecer como renglón de tabla,un campo en cada columna, aparece un form vertical ocupando el espacio de la primera columna. Una vez que envió el formulario, con error por ejemplo y la lista tenia datos, al renderizarlo nuevamente aparece la ta la tal como la quiero. Tenes idea que puede ser?

Te agradezco el tiempo aunque se que trabajaste con esto hace rato. Virginia