Sunday, February 3, 2013

Symfony2 - Customize output of expanded form choices

I'm updating one of my projects to the current master of the symfony2 framework. One of the backwards incompatible changes I noticed are changes in the form framework. In one of my templates I need to customize the output of a list of checkboxes as shown in the screenshot of my data table.
The data for the checkboxes is taken from the database, so I'm using the 'entity' type in my form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
         ->add('cities', 'entity', array(
            'class' => 'MyCityBundle:City',
            'query_builder' => $this->queryBuilder,
            'required' => false,
            'expanded' => true,
            'multiple' => true,
        ))
    ;
} 
Using twig you could render all of the checkboxes without labels or anything else very easily: But obviously you don't want to render all checkboxes all at once, but in a loop. Each loop renders a table row and the checkbox is the content of one of the columns. You can loop over each of the choices with: That's fine. But what about the other data? The other data is part of the choice list which is saved in the form element and automatically retrieved from the database. The checkbox label and value can be retrieved via {{ child.vars.value }} and {{ child.vars.label }}. But there doesn't seem to be any possibility to retrieve all of the entity data in the twig template. What we need to do is saving the entity data in a separate variable and access it in the twig template. You could use the query builder, which was passed to the form element during creation to retrieve your entity data, but that would mean, that the whole data has to be retrieved again from the database, although it's already available somewhere in the form element. The way I extracted the entity data from the form element before Symfony 2.1 was: ...which doesn't work anymore. The new way (Symfony 2.1) to do it is: The only thing left is to connect the entity to the currently drawn checkbox. This can be done via the checkbox value, as this is the entity's ID attribute: This way you have full flexibility when rendering a complex expanded entity choice type.