Symfony 2 Entity field type with select and/or add new

后端 未结 2 586
孤独总比滥情好
孤独总比滥情好 2021-02-01 09:48

Context:

Let there be two entities (correctly mapped for Doctrine).

  1. Post with properties {$id (integer, autoinc), $name
2条回答
  •  爱一瞬间的悲伤
    2021-02-01 10:37

    I took a slightly different approach using Select2's tag input:

    It has the advantage that it prevents duplicates on the client side and looks pretty.

    To create the newly added entities, I am using a EventSubscriber rather than a DataTransformer.

    For a few more details, see my gist. Below are the TagType and the AddEntityChoiceSubscriber.

    AppBundle/Form/Type/TagType:

    addEventSubscriber($subscriber);
        }
    
        /**
         * {@inheritdoc}
         */
        public function getParent()
        {
            return EntityType::class;
        }
    
        /**
         * {@inheritdoc}
         */
        public function getName()
        {
            return 'tag';
        }
    }
    

    AppBundle/Form/EventListener/AddEntityChoiceSubscriber:

    em = $em;
            $this->entityName = $entityName;
        }
    
        public static function getSubscribedEvents()
        {
            return [
                FormEvents::PRE_SUBMIT => 'preSubmit',
            ];
        }
    
        public function preSubmit(FormEvent $event)
        {
            $data = $event->getData();
    
            if (!is_array($data) && !($data instanceof \Traversable && $data instanceof \ArrayAccess)) {
                $data = [];
            }
    
            // loop through all values
            $repository = $this->em->getRepository($this->entityName);
            $choices = array_map('strval', $repository->findAll());
            $className = $repository->getClassName();
            $newChoices = [];
            foreach($data as $key => $choice) {
                // if it's numeric we consider it the primary key of an existing choice
                if(is_numeric($choice) || in_array($choice, $choices)) {
                    continue;
                }
                $entity = new $className($choice);
                $newChoices[] = $entity;
                $this->em->persist($entity);
            }
            $this->em->flush();
    
            // now we need to replace the text values with their new primary key
            // otherwise, the newly added choice won't be marked as selected
            foreach($newChoices as $newChoice) {
                $key = array_search($newChoice->__toString(), $data);
                $data[$key] = $newChoice->getId();
            }
    
            $event->setData($data);
        }
    }
    

提交回复
热议问题