Adding dynamic choices to ChoiceType form field in Symfony 6

34 Views Asked by At

Environment is Symfony 6.4.5 and I'm trying to use select2 on the front end and a choicetype field as part of a form on the back end.

Form class that is trimmed down and includes a PRE-SUBMIT event listener to dynamically add the options

class UnitEditFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {

        $builder
            ->add('amenity',  ChoiceType::class, ['label' => ' ', 'expanded' => false, 'multiple' => true, 'attr' => ["class" => 'form-select multi-selector', 'data-placeholder' => 'This is only a test'], 'row_attr' => ['class' => "col-md-6 m-4"] ])

            ->add('save', SubmitType::class, ['label' => 'Save', 'attr' => ['class' => 'btn btn-a']])


            ->addEventListener(FormEvents::PRE_SUBMIT,function (FormEvent $event): void {
                $form = $event->getForm();
                $amenity = $event->getData()['amenity'] ?? NULL;
//                dd($amenity);
                if ( !is_null($amenity) && is_array($amenity) ) {
                    foreach($amenity as $item){
                        $options[$item] = $item;
                    }
                    if($amenity){
                        $form->add('amenity', ChoiceType::class, ['choices' => $options]);
                    }
                }
                return;
//                dd($form->get('amenity')->getConfig()->getOption('choices'));

            } )
        ;

    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'csrf_protection' => true,
            'data_class' => 'App\Entity\Unit',
            'attr' => ['class' => 'row']
        ]);
    }
}

This is the relevant unit entity type

class Unit
{
#enforces constraint checking on arrays
    /**
     *
     *
     * @Assert\Valid()
     */

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;
    
    ...

    #[ORM\Column(type: Types::ARRAY, nullable: true)]
    private ?array $amenity = null;

    ...

    public function getAmenity(): ?array
    {
        return $this->amenity;
    }

    public function setAmenity(?array $amenity): static
    {
        $this->amenity = $amenity;
//        dd($this->amenity);

        return $this;
    }
}

The front end works mostly as expected. I'm left with two problems, that are likely connected. 1)

  • When the event listener form->add line adds the choices to the ChoiceType field, I get an error "Submitted data was expected to be text or number, array given.". This error is attached at the form level and not the field level. I've confirmed the choice was added both by the dd and by the debug console.
  • When the event listener form-add line is commented out I get an error "The choices "xxxx" do not exist in the choice list." The error is attached to the field and not the form. The respective values entered into the form are available in the debug console.
  1. When the form-add() choice is enabled and I submit the form while there is already data persisted to that field (saved in the db), it comes back with "Warning: Array to string conversion " on .. \vendor\symfony\form\ChoiceList\ArrayChoiceList.php:67 If I remove the data in the db for this field, the error goes away.

If I add the choices to the field ie. 'choices' => ['test' => 'test', 'another' => 'another'] and I enter one or both of those values, they are saved.

Desired is that I can dynamically add the user choices to the form without getting these errors.

0

There are 0 best solutions below