David Rojo David Rojo - 1 month ago 15
PHP Question

Symfony forms, show ManyToMany relation as a list of checkboxes instead of a select

I want to show a ManyToMany relation in an entity as a list of checkboxes in a form instead of a select with the multiple selection.

In my entity I have this:

/**
* @var ArrayCollection
*
* @ORM\ManyToMany(targetEntity="Language")
* @ORM\JoinTable(name="courses_languages",
* joinColumns={@ORM\JoinColumn(name="course_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="language_id", referencedColumnName="id")}
* )
*/
private $languages = [];


And in my FormType for this entity I have this:

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('languages', ChoiceType::class, [
'multiple' => true,
'expanded' => true
])
;
}


But when setting multiple and expanded to true I receive this error:

Unable to transform value for property path "languages": Expected an array.


I've investigated and it is in
Symfony\Component\Form\Extension\Core\DataTransformer\ChoicesToValuesTransfomer
in function transform

public function transform($array)
{
if (null === $array) {
return array();
}

if (!is_array($array)) {
throw new TransformationFailedException('Expected an array.');
}

return $this->choiceList->getValuesForChoices($array);
}


The type of the array is
Doctrine\ORM\PersistentCollection
so it fails in checking is_array.

How could I fix this?
Thank you

Answer

Change ChoiceType by EntityType (setting class option) or simply leave it null, Doctrine is able to guess the type (EntityType in this case) from your mapped property:

$builder
    ->add('languages', null, [
        'multiple' => true,
        'expanded' => true
    ]);

In a nutshell, the problem is that ChoiceType is designed to work with array of elements whilst EntityType with array and Doctrine\Common\Collections\Collection as well.

Comments