Partage
  • Partager sur Facebook
  • Partager sur Twitter

Formulaire Symfony

sélectionner une entité ou l'ajouter

Sujet résolu
    28 mai 2017 à 15:16:21

    Bonjour,

    Je suis débutant en Symfony. Dans un formulaire j'ai besoin d'avoir la possibilité de sélectionner une entité ou de la créer si elle n'existe pas. En cherchant sur internet, j'ai trouvé "une solution" dans GitHub 
    [url]https://github.com/LPodolski/selectOrCreateOptionForm[/url]
    Il semble que tout fonctionne bien,sauf lorsque je choisis de créer une nouvelle option, un message d’erreurs me dit : Expected argument of type "AppBundle\Entity\ItemOption", "array" given 

    ça fait deux jours que je galère mais sans issue. Dans l’espoir que quelqu'un puisse m'éclairer sur ce problème, je joints les fichiers suivants. Merci d'avance.
    <?php
    # DefaultController.php
    namespace AppBundle\Controller;
    
    use AppBundle\Entity\Item;
    use AppBundle\Form\ItemType;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\Request;
    
    
    class DefaultController extends Controller
    {
        /**
         * @Route("/", name="homepage")
         */
        public function indexAction(Request $request)
        {
            $item = new Item();
            $form = $this->createForm('AppBundle\Form\ItemType', $item);
            $em   = $this->getDoctrine()->getManager();
    
            if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
                $em->persist($item);
                $em->flush();
            }
    
            return $this->render('default/index.html.twig', array(
                'form' => $form->createView(),
            ));
        }
    }
    <?php
    # Item.php
    namespace AppBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * Item
     *
     * @ORM\Table()
     * @ORM\Entity
     */
    class Item
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @var string
         *
         * @ORM\ManyToOne(targetEntity="AppBundle\Entity\ItemOption", inversedBy="item", cascade={"persist"})
         */
        private $itemOption;
    
    
    
        /**
         * Get id
         *
         * @return integer
         */
        public function getId()
        {
            return $this->id;
        }
    
        /**
         * Set itemOption
         *
         * @param \AppBundle\Entity\ItemOption $itemOption
         * @return Item
         */
        public function setItemOption(\AppBundle\Entity\ItemOption $itemOption = null)
        {
            $this->itemOption = $itemOption;
    
            return $this;
        }
    
        /**
         * Get itemOption
         *
         * @return \AppBundle\Entity\ItemOption
         */
        public function getItemOption()
        {
            return $this->itemOption;
        }
    }
    
    <?php
    # ItemOption.php
    namespace AppBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * ItemOption
     *
     * @ORM\Table()
     * @ORM\Entity
     */
    class ItemOption
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @var string
         *
         * @ORM\Column(name="name", type="string", length=255)
         */
        private $name;
    
        /**
         * @ORM\OneToMany(targetEntity="AppBundle\Entity\Item", mappedBy="itemOption")
         */
        private $item;
    
        /**
         * Constructor
         */
        public function __construct()
        {
            $this->item = new \Doctrine\Common\Collections\ArrayCollection();
        }
    
        /**
         * Get id
         *
         * @return integer 
         */
        public function getId()
        {
            return $this->id;
        }
    
        /**
         * Set name
         *
         * @param string $name
         * @return ItemOption
         */
        public function setName($name)
        {
            $this->name = $name;
    
            return $this;
        }
    
        /**
         * Get name
         *
         * @return string 
         */
        public function getName()
        {
            return $this->name;
        }
    
        /**
         * Add item
         *
         * @param \AppBundle\Entity\Item $item
         * @return ItemOption
         */
        public function addItem(\AppBundle\Entity\Item $item)
        {
            $this->item[] = $item;
    
            return $this;
        }
    
        /**
         * Remove item
         *
         * @param \AppBundle\Entity\Item $item
         */
        public function removeItem(\AppBundle\Entity\Item $item)
        {
            $this->item->removeElement($item);
        }
    
        /**
         * Get item
         *
         * @return \Doctrine\Common\Collections\Collection 
         */
        public function getItem()
        {
            return $this->item;
        }
    }
    
    <?php
    # ItemOptionType.php
    namespace AppBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class ItemOptionType extends AbstractType
    {
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('name')
            ;
        }
    
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'AppBundle\Entity\ItemOption'
            ));
        }
    
        /**
         * @return string
         */
        public function getName()
        {
            return 'appbundle_itemoption';
        }
    }
    
    <?php
    # ItemType.php
    namespace AppBundle\Form;
    
    use AppBundle\Entity\Item;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\Form\FormEvent;
    use Symfony\Component\Form\FormEvents;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    use Symfony\Component\Form\Extension\Core\Type\SubmitType;
    
    class ItemType extends AbstractType
    {
        /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
    
            
    
            $builder
                ->add('itemOption', null, array(
                    'choice_label'    => 'name',
                    'placeholder' => 'create new item Option',
                ))
                ->add('itemOptionNew', 'AppBundle\Form\ItemOptionType', array(
                    'required' => false,
                    'mapped'   => false,
    
                ))
            ;
    
            $builder->add('save', SubmitType::class);
    
            $builder->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
                $data = $event->getData();
                $form = $event->getForm();
    
                if (empty($data['itemOption']) && !empty($data['itemOptionNew']['name'])) {
                    $form->remove('itemOptionNew');
    
                    $form->add('itemOptionNew', 'AppBundle\Form\ItemOptionType', array(
                        'property_path' => 'itemOption',
                    ));
                }
            });
        }
    
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'AppBundle\Entity\Item'
            ));
        }
    
        /**
         * @return string
         */
        public function getName()
        {
            return 'appbundle_item';
        }
    }
    





    • Partager sur Facebook
    • Partager sur Twitter
      28 mai 2017 à 20:41:51

      Bonjour,

      Je n'ai pas tout lu ...

      Dans quelle version de Symfony es tu car certaines syntaxes dans ton code ne sont plus possibles en version 3 ?

      A+

      • Partager sur Facebook
      • Partager sur Twitter
        29 mai 2017 à 0:25:43

        Bonjour,

        Merci pour la question car effectivement j'utilise la version 3 de symfony. Peux-tu m'indiquer ce qui ne va pas avec la version 3 ?

        • Partager sur Facebook
        • Partager sur Twitter
          29 mai 2017 à 7:29:54

          Par exemple le createForm http://symfony.com/doc/current/best_practices/forms.html

          $form = $this->createForm(PostType::class, $post);

          La référence : https://github.com/symfony/symfony/blob/master/UPGRADE-3.0.md

          A+

          • Partager sur Facebook
          • Partager sur Twitter
            29 mai 2017 à 12:34:25

            Merci pour les liens, ils sont intéressants. Après les changements suivants  

            • function setDefaultOptions --> function configureOptions
            • AppBundle\Entity\ItemOption --> ItemOption::class

            Tout est rentré dans l'ordre. Un grand merci monkey3d. Juste par curiosité, quel est le rôle de property_path. Merci encore une fois.

            Pour ceux qui ont rencontré le même problème, je joints les fichiers qui ont été modifiés.

            <?php
            # DefaultController.php
            namespace AppBundle\Controller;
            
            use AppBundle\Entity\Item;
            use AppBundle\Form\ItemType;
            use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
            use Symfony\Bundle\FrameworkBundle\Controller\Controller;
            use Symfony\Component\HttpFoundation\Request;
            
            
            class DefaultController extends Controller
            {
                /**
                 * @Route("/", name="homepage")
                 */
                public function indexAction(Request $request)
                {
                    $item = new Item();
                    $form = $this->createForm(ItemType::class, $item);
                    $em   = $this->getDoctrine()->getManager();
            
                    if ($request->isMethod('POST') && $form->handleRequest($request)) {
            
                        if($form->isValid()){
                            $em->persist($item);
                            $em->flush();
                        }                
                    }
                    return $this->render('default/index.html.twig', array(
                        'form' => $form->createView(),
                    ));
                }
            } 
            <?php
            # ItemType.php
            namespace AppBundle\Form;
            
            use AppBundle\Entity\Item;
            use AppBundle\Form\ItemOptionType;
            use Symfony\Component\Form\AbstractType;
            use Symfony\Bridge\Doctrine\Form\Type\EntityType;
            use Symfony\Component\Form\FormBuilderInterface;
            use Symfony\Component\Form\FormEvent;
            use Symfony\Component\Form\FormEvents;
            use Symfony\Component\OptionsResolver\OptionsResolver;
            use Symfony\Component\Form\Extension\Core\Type\SubmitType;
            
            
            
            class ItemType extends AbstractType
            {
                /**
                 * @param FormBuilderInterface $builder
                 * @param array $options
                 */
                public function buildForm(FormBuilderInterface $builder, array $options)
                {
            
                    
            
                    $builder
                        ->add('itemOption', null, array(
                            'choice_label'    => 'name',
                            'placeholder' => 'create new item Option',
                        ))
                        ->add('itemOptionNew', ItemOptionType::class, array(
                            'required' => false,
                            'mapped'   => false,
                        ));
            
                    $builder->add('save', SubmitType::class);
            
                    $builder->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
                        $data = $event->getData();
                        $form = $event->getForm();
                        if (empty($data['itemOption']) && !empty($data['itemOptionNew']['name'])) {
                            $form->remove('itemOptionNew');
            
                            $form->add('itemOptionNew',  ItemOptionType::class, array(
                                'property_path' => 'itemOption',
                            ));                
                        }
                    });
                }
                
                public function configureOptions(OptionsResolver $resolver)
                {
                    $resolver->setDefaults(array(
                        'data_class' => Item::class,
                    ));
                }
            
                /**
                 * @return string
                 */
                public function getName()
                {
                    return 'appbundle_item';
                }
            }
            <?php
            # ItemOptionType.php
            namespace AppBundle\Form;
            
            use Symfony\Component\Form\AbstractType;
            use Symfony\Component\Form\FormBuilderInterface;
            use Symfony\Component\OptionsResolver\OptionsResolver;
            use AppBundle\Entity\ItemOption;
            
            class ItemOptionType extends AbstractType
            {
                /**
                 * @param FormBuilderInterface $builder
                 * @param array $options
                 */
                public function buildForm(FormBuilderInterface $builder, array $options)
                {
                    $builder
                        ->add('name')
                    ;
                }
               
                public function configureOptions(OptionsResolver $resolver)
                {
                    $resolver->setDefaults(array(
                        'data_class' => ItemOption::class
                    ));
                }
            
                /**
                 * @return string
                 */
                public function getName()
                {
                    return 'appbundle_itemoption';
                }
            }
            





            • Partager sur Facebook
            • Partager sur Twitter
              29 mai 2017 à 13:28:08

              Content t'avoir contribuer à résoudre ton problème. :D

              A ta question la doc indique :

              http://symfony.com/doc/current/reference/forms/types/form.html#property-path

              Passe le sujet en résolu.

              Bye

              -
              Edité par monkey3d 29 mai 2017 à 13:29:22

              • Partager sur Facebook
              • Partager sur Twitter

              Formulaire Symfony

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown