I try to create a Symfony Custom type extending the core \"entity\" type.
But I want to use it with Select2 version 4.0.0
here's my approach based on Your bundle just for entity type in one formtype. Usage is
MyType extends ExtensibleEntityType
(dont forget parent calls on build form and configure options)
and the class itself
abstract class ExtensibleEntityType extends AbstractType
{
/**
* @var EntityManagerInterface
*/
private EntityManagerInterface $entityManager;
/**
* ExtensibleEntityType constructor.
* @param EntityManagerInterface $entityManager
*/
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function getParent()
{
return EntityType::class;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'preSetData']);
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'preSubmit'], 50);
}
/**
* @param FormEvent $event
*/
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
$parent = $event->getForm()->getParent();
$options = $form->getConfig()->getOptions();
if (!$options['pre_set_called']) {
$options['pre_set_called'] = true;
$options['choices'] = $this->getChoices($options, $event->getData());
$parent->add($form->getName(), get_class($this), $options);
}
}
/**
* @param FormEvent $event
*/
public function preSubmit(FormEvent $event)
{
$form = $event->getForm();
$parent = $event->getForm()->getParent();
$options = $form->getConfig()->getOptions();
if (!$options['pre_submit_called']) {
$options['pre_submit_called'] = true;
$options['choices'] = $this->getChoices($options, $event->getData());
$parent->add($form->getName(), get_class($this), $options);
$newForm = $parent->get($form->getName());
$newForm->submit($event->getData());
}
}
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'multiple' => true,
'expanded' => true,
'choices' => [],
'required' => false,
'pre_set_called' => false,
'pre_submit_called' => false,
'validation_groups' => false,
]);
}
/**
* @param array $options
* @param $data
* @return mixed
*/
public function getChoices(array $options, $data)
{
if ($data instanceof PersistentCollection) {
return $data->toArray();
}
return $this->entityManager->getRepository($options['class'])->findBy(['id' => $data]);
}
}
Problem solved.
The solution is to recreate the form field with 'choices'=>$selectedChoices in both PRE_SET_DATA and PRE_SUBMIT FormEvents.
Selected choices can be retrived from the event with $event->getData()
Have a look on the bundle I created, it implements this method :
Alsatian/FormBundle - ExtensibleSubscriber