Symfony 2: Попытка расширить поле формы EntityType с помощью jquery select2 - PullRequest
0 голосов
/ 19 апреля 2020

Я пытаюсь создать поле настраиваемого типа, расширяющее EntityType в Symfony 2.

Это новое поле не имеет выбора, пока пользователь не выберет правильный параметр с помощью ajax.

Поле работает нормально до проверки формы, где класс ChoiceToValueTransformer в своем методе reverseTransform просто не может найти любое значение в choicesList.

Это строка кода, выдающая ошибку:

$choices = $this->choiceList->getChoicesForValues(array((string) $value));

$ choices всегда пуст, и сообщение TransformationFailedException: не удалось отменить значение для пути свойства "XXXX": выбор "XX" не существует или не является уникальным.

Я пробовал PRE_SUBMIT FormEvents прикреплен к родительской форме, чтобы заполнить этот выбор, но, похоже, он не работает.

$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
          $form = $event->getForm();
          $child = $form->get('myVarName');
          $data = $child->getData();
          $myOptions = $child->getConfig()->getOptions();
          $name = $child->getName();
          $obj = $event->getData();
          if (empty($obj[$name]))
             return;

          $choices = array($obj[$name] => $obj[$name]);
          if ($data instanceof \Doctrine\ORM\PersistentCollection) {
               $data = $data->toArray();
          }
          if ($data != null) {
               if (is_array($data)) {
                    foreach ($data as $entity) {
                         $choices[$entity] = $entity;
                    }
               } else {
                    $choices[$data] = $data;
               }
          }


          $myOptions['choices'] = [];
          foreach ($choices as $key => $val) {
                $myOptions['choices'][] = $myOptions['em']->getRepository($myOptions['target_object'])->find($val);
          }

          // I've tried setting the option as well with no luck.
          if (count($myOptions['choices']) > 0) {
               $obj[$name] = $myOptions['choices'][array_key_first($tmp)];
               $event->setData($obj);
          }

          $form->add($name, 'entity_ajax_select', $myOptions);
});

Я пробовал PRE_SUBMIT FormEvents, также прикрепленный к моему полю, но не работает, я также оставляю закомментированный пробный код :

$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) {
            $bdData = $this->em->getRepository($options['target_object'])->find($event->getData());
            if ($bdData) {
               // $event->setData($bdData);
                //$event->setData([$bdData->getId() => $bdData]);
                $event->getForm()->getParent()->add($event->getForm()->getName(), 'entity_ajax_select', array('class' => $options['target_object'], 'choices' => $choices, 'data' => $bdData->getId(), 'label' => $options['label'], 'attr' => $options['attr'], 'route' => $options['route']));
               // $event->getForm()->getParent()->add($event->getForm()->getName(), 'entity_ajax_select', array('class' => $options['target_object'], 'choice_value' => function($entity) use ($bdData) {return $bdData;}, 'choices' => [$bdData->getId() => $bdData], 'route' => $options['route']));
            }
        });

Я попытался добавить преобразователь данных модели и просмотреть преобразователь данных также в классе типа поля, когда я добавляю это, то t Форма действительна, но мой объект пуст:

$builder->resetViewTransformers();
$builder->addViewTransformer(new EntityAjaxSelectTransformer($this->em, $options['target_object']), true);
$builder->resetModelTransformers();
$builder->addModelTransformer(new EntityAjaxSelectTransformer($this->em, $options['target_object']), true);

Вот код преобразователя:

<?php

namespace Kimerikal\UtilBundle\Form\DataTransformer;

use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

class EntityAjaxSelectTransformer implements DataTransformerInterface
{
    private $objectManager;
    private $className;

    public function __construct(ObjectManager $objectManager, $className)
    {
        $this->objectManager = $objectManager;
        $this->className = $className;
    }

    public function transform($obj)
    {
        if (empty($obj)) {
            return '';
        }

        return $obj->getId();
    }

    public function reverseTransform($id)
    {
        if (!$id)
            return;

        $obj = $this->objectManager->getRepository($this->className)->find($id);
        if (null === $obj)
            throw new TransformationFailedException(sprintf('An object class: ' . $this->className . ' with id "%s" does not exist!', $id));

        return $obj;
    }
}

Любая идея будет высоко оценена.

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...