Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Symfony 5] Propriété portée, Ajouter Qte Form

Sujet résolu
    19 février 2021 à 11:10:10

    Bonjour !

    Je suis Etudiant en informatique et pour un projet, je réalise un configurateur qui permettra de mettre en place une configuration d'échelle (Choix du type d'echelle, etc...). J'arrive donc sur la page du choix des accessoires : J'ai dans mes entités

    • Une entité Accessoire
    namespace App\Entity;
    
    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Collection;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * Accessoire
     *
     * @ORM\Table(name="accessoire")
     * @ORM\Entity
     */
    class Accessoire
    {
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer", nullable=false)
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="IDENTITY")
         */
        private $id;
    
        /**
         * @var string
         *
         * @ORM\Column(name="nom_accessoire", type="string", length=50, nullable=false)
         */
        private $nomAccessoire;
    
        /**
         * @var string
         *
         * @ORM\Column(name="ref_accessoire", type="string", length=50, nullable=false)
         */
        private $refAccessoire;
    
        /**
         * @var float
         *
         * @ORM\Column(name="prix_accessoire", type="float", precision=10, scale=0, nullable=false)
         */
        private $prixAccessoire;
    
        /**
         * Constructor
         */
        public function __construct()
        {
            $this->echelle = new \Doctrine\Common\Collections\ArrayCollection();
        }
    
        public function getId(): ?int
        {
            return $this->id;
        }
    
        public function getNomAccessoire(): ?string
        {
            return $this->nomAccessoire;
        }
    
        public function setNomAccessoire(string $nomAccessoire): self
        {
            $this->nomAccessoire = $nomAccessoire;
    
            return $this;
        }
    
        public function getRefAccessoire(): ?string
        {
            return $this->refAccessoire;
        }
    
        public function setRefAccessoire(string $refAccessoire): self
        {
            $this->refAccessoire = $refAccessoire;
    
            return $this;
        }
    
        public function getPrixAccessoire(): ?float
        {
            return $this->prixAccessoire;
        }
    
        public function setPrixAccessoire(float $prixAccessoire): self
        {
            $this->prixAccessoire = $prixAccessoire;
    
            return $this;
        }
    
    }
    • Une entité Echelle :
    namespace App\Entity;
    
    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Collection;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * Echelle
     *
     * @ORM\Table(name="echelle", indexes={@ORM\Index(name="IDX_DA65794D712551BC", columns={"echelle_type_echelle_id"}), @ORM\Index(name="IDX_DA65794D52EAF347", columns={"echelle_hauteur_id"}), @ORM\Index(name="IDX_DA65794D21127304", columns={"echelle_sortie_id"}), @ORM\Index(name="IDX_DA65794DB7242249", columns={"echelle_norme_id"}), @ORM\Index(name="IDX_DA65794DC9BBACD4", columns={"echelle_config_id"}), @ORM\Index(name="IDX_DA65794D421B7347", columns={"echelle_entree_id"})})
     * @ORM\Entity
     */
    class Echelle
    {
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer", nullable=false)
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="IDENTITY")
         */
        private $id;
    
        /**
         * @var \Sortie
         *
         * @ORM\ManyToOne(targetEntity="Sortie")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="echelle_sortie_id", referencedColumnName="id")
         * })
         */
        private $echelleSortie;
    
        /**
         * @var \Entree
         *
         * @ORM\ManyToOne(targetEntity="Entree")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="echelle_entree_id", referencedColumnName="id")
         * })
         */
        private $echelleEntree;
    
        /**
         * @var \Hauteur
         *
         * @ORM\ManyToOne(targetEntity="Hauteur")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="echelle_hauteur_id", referencedColumnName="id")
         * })
         */
        private $echelleHauteur;
    
        /**
         * @var \TypeEchelle
         *
         * @ORM\ManyToOne(targetEntity="TypeEchelle")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="echelle_type_echelle_id", referencedColumnName="id")
         * })
         */
        private $echelleTypeEchelle;
    
        /**
         * @var \Norme
         *
         * @ORM\ManyToOne(targetEntity="Norme")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="echelle_norme_id", referencedColumnName="id")
         * })
         */
        private $echelleNorme;
    
        /**
         * @var \Config
         *
         * @ORM\ManyToOne(targetEntity="Config")
         * @ORM\JoinColumns({
         *   @ORM\JoinColumn(name="echelle_config_id", referencedColumnName="id")
         * })
         */
        private $echelleConfig;
    
        /**
         * @var \Doctrine\Common\Collections\Collection
         *
         * @ORM\ManyToMany(targetEntity="ChangementVolee", inversedBy="echelle")
         * @ORM\JoinTable(name="echelle_changement_volee",
         *   joinColumns={
         *     @ORM\JoinColumn(name="echelle_id", referencedColumnName="id")
         *   },
         *   inverseJoinColumns={
         *     @ORM\JoinColumn(name="changement_volee_id", referencedColumnName="id")
         *   }
         * )
         */
        private $changementVolee;
    
        /**
         * @var \Doctrine\Common\Collections\Collection
         *
         * @ORM\ManyToMany(targetEntity="Fixation", inversedBy="echelle")
         * @ORM\JoinTable(name="echelle_fixation",
         *   joinColumns={
         *     @ORM\JoinColumn(name="echelle_id", referencedColumnName="id")
         *   },
         *   inverseJoinColumns={
         *     @ORM\JoinColumn(name="fixation_id", referencedColumnName="id")
         *   }
         * )
         */
        private $fixation;
    
        /**
         * @var \Doctrine\Common\Collections\Collection
         *
         * @ORM\ManyToMany(targetEntity="Palier", inversedBy="echelle")
         * @ORM\JoinTable(name="echelle_palier",
         *   joinColumns={
         *     @ORM\JoinColumn(name="echelle_id", referencedColumnName="id")
         *   },
         *   inverseJoinColumns={
         *     @ORM\JoinColumn(name="palier_id", referencedColumnName="id")
         *   }
         * )
         */
        private $palier;
    
        /**
         * Constructor
         */
        public function __construct()
        {
            $this->accessoire = new \Doctrine\Common\Collections\ArrayCollection();
            $this->changementVolee = new \Doctrine\Common\Collections\ArrayCollection();
            $this->fixation = new \Doctrine\Common\Collections\ArrayCollection();
            $this->palier = new \Doctrine\Common\Collections\ArrayCollection();
        }
    
        public function getId(): ?int
        {
            return $this->id;
        }
    
        public function getEchelleSortie(): ?Sortie
        {
            return $this->echelleSortie;
        }
    
        public function setEchelleSortie(?Sortie $echelleSortie): self
        {
            $this->echelleSortie = $echelleSortie;
    
            return $this;
        }
    
        public function getEchelleEntree(): ?Entree
        {
            return $this->echelleEntree;
        }
    
        public function setEchelleEntree(?Entree $echelleEntree): self
        {
            $this->echelleEntree = $echelleEntree;
    
            return $this;
        }
    
        public function getEchelleHauteur(): ?Hauteur
        {
            return $this->echelleHauteur;
        }
    
        public function setEchelleHauteur(?Hauteur $echelleHauteur): self
        {
            $this->echelleHauteur = $echelleHauteur;
    
            return $this;
        }
    
        public function getEchelleTypeEchelle(): ?TypeEchelle
        {
            return $this->echelleTypeEchelle;
        }
    
        public function setEchelleTypeEchelle(?TypeEchelle $echelleTypeEchelle): self
        {
            $this->echelleTypeEchelle = $echelleTypeEchelle;
    
            return $this;
        }
    
        public function getEchelleNorme(): ?Norme
        {
            return $this->echelleNorme;
        }
    
        public function setEchelleNorme(?Norme $echelleNorme): self
        {
            $this->echelleNorme = $echelleNorme;
    
            return $this;
        }
    
        public function getEchelleConfig(): ?Config
        {
            return $this->echelleConfig;
        }
    
        public function setEchelleConfig(?Config $echelleConfig): self
        {
            $this->echelleConfig = $echelleConfig;
    
            return $this;
        }
    
        /**
         * @return Collection|ChangementVolee[]
         */
        public function getChangementVolee(): Collection
        {
            return $this->changementVolee;
        }
    
        public function addChangementVolee(ChangementVolee $changementVolee): self
        {
            if (!$this->changementVolee->contains($changementVolee)) {
                $this->changementVolee[] = $changementVolee;
            }
    
            return $this;
        }
    
        public function removeChangementVolee(ChangementVolee $changementVolee): self
        {
            $this->changementVolee->removeElement($changementVolee);
    
            return $this;
        }
    
        /**
         * @return Collection|Fixation[]
         */
        public function getFixation(): Collection
        {
            return $this->fixation;
        }
    
        public function addFixation(Fixation $fixation): self
        {
            if (!$this->fixation->contains($fixation)) {
                $this->fixation[] = $fixation;
            }
    
            return $this;
        }
    
        public function removeFixation(Fixation $fixation): self
        {
            $this->fixation->removeElement($fixation);
    
            return $this;
        }
    
        /**
         * @return Collection|Palier[]
         */
        public function getPalier(): Collection
        {
            return $this->palier;
        }
    
        public function addPalier(Palier $palier): self
        {
            if (!$this->palier->contains($palier)) {
                $this->palier[] = $palier;
            }
    
            return $this;
        }
    
        public function removePalier(Palier $palier): self
        {
            $this->palier->removeElement($palier);
    
            return $this;
        }
    
    }
    • Et une 3ème entité qui permet de faire le lien entre les deux précédente et d'avoir un champ Qte pour que l'utilisateur choisisse combien d'accessoire de chaque il prend, EchelleAccessoire :
    namespace App\Entity;
    
    use App\Repository\EchelleAccessoireRepository;
    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity(repositoryClass=EchelleAccessoireRepository::class)
     */
    class EchelleAccessoire
    {
        /**
         * @ORM\Id
         * @ORM\GeneratedValue
         * @ORM\Column(type="integer")
         */
        private $id;
    
        /**
         * @ORM\ManyToOne(targetEntity=Echelle::class)
         * @ORM\JoinColumn(nullable=false)
         */
        private $Echelle;
    
        /**
         * @ORM\ManyToOne(targetEntity=Accessoire::class)
         * @ORM\JoinColumn(nullable=false)
         */
        private $Accessoire;
    
        /**
         * @ORM\Column(type="integer")
         * @ORM\Column(nullable=true)
         */
        private $Qte;
    
        public function getId(): ?int
        {
            return $this->id;
        }
    
        public function getEchelle(): ?Echelle
        {
            return $this->Echelle;
        }
    
        public function setEchelle(?Echelle $Echelle): self
        {
            $this->Echelle = $Echelle;
    
            return $this;
        }
    
        public function getAccessoire(): ?Accessoire
        {
            return $this->Accessoire;
        }
    
        public function setAccessoire(?Accessoire $Accessoire): self
        {
            $this->Accessoire = $Accessoire;
    
            return $this;
        }
    
        public function getQte(): ?int
        {
            return $this->Qte;
        }
    
        public function setQte(int $Qte): self
        {
            $this->Qte = $Qte;
    
            return $this;
        }
    }

    J'ai fais un formulaire pour la page de choix des Accessoires en utilisant un EntityType avec l'option multiple pour que l'utilisateur puisse choisir celui qu'il désire ou non :

    namespace App\Form;
    
    use App\Entity\Echelle;
    use App\Entity\Accessoire;
    use Symfony\Bridge\Doctrine\Form\Type\EntityType;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\Extension\Core\Type\CollectionType;
    use Symfony\Component\Form\Extension\Core\Type\NumberType;
    use Symfony\Component\Form\Extension\Core\Type\TextType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    
    class AccessoireType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
            ->add('id', EntityType::class, [
                'class' => Accessoire::class,
                'choice_value' => 'id',
                'choice_label' => 'nomAccessoire',
                'multiple' => 'true',
                'expanded' => 'true'
            ])
            ->add('Qte');
            
        }
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults([
    
            ]);
        }
    }


    Enfin, j'ai fait mon formulaire pour l'affichage :

    {% extends 'base.html.twig' %}
    
    {% block title %}Choisir des accessoires{% endblock %}
    
    {% block body %}
    
    
    <div class="container">
        
            <div class="w-75 mx-auto">
            <div><h1>Choix des Accessoires</h1></div>
        {{ form_start(AccessoireAjoutForm) }}
        {% for Accessoire in AccessoireAjoutForm.id %}
          {{ form_row(Accessoire) }}
          {{ form_row(AccessoireAjoutForm.Qte) }}
        {% endfor %}
        
            <a styke="color:black" class="text-dark btn bg-warning" href="{{ path('index') }}">Precedent</a>
            <button type="submit" class="btn bg-warning">Suivant</button>
        {{ form_end(AccessoireAjoutForm) }}
        
            </div>
        </div>
    
    {% endblock %}


    Ici, j'ai voulu, dans le for, afficher chaque accessoire présents dans ma base de données et ajouter juste à coté donc, ce fameux champs pour choisir combien d'accessoire on veut avant de submit le formulaire. Cette solution de mettre le champs Qte dans le for du formulaire ne fonctionne pas puisque Symfony me dit qu'il a déjà été "rendu". Si le champs Qte n'est pas renseigné, l'affichage des choix d'Accessoire sans ce champs dans tous les cas fonctionne, l'utilisateur peut sélectionner ce qu'il veut pour insérer. Je vous laisse d'ailleurs la partie du controller qui correspond :

    /* Choix des accessoires d'une echelle dans la liste d'accessoires*/
        public function AjoutAccessoire(Request $request, int $id): Response
        {
            $repository = $this->getDoctrine()->getRepository(Echelle::class);
            $Echelle = $repository->find($id);
            $form = $this->createForm(AccessoireType::class);
            $form->handleRequest($request);
    
            if ($form->isSubmitted() && $form->isValid())
            {
                /*Recuperation des données du formulaire*/
                $Accessoire = $form->getData();
                $Accessoires = $Accessoire['id'];
                $tableau = count($Accessoires ,$mode = COUNT_NORMAL );
                
                /* Pour i allant de 0 jusqu'à le nombre de valeur sélectionnées, on ajoute chaque valeur une à une dans la relation entre Accessoire et Echelle*/
                for ($i = 0; $i < $tableau; $i++)
                {
                    $EchelleAccessoire = new EchelleAccessoire();
                    $EchelleAccessoire->setAccessoire($Accessoires[$i]);
                    $EchelleAccessoire->setEchelle($Echelle);
    
                    $entityManager = $this->getDoctrine()->getManager();
                    $entityManager->persist($EchelleAccessoire);
                    $entityManager->flush();
                }
    
                return $this->redirectToRoute('ajoutChangementVolee', array('id'=> $id));
            }
    
    
    
    
    
    
            return $this->render('AccessoireAjout.html.twig',['AccessoireAjoutForm' => $form->createView()]);
    
        }

    Mon problème est donc, après plusieurs recherches sur le web, de trouver une solution pour ajouter un field Qte pour chaque Accessoires générés par le for, mon but étant de récupérer bien sur la valeur dans le isSubmitted. Concernant mes recherches, j'ai trouvé l'idée des formulaires imbriqués qui n'a pas donné grand chose. Ensuite j'ai essayé de voir si des options dans EntityType ne pouvaient pas faire ça pour moi. J'ai même rajouté un input simple dans le for mais je ne sait pas comment récupérer toutes les valeurs pour chaque accessoire (différent du $form->getData() si j'ai bien compris ?). Voila plusieurs jours que je suis bloqué sur ce problème alors je viens faire appel à vous qui pouvez sans doute éclairer ma lanterne.

    Bonne journée !

    • Partager sur Facebook
    • Partager sur Twitter
      20 février 2021 à 17:14:11

      Hello !

      Alors si j'ai bien compris ce que tu veux faire, je pense que tu t'y prends mal si tu souhaites rester Symfony Friendly.

      Il faut, que tu faudrais que tu es une collection de FormType où le champ Accessoire ne serait sélectionnable qu'une fois (à contrario du multiple que tu as mis).  Regarde ici: https://symfony.com/doc/current/form/form_collections.html

      • Partager sur Facebook
      • Partager sur Twitter
      $2b||!$2b
        1 mars 2021 à 8:56:58

        Bonjour à toi ! Merci de ta réponse je regarde ça aujourd'hui ! Je ferais une réponse pour montrer mon avancement dans la journée !

        PS : En priant d'excuser mon retard, étant en alternance je n'ai pas eu le temps de me pencher sur la question (semaine de cours)

        • Partager sur Facebook
        • Partager sur Twitter
          1 mars 2021 à 9:13:48

          Mais pas de problème t'inquiète :)
          • Partager sur Facebook
          • Partager sur Twitter
          $2b||!$2b
            1 mars 2021 à 16:21:11

            Me revoici donc ! Alors ton idée semble fonctionner en effet. Cependant lorsque j'arrive sur la page, rien ne s'affiche :

            Mon twig :

            % extends 'base.html.twig' %}
            
            {% block title %}Choisir des accessoires{% endblock %}
            
            {% block body %}
            
            
            <div class="container">
                
                    <div class="w-75 mx-auto">
                    <div><h1>Choix des Accessoires</h1></div>
                {{ form_start(AccessoireAjoutForm) }}
                {{ form_row(AccessoireAjoutForm.champs) }}
                {% for Accessoire in AccessoireAjoutForm.FormAccessoire %}
                  {{ form_row(Accessoire.id) }}
                  {{ form_row(Accessoire.Qte) }}
                {% endfor %}
                
                    <a styke="color:black" class="text-dark btn bg-warning" href="{{ path('index') }}">Precedent</a>
                    <button type="submit" class="btn bg-warning">Suivant</button>
                {{ form_end(AccessoireAjoutForm) }}
                
                    </div>
                </div>
            
            {% endblock %}


            Mon Formulaire qui contient ma collection de formulaire d'accessoire :

            <?php
            
            namespace App\Form;
            
            use App\Form\AccessoireType;
            use Symfony\Component\Form\AbstractType;
            use Symfony\Component\Form\Extension\Core\Type\CollectionType;
            use Symfony\Component\Form\FormBuilderInterface;
            use Symfony\Component\OptionsResolver\OptionsResolver;
            
            class AccessoireType2Type extends AbstractType
            {
                public function buildForm(FormBuilderInterface $builder, array $options)
                {
                    $builder
                    ->add('champs')
                    ->add('FormAccessoire', CollectionType::class, [
                    'entry_type' => AccessoireType::class,
                    'entry_options' => ['label' => false],
                    'allow_add' => true,
                    ]);
            
                    ;
                }
            
                public function configureOptions(OptionsResolver $resolver)
                {
                    $resolver->setDefaults([
                        // Configure your form options here
                    ]);
                }
            }
            


            et mon formulaire d'accessoire :

            <?php
            
            namespace App\Form;
            
            use App\Entity\Echelle;
            use App\Entity\Accessoire;
            use Symfony\Bridge\Doctrine\Form\Type\EntityType;
            use Symfony\Component\Form\AbstractType;
            use Symfony\Component\Form\Extension\Core\Type\CollectionType;
            use Symfony\Component\Form\Extension\Core\Type\NumberType;
            use Symfony\Component\Form\Extension\Core\Type\TextType;
            use Symfony\Component\Form\FormBuilderInterface;
            use Symfony\Component\OptionsResolver\OptionsResolver;
            
            class AccessoireType extends AbstractType
            {
                public function buildForm(FormBuilderInterface $builder, array $options)
                {
                    $builder
                    ->add('id', EntityType::class, [
                        'class' => Accessoire::class,
                        'choice_value' => 'id',
                        'choice_label' => 'nomAccessoire',
                        'multiple' => 'true',
                        'expanded' => 'true'
                    ])
                    ->add('Qte', NumberType::class);
                    
                }
            
                public function configureOptions(OptionsResolver $resolver)
                {
                    $resolver->setDefaults([
            
                    ]);
                }
            }
            

            Je sais que le fait que cela n'affiche rien vient du fait que je dis dans le twig : Pour chaque formulaire dans LesFormulaires, J'affiche Fomulaire.id et Formulaire.Qte

            Faudrait-il que je fasse un for pour qu'il sache que c'est selon le nombre d'accessoire dans la base de données ? Faut-il que je passe mon entity Accessoire dans l'un des formulaire ?

            Pour être plus precis, je souhaite ici eviter de faire un choix d'accessoire pour chaque ligne comme ça :

            Accessoire 1 -> Quantité ?

            Accessoire 2 -> Quantité ?

            Accessoire 3 -> Quantité ?

            Bouton Submit -> Si quantité = 0 -> on associe pas d'accessoire à l'echelle.


            Enfin, dans le formulaire qui contient la collection de form, j'ai mis un champs appellé "champs pour voir si le problème vient bien de ma collection de form donc pas besoin de s'en préocupé.

            Je laisse un screenshot de ce que ça me rend à la fin.

            -
            Edité par TheoGouchet 1 mars 2021 à 16:22:11

            • Partager sur Facebook
            • Partager sur Twitter
              1 mars 2021 à 20:48:10

              Alors deux choses:

              • La première est que dans une collection form, tu dois avoir en front un bouton qui te permet d'ajouter ou de supprimer une ligne (un sous formulaire) en JS. Tout est fournis dans le lien que je t'ai donnée.
              • La deuxième est que dans ton contrôleur, tu dois "hydrater" ton objet avec les valeurs de ta BDD avant de passer ton objet à ton create form. Ce qui a pour effet de préremplir ton formulaire avec les "sous form" déjà pré rempli avec les données que tu as en BDD.

              Pourrais tu nous montrer ton contrôleur stp ?

              • Partager sur Facebook
              • Partager sur Twitter
              $2b||!$2b
                2 mars 2021 à 10:54:04

                Salut ! Voici mon contrôleur ! Ne te préoccupe pas du submit, je cherche uniquement à faire l'affichage pour le moment :

                    public function AjoutAccessoire(Request $request, int $id): Response
                    {
                        $repository = $this->getDoctrine()->getRepository(Echelle::class);
                        $Echelle = $repository->find($id);
                        $form = $this->createForm(AccessoireType2Type::class);
                        $form->handleRequest($request);
                
                        if ($form->isSubmitted() && $form->isValid())
                        {
                            /*Recuperation des données du formulaire*/
                            /*$Accessoire = $form->getData();
                            $Accessoires = $Accessoire['id'];
                            $tableau = count($Accessoires ,$mode = COUNT_NORMAL );*/
                            
                            /* Pour i allant de 0 jusqu'à le nombre de valeur sélectionnées, on ajoute chaque valeur une à une dans la relation entre Accessoire et Echelle
                            for ($i = 0; $i < $tableau; $i++)
                            {
                                $EchelleAccessoire = new EchelleAccessoire();
                                $EchelleAccessoire->setAccessoire($Accessoires[$i]);
                                $EchelleAccessoire->setEchelle($Echelle);
                
                                $entityManager = $this->getDoctrine()->getManager();
                                $entityManager->persist($EchelleAccessoire);
                                $entityManager->flush();*/
                            }
                
                            /*return $this->redirectToRoute('ajoutChangementVolee', array('id'=> $id));*/
                        }
                        return $this->render('AccessoireAjout.html.twig',['AccessoireAjoutForm' => $form->createView()]);
                
                    }

                Pour ce qui est du bouton, je vais m'en occuper de suite ! Et je n'ai pas saisi ta première indications : Faut-il faire un get sur tous les objets dans la BDD et ensuite les passer en parametre lors du createForm ?

                Merci à toi !

                Edit :

                L'affichage du bouton avec le Jqery lui même ne fonctionne pas :

                {% extends 'base.html.twig' %}
                
                
                {% block title %}Choisir des accessoires{% endblock %}
                
                {% block body %}
                
                {% block javascripts %}
                <script>
                jQuery(document).ready(function() {
                    // Get the ul that holds the collection of tags
                    var $tagsCollectionHolder = $('ul.tags');
                    // count the current form inputs we have (e.g. 2), use that as the new
                    // index when inserting a new item (e.g. 2)
                    $tagsCollectionHolder.data('index', $tagsCollectionHolder.find('input').length);
                
                    $('body').on('click', '.add_item_link', function(e) {
                        var $collectionHolderClass = $(e.currentTarget).data('collectionHolderClass');
                        // add a new tag form (see next code block)
                        addFormToCollection($collectionHolderClass);
                    })
                });
                </script>
                {% endblock %}
                
                
                <div class="container">
                        <div class="w-75 mx-auto">
                        <div><h1>Choix des Accessoires</h1></div>
                    {{ form_start(AccessoireAjoutForm) }}
                    <ul class="tags">
                    {% for Accessoire in AccessoireAjoutForm.Accessoire %}
                      {{ form_row(Accessoire.id) }}
                
                      {{ form_row(Accessoire.Qte) }}
                    {% endfor %}
                    </ul>
                    
                        <a styke="color:black" class="text-dark btn bg-warning" href="{{ path('index') }}">Precedent</a>
                        <button type="submit" class="btn bg-warning">Suivant</button>
                    {{ form_end(AccessoireAjoutForm) }}
                
                    
                    
                        </div>
                    </div>
                
                {% endblock %}




                -
                Edité par TheoGouchet 2 mars 2021 à 16:37:33

                • Partager sur Facebook
                • Partager sur Twitter
                  2 mars 2021 à 20:45:22

                  Re !

                  Alors je ne suis pas certains de comprendre la qu'est ce que tu veux créer et pour quelle entité.

                  Tu veux ajouter des accessoires à ton entité Echelle ?

                  Et pour la partie jQuery, tu me dis pas ce qui ne marche pas: Il ne s'affiche pas ? Il ne fait rien quand tu clic dessus ? etc

                  Normalement, un formulaire est en général bind à une entité.

                  Donc si je te fais une exemple ci-dessous, voilà ce que cela donnerai côté PHP pour une Page contenant plusieurs Articles (bien sûr je le fais de tête sans tester):

                  Entités Article :

                  <?php
                  
                  namespace App\Entity;
                  
                  use App\Entity\Page;
                  use Doctrine\ORM\Mapping as ORM;
                  
                  /*
                   * @ORM\Entity
                   */
                  class Article
                  {
                      /**
                       * @ORM\Id
                       * @ORM\GeneratedValue
                       * @ORM\Column(type="integer")
                       */
                      protected $id;
                  
                      /**
                       * @ORM\column(type="string")
                       */
                      protected $title;
                  
                      /**
                       * @ORM\column(type="text")
                       */
                      protected $content;
                  
                      /**
                       * @ORM\ManyToOne(targetEntity="App\Entity\Page", inversedBy="articles")
                       */
                      protected $page;
                  
                      public function getId()
                      {
                          return $this->id;
                      }
                  
                      public function getTitle(): string
                      {
                          return $this->title;
                      }
                  
                      public function setTitle(string $title): self
                      {
                          $this->title = $title;
                          return $this;
                      }
                  
                      public function getContent(): string
                      {
                          return $this->content;
                      }
                  
                      public function setContent(string $content): self
                      {
                          $this->content = $content;
                          return $this;
                      }
                  
                      public function getPage(): Page
                      {
                          return $this->page;
                      }
                  
                      public function setPage(string $page): self
                      {
                          $this->page = $page;
                          return $this;
                      }
                  }

                  Entités Page :

                  <?php
                  
                  namespace App\Entity;
                  
                  use App\Entity\Article;
                  use Doctrine\Common\Collections\ArrayCollection;
                  use Doctrine\Common\Collections\Collection;
                  use Doctrine\ORM\Mapping as ORM;
                  
                  /*
                   * @ORM\Entity
                   */
                  class Page
                  {
                      /**
                       * @ORM\Id
                       * @ORM\GeneratedValue
                       * @ORM\Column(type="integer")
                       */
                      protected $id;
                  
                      /**
                       * @ORM\column(type="string")
                       */
                      protected $title;
                  
                      /**
                       * @ORM\ManyToOne(targetEntity="App\Entity\Article", inversedBy="page", cascade={"persist", "remove"})
                       */
                      protected $articles;
                  
                      public function __construct()
                      {
                          $this->articles = new ArrayCollection();
                      }
                  
                      public function getId()
                      {
                          return $this->id;
                      }
                  
                      public function getTitle(): string
                      {
                          return $this->title;
                      }
                  
                      public function setTitle(string $title): self
                      {
                          $this->title = $title;
                          return $this;
                      }
                  
                      public function getArticles(): Collection
                      {
                          return $this->articles;
                      }
                  
                      public function setArticles(Collection $articles): self
                      {
                          $this->articles = $articles;
                          return $this;
                      }
                  
                      public function addArticle(Article $article): self
                      {
                          if (!$this->articles->contains($article)) {
                              $this->article->add($article);
                              $article->setPage($this);
                          }
                  
                          return $this;
                      }
                  
                      public function removeArticle(Article $article): self
                      {
                          $this->articles->remove($article);
                  
                          return $this;
                      }
                  }

                  Formulaire Article :

                  <?php
                  
                  namespace App\Form;
                  
                  use App\Entity\Article;
                  use Symfony\Component\Form\AbstractType;
                  use Symfony\Component\Form\Extension\Core\Type\CollectionType;
                  use Symfony\Component\Form\FormBuilderInterface;
                  use Symfony\Component\OptionsResolver\OptionsResolver;
                  
                  class ArticleFormType extends AbstractType
                  {
                      public function buildForm(FormBuilderInterface $builder, array $options): void
                      {
                          // Les champs ajouter doivent correspondre aux noms des attributs de l'entité Article
                          // que je souhaite modifier/ajouter
                          $builder
                              ->add('title')
                              ->add('content');
                      }
                  
                      public function configureOptions(OptionsResolver $resolver): void
                      {
                          $resolver->setDefaults([
                              'data_class' => Article::class, // Ici j'indique que ce formulaire est lié à l'entité Article
                          ]);
                      }
                  }

                  Formulaire Page :

                  <?php
                  
                  namespace App\Form;
                  
                  use App\Entity\Page;
                  use App\Entity\Article;
                  use App\Form\ArticleType;
                  use Symfony\Component\Form\AbstractType;
                  use Symfony\Component\Form\Extension\Core\Type\CollectionType;
                  use Symfony\Component\Form\FormBuilderInterface;
                  use Symfony\Component\OptionsResolver\OptionsResolver;
                  
                  class UpdatePageArticlesFormType extends AbstractType
                  {
                      public function buildForm(FormBuilderInterface $builder, array $options): void
                      {
                          // Le champs ajouté doit correspondre au nom de l'attribut qui contient les Articles
                          // dans l'entité Page
                          $builder->add('articles', CollectionType::class, [
                              'entry_type' => ArticleType::class, // Ici le FormType d'un Article définie au dessus
                              'entry_options' => ['label' => false],
                          ]);
                      }
                  
                      public function configureOptions(OptionsResolver $resolver): void
                      {
                          $resolver->setDefaults([
                              'data_class' => Page::class, // Ici j'indique que ce formulaire est lié à l'entité Page
                          ]);
                      }
                  }

                  Contrôleur :

                  namespace App\Controller;
                  
                  use App\Entity\Page;
                  use App\Entity\Article;
                  use App\Form\UpdatePageArticlesFormType;
                  use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
                  use Symfony\Component\HttpFoundation\Request;
                  use Symfony\Component\HttpFoundation\Response;
                  
                  class TaskController extends AbstractController
                  {
                      public function new(Request $request): Response
                      {
                          $page = $this->getDoctrine()->getRepository(Page::class)->find(1); // Je récupère l'entité mère que je vais MAJ
                          $form = $this->createForm(UpdatePageArticlesFormType::class, $page); // Je passe mon entité à mon form
                          $form->handleRequest($request);
                  
                          if ($form->isSubmit()) {
                              if ($form->isValid()) {
                                  $this->getDoctrine()->flush();
                              }
                              $this->addFlash('error', $form->getErrors());
                          }
                  
                          return $this->render('page/update_articles.html.twig', [
                              'form' => $form->createView(),
                          ]);
                      }
                  }



                  • Partager sur Facebook
                  • Partager sur Twitter
                  $2b||!$2b
                    3 mars 2021 à 9:09:36

                    Re bonjour ! Alors enfaite j'ai 3 entités : Une entité qui contient des accessoires, une entité qui contient des echelles et une troisième entité (EchelleAccessoire) dans laquelle je met l'id d'une echelle et l'id d'un accessoire avec un champs quantité pour connaitre le nombre de fois que j'associe un tel accessoire à une echelle, et ce pour tous les accessoire et une même echelle. D'où le fait que je souhaite afficher autant de fois le champ accessoire et quantité pour pouvoir eventuellement associé tous les accessoires à une même echelle

                    J'ai fais un petit mcd de cette partie pour mieux te montrer :

                    Mon formulaire doit être lié à l'entité EchelleAccessoire : Pour une echelle dont j'ai deja l'id, je dois choisir un accessoire et la quantité de cet accessoire pour l'echelle et je dois pouvoir le faire pour chaque accessoire présents dans l'entité Accessoire. Donc pour moi, le formulaire à afficher est lié à l'entité EchelleAccessoire, seulement de ce que j'ai compris, je dois hydrater ce fameux formulaire avec TOUS les accessoires dans ma BDD c'est bien ça ?

                    Pour le bouton en JQuery, il ne s'affiche pas en effet. J'ai bien tester un Alert() pour voir si le javasscript fonctionne dans un premier temps, puis la fonction 

                    jQuery(document).ready(function($) {
                    	alert("js is working");

                    Et tout est fonctionnel.

                    N'hésite pas à me poser d'autre questions si c'est encore flou pour toi, en te remerciant car pour le coup, tu es la seule aide à ma dispostion même après plusieurs heures de surf pour tenter de trouver une solution

                    EDIT : 

                    J'ai reussi à afficher sans utiliser une CollectionType pour le moment, en utilisant seulement un formaulaire :

                    Maintenant il faut que je realise ta methode en faisant un deuxième formulaire avec un champ CollectionType de ce formulaire avec le bouton en JQuery. Je dois aussi trouver le moyen qu'il me montre uniquement manivelle puis levier etc pour avec un champs quantité pour chaque accessoire

                    -
                    Edité par TheoGouchet 3 mars 2021 à 9:31:37

                    • Partager sur Facebook
                    • Partager sur Twitter
                      3 mars 2021 à 9:44:55

                      Ok je vois. Dans ce cas, l'élément que tu souhaites modifier c'est l'Echelle et pas EchelleAccessoire. Du coup dans ton contrôleur, tu dois récupérer ton Echelle avec son ID et le passer à la création du formulaire.

                      Laisse mon la matinée et je te ferais une exemple avec le modèle de données que tu m'as donné.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      $2b||!$2b
                        3 mars 2021 à 11:21:56

                        Ce n'est pas une insertion dans l'entité EchelleAccessoire qu'il faut faire ? Pour l'id de l'echelle je l'ai déja, il est passé dans la fonction AjoutAccessoire de mon controleur

                        -
                        Edité par TheoGouchet 3 mars 2021 à 11:23:07

                        • Partager sur Facebook
                        • Partager sur Twitter
                          4 mars 2021 à 14:11:16

                          Hello, désolé pour le retard, cela m'a pris plus de temps que prévu à cause de mon taf.

                          Je t'ai créer un exemple testable à récupérer sur mon repo à cette adresse.

                          N'hésite pas si tu as besoin d'explication.

                          • Partager sur Facebook
                          • Partager sur Twitter
                          $2b||!$2b
                            4 mars 2021 à 14:31:50

                            Salut ! Pas de soucis, on a tous des obligations à coté. C'est incroyable de voir à quel point je n'y serais pas arrivé seul. Je suis en train de regarder et d'essayer de voir la où je me suis trompé. Je te fais un compte rendu tout à l'heure.

                            EDIT : 

                            Pour être honnête j'ai compris l'imbrication de form, si ce n'est, le fait de mettre Echelle en data_class pour le formulaire qui contient la collection. J'ai vu que il y avait également des attributs EchelleAccessoire dans l'entité echelle et accessoire, chose que je n'avais pas avant, je les ai donc rajouté à la main mais seulement je reviens au point de départ. Aucun des boutons ne me permet de faire quoi que ce soit et rien ne s'affiche sur mon twig :

                            Je vais te remettre chaque screen pour que tu vois ce que j'ai fais :

                            Mon twig :

                            {% extends 'base.html.twig' %}
                            
                            
                            {% block title %}Choisir des accessoires{% endblock %}
                            
                            {% block body %}
                            
                            {% block javascripts %}
                            <script>
                            jQuery(document).ready(function() {
                                // Get the ul that holds the collection of tags
                                var $tagsCollectionHolder = $('ul.tags');
                                // count the current form inputs we have (e.g. 2), use that as the new
                                // index when inserting a new item (e.g. 2)
                                $tagsCollectionHolder.data('index', $tagsCollectionHolder.find('input').length);
                            
                                $('body').on('click', '.add_item_link', function(e) {
                                    var $collectionHolderClass = $(e.currentTarget).data('collectionHolderClass');
                                    // add a new tag form (see next code block)
                                    addFormToCollection($collectionHolderClass);
                                })
                            });
                            </script>
                            {% endblock %}
                            
                            
                            <div class="container">
                                    <div class="w-75 mx-auto">
                                    <div><h1>Choix des Accessoires</h1></div>
                                {{ form_start(Form) }}
                                <table>
                                        <tr>
                                            <td>
                                                <ul class="accessories" data-prototype="{{ form_widget(Form.EchelleAccessoire.vars.prototype)|e('html_attr') }}">
                                                    {% for accessory in Form.EchelleAccessoire %}
                                                        <li>
                                                            <table>
                                                                <tr>
                                                                    <td>{{ form_label(accessory.Accessoire) }}</td>
                                                                    <td>{{ form_widget(accessory.Accessoire) }}</td>
                                                                    <td>{{ form_errors(accessory.Accessoire) }}</td>
                                                                <tr>
                                                                <tr>
                                                                    <td>{{ form_label(accessory.Qte) }}</td>
                                                                    <td>{{ form_widget(accessory.Qte) }}</td>
                                                                    <td>{{ form_errors(accessory.Qte) }}</td>
                                                                <tr>
                                                            </table>
                                                        </li>
                                                    {% endfor %}
                                                </ul>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td><button type="submit">Créer</button></td>
                                            <td><button type="button" class="add_item_link" data-collection-holder-class="accessories">Ajouter Accessoire</button></td>
                                        </tr>
                                    </table>
                                {{ form_end(Form) }}
                            
                                
                                
                                    </div>
                                </div>
                            
                            {% endblock %}


                            Mon entité Accessoire :

                            <?php
                            
                            namespace App\Entity;
                            
                            use Doctrine\Common\Collections\ArrayCollection;
                            use Doctrine\Common\Collections\Collection;
                            use Doctrine\ORM\Mapping as ORM;
                            
                            /**
                             * Accessoire
                             *
                             * @ORM\Table(name="accessoire")
                             * @ORM\Entity
                             */
                            class Accessoire
                            {
                                /**
                                 * @var int
                                 *
                                 * @ORM\Column(name="id", type="integer", nullable=false)
                                 * @ORM\Id
                                 * @ORM\GeneratedValue(strategy="IDENTITY")
                                 */
                                private $id;
                            
                                /**
                                 * @var string
                                 *
                                 * @ORM\Column(name="nom_accessoire", type="string", length=50, nullable=false)
                                 */
                                private $nomAccessoire;
                            
                                /**
                                 * @var string
                                 *
                                 * @ORM\Column(name="ref_accessoire", type="string", length=50, nullable=false)
                                 */
                                private $refAccessoire;
                            
                                /**
                                 * @var float
                                 *
                                 * @ORM\Column(name="prix_accessoire", type="float", precision=10, scale=0, nullable=false)
                                 */
                                private $prixAccessoire;
                            
                                /**
                                 * @var EchelleAccessoire[]|Collection
                                 * @ORM\OneToMany(targetEntity="App\Entity\EchelleAccessoire", mappedBy="accessory", cascade={"persist"})
                                 */
                                private $EchelleAccessoire;
                            
                                /**
                                 * Constructor
                                 */
                                public function __construct()
                                {
                                    $this->EchelleAccessoire = new ArrayCollection();
                                }
                            
                                public function getId(): ?int
                                {
                                    return $this->id;
                                }
                            
                                public function getNomAccessoire(): ?string
                                {
                                    return $this->nomAccessoire;
                                }
                            
                                public function setNomAccessoire(string $nomAccessoire): self
                                {
                                    $this->nomAccessoire = $nomAccessoire;
                            
                                    return $this;
                                }
                            
                                public function getRefAccessoire(): ?string
                                {
                                    return $this->refAccessoire;
                                }
                            
                                public function setRefAccessoire(string $refAccessoire): self
                                {
                                    $this->refAccessoire = $refAccessoire;
                            
                                    return $this;
                                }
                            
                                public function getPrixAccessoire(): ?float
                                {
                                    return $this->prixAccessoire;
                                }
                            
                                public function setPrixAccessoire(float $prixAccessoire): self
                                {
                                    $this->prixAccessoire = $prixAccessoire;
                            
                                    return $this;
                                }
                            
                                public function getEchelleAccessoire(): Collection
                                {
                                    return $this->EchelleAccessoire;
                                }
                            
                                public function setEchelleAccessoire(Collection $EchelleAccessoire): self
                                {
                                    $this->EchelleAccessoire = $EchelleAccessoire;
                                    return $this;
                                }
                            
                                public function addEchelleAccessoire(EchelleAccessoire $EchelleAccessoire): self
                                {
                                    if (!$this->EchelleAccessoire->contains($EchelleAccessoire)) {
                                        $this->EchelleAccessoire->add($EchelleAccessoire);
                                        $EchelleAccessoire->setAccessoire($this);
                                    }
                                    return $this;
                                }
                            
                                public function removeEchelleAccessoire(EchelleAccessoire $EchelleAccessoire): self
                                {
                                    $this->EchelleAccessoire->removeElement($EchelleAccessoire);
                                    return $this;
                                }
                            
                            }
                            


                            Mon entité Echelle :

                            <?php
                            
                            namespace App\Entity;
                            
                            use Doctrine\Common\Collections\ArrayCollection;
                            use Doctrine\Common\Collections\Collection;
                            use Doctrine\ORM\Mapping as ORM;
                            
                            /**
                             * Echelle
                             *
                             * @ORM\Table(name="echelle", indexes={@ORM\Index(name="IDX_DA65794D712551BC", columns={"echelle_type_echelle_id"}), @ORM\Index(name="IDX_DA65794D52EAF347", columns={"echelle_hauteur_id"}), @ORM\Index(name="IDX_DA65794D21127304", columns={"echelle_sortie_id"}), @ORM\Index(name="IDX_DA65794DB7242249", columns={"echelle_norme_id"}), @ORM\Index(name="IDX_DA65794DC9BBACD4", columns={"echelle_config_id"}), @ORM\Index(name="IDX_DA65794D421B7347", columns={"echelle_entree_id"})})
                             * @ORM\Entity
                             */
                            class Echelle
                            {
                                /**
                                 * @var int
                                 *
                                 * @ORM\Column(name="id", type="integer", nullable=false)
                                 * @ORM\Id
                                 * @ORM\GeneratedValue(strategy="IDENTITY")
                                 */
                                private $id;
                            
                                /**
                                 * @var \Sortie
                                 *
                                 * @ORM\ManyToOne(targetEntity="Sortie")
                                 * @ORM\JoinColumns({
                                 *   @ORM\JoinColumn(name="echelle_sortie_id", referencedColumnName="id")
                                 * })
                                 */
                                private $echelleSortie;
                            
                                /**
                                 * @var \Entree
                                 *
                                 * @ORM\ManyToOne(targetEntity="Entree")
                                 * @ORM\JoinColumns({
                                 *   @ORM\JoinColumn(name="echelle_entree_id", referencedColumnName="id")
                                 * })
                                 */
                                private $echelleEntree;
                            
                                /**
                                 * @var \Hauteur
                                 *
                                 * @ORM\ManyToOne(targetEntity="Hauteur")
                                 * @ORM\JoinColumns({
                                 *   @ORM\JoinColumn(name="echelle_hauteur_id", referencedColumnName="id")
                                 * })
                                 */
                                private $echelleHauteur;
                            
                                /**
                                 * @var \TypeEchelle
                                 *
                                 * @ORM\ManyToOne(targetEntity="TypeEchelle")
                                 * @ORM\JoinColumns({
                                 *   @ORM\JoinColumn(name="echelle_type_echelle_id", referencedColumnName="id")
                                 * })
                                 */
                                private $echelleTypeEchelle;
                            
                                /**
                                 * @var \Norme
                                 *
                                 * @ORM\ManyToOne(targetEntity="Norme")
                                 * @ORM\JoinColumns({
                                 *   @ORM\JoinColumn(name="echelle_norme_id", referencedColumnName="id")
                                 * })
                                 */
                                private $echelleNorme;
                            
                                /**
                                 * @var \Config
                                 *
                                 * @ORM\ManyToOne(targetEntity="Config")
                                 * @ORM\JoinColumns({
                                 *   @ORM\JoinColumn(name="echelle_config_id", referencedColumnName="id")
                                 * })
                                 */
                                private $echelleConfig;
                            
                                /**
                                 * @var \Doctrine\Common\Collections\Collection
                                 *
                                 * @ORM\ManyToMany(targetEntity="ChangementVolee", inversedBy="echelle")
                                 * @ORM\JoinTable(name="echelle_changement_volee",
                                 *   joinColumns={
                                 *     @ORM\JoinColumn(name="echelle_id", referencedColumnName="id")
                                 *   },
                                 *   inverseJoinColumns={
                                 *     @ORM\JoinColumn(name="changement_volee_id", referencedColumnName="id")
                                 *   }
                                 * )
                                 */
                                private $changementVolee;
                            
                                /**
                                 * @var \Doctrine\Common\Collections\Collection
                                 *
                                 * @ORM\ManyToMany(targetEntity="Fixation", inversedBy="echelle")
                                 * @ORM\JoinTable(name="echelle_fixation",
                                 *   joinColumns={
                                 *     @ORM\JoinColumn(name="echelle_id", referencedColumnName="id")
                                 *   },
                                 *   inverseJoinColumns={
                                 *     @ORM\JoinColumn(name="fixation_id", referencedColumnName="id")
                                 *   }
                                 * )
                                 */
                                private $fixation;
                            
                                /**
                                 * @var \Doctrine\Common\Collections\Collection
                                 *
                                 * @ORM\ManyToMany(targetEntity="Palier", inversedBy="echelle")
                                 * @ORM\JoinTable(name="echelle_palier",
                                 *   joinColumns={
                                 *     @ORM\JoinColumn(name="echelle_id", referencedColumnName="id")
                                 *   },
                                 *   inverseJoinColumns={
                                 *     @ORM\JoinColumn(name="palier_id", referencedColumnName="id")
                                 *   }
                                 * )
                                 */
                                private $palier;
                            
                                /**
                                 * @var EchelleAccessoire[]|Collection
                                 * @ORM\OneToMany(targetEntity="App\Entity\EchelleAccessoire", mappedBy="Echelle", cascade={"persist", "remove"})
                                 */
                                private $EchelleAccessoire;
                            
                                /**
                                 * Constructor
                                 */
                                public function __construct()
                                {
                                    $this->EchelleAccessoire = new ArrayCollection();
                                    $this->changementVolee = new \Doctrine\Common\Collections\ArrayCollection();
                                    $this->fixation = new \Doctrine\Common\Collections\ArrayCollection();
                                    $this->palier = new \Doctrine\Common\Collections\ArrayCollection();
                                }
                            
                                public function getId(): ?int
                                {
                                    return $this->id;
                                }
                            
                                public function getEchelleSortie(): ?Sortie
                                {
                                    return $this->echelleSortie;
                                }
                            
                                public function setEchelleSortie(?Sortie $echelleSortie): self
                                {
                                    $this->echelleSortie = $echelleSortie;
                            
                                    return $this;
                                }
                            
                                public function getEchelleEntree(): ?Entree
                                {
                                    return $this->echelleEntree;
                                }
                            
                                public function setEchelleEntree(?Entree $echelleEntree): self
                                {
                                    $this->echelleEntree = $echelleEntree;
                            
                                    return $this;
                                }
                            
                                public function getEchelleHauteur(): ?Hauteur
                                {
                                    return $this->echelleHauteur;
                                }
                            
                                public function setEchelleHauteur(?Hauteur $echelleHauteur): self
                                {
                                    $this->echelleHauteur = $echelleHauteur;
                            
                                    return $this;
                                }
                            
                                public function getEchelleTypeEchelle(): ?TypeEchelle
                                {
                                    return $this->echelleTypeEchelle;
                                }
                            
                                public function setEchelleTypeEchelle(?TypeEchelle $echelleTypeEchelle): self
                                {
                                    $this->echelleTypeEchelle = $echelleTypeEchelle;
                            
                                    return $this;
                                }
                            
                                public function getEchelleNorme(): ?Norme
                                {
                                    return $this->echelleNorme;
                                }
                            
                                public function setEchelleNorme(?Norme $echelleNorme): self
                                {
                                    $this->echelleNorme = $echelleNorme;
                            
                                    return $this;
                                }
                            
                                public function getEchelleConfig(): ?Config
                                {
                                    return $this->echelleConfig;
                                }
                            
                                public function setEchelleConfig(?Config $echelleConfig): self
                                {
                                    $this->echelleConfig = $echelleConfig;
                            
                                    return $this;
                                }
                            
                                /**
                                 * @return Collection|ChangementVolee[]
                                 */
                                public function getChangementVolee(): Collection
                                {
                                    return $this->changementVolee;
                                }
                            
                                public function addChangementVolee(ChangementVolee $changementVolee): self
                                {
                                    if (!$this->changementVolee->contains($changementVolee)) {
                                        $this->changementVolee[] = $changementVolee;
                                    }
                            
                                    return $this;
                                }
                            
                                public function removeChangementVolee(ChangementVolee $changementVolee): self
                                {
                                    $this->changementVolee->removeElement($changementVolee);
                            
                                    return $this;
                                }
                            
                                /**
                                 * @return Collection|Fixation[]
                                 */
                                public function getFixation(): Collection
                                {
                                    return $this->fixation;
                                }
                            
                                public function addFixation(Fixation $fixation): self
                                {
                                    if (!$this->fixation->contains($fixation)) {
                                        $this->fixation[] = $fixation;
                                    }
                            
                                    return $this;
                                }
                            
                                public function removeFixation(Fixation $fixation): self
                                {
                                    $this->fixation->removeElement($fixation);
                            
                                    return $this;
                                }
                            
                                /**
                                 * @return Collection|Palier[]
                                 */
                                public function getPalier(): Collection
                                {
                                    return $this->palier;
                                }
                            
                                public function addPalier(Palier $palier): self
                                {
                                    if (!$this->palier->contains($palier)) {
                                        $this->palier[] = $palier;
                                    }
                            
                                    return $this;
                                }
                            
                                public function removePalier(Palier $palier): self
                                {
                                    $this->palier->removeElement($palier);
                            
                                    return $this;
                                }
                            
                                public function getEchelleAccessoire(): Collection
                                {
                                    return $this->EchelleAccessoire;
                                }
                            
                                public function setEchelleAccessoire(Collection $EchelleAccessoire): self
                                {
                                    $this->EchelleAccessoire = $EchelleAccessoire;
                                    return $this;
                                }
                            
                                public function addEchelleAccessoire(EchelleAccessoire $EchelleAccessoire): self
                                {
                                    if (!$this->EchelleAccessoire->contains($EchelleAccessoire)) {
                                        $this->EchelleAccessoire->add($EchelleAccessoire);
                                        $EchelleAccessoire->setEchelle($this);
                                    }
                                    return $this;
                                }
                            
                                public function removeEchelleAccessoire(EchelleAccessoire $EchelleAccessoire): self
                                {
                                    $this->EchelleAccessoire->removeElement($EchelleAccessoire);
                                    return $this;
                                }
                            
                            }
                            


                            Mon entité EchelleAccessoire :

                            <?php
                            
                            namespace App\Entity;
                            
                            use App\Repository\EchelleAccessoireRepository;
                            use Doctrine\ORM\Mapping as ORM;
                            
                            /**
                             * @ORM\Entity(repositoryClass=EchelleAccessoireRepository::class)
                             */
                            class EchelleAccessoire
                            {
                                /**
                                 * @ORM\Id
                                 * @ORM\GeneratedValue
                                 * @ORM\Column(type="integer")
                                 */
                                private $id;
                            
                                /**
                                 * @ORM\ManyToOne(targetEntity=Echelle::class)
                                 * @ORM\JoinColumn(nullable=false)
                                 */
                                private $Echelle;
                            
                                /**
                                 * @ORM\ManyToOne(targetEntity=Accessoire::class)
                                 * @ORM\JoinColumn(nullable=false)
                                 */
                                private $Accessoire;
                            
                                /**
                                 * @ORM\Column(type="integer")
                                 * @ORM\Column(nullable=true)
                                 */
                                private $Qte;
                            
                                public function getId(): ?int
                                {
                                    return $this->id;
                                }
                            
                                public function getEchelle(): ?Echelle
                                {
                                    return $this->Echelle;
                                }
                            
                                public function setEchelle(?Echelle $Echelle): self
                                {
                                    $this->Echelle = $Echelle;
                            
                                    return $this;
                                }
                            
                                public function getAccessoire(): ?Accessoire
                                {
                                    return $this->Accessoire;
                                }
                            
                                public function setAccessoire(?Accessoire $Accessoire): self
                                {
                                    $this->Accessoire = $Accessoire;
                            
                                    return $this;
                                }
                            
                                public function getQte(): ?int
                                {
                                    return $this->Qte;
                                }
                            
                                public function setQte(int $Qte): self
                                {
                                    $this->Qte = $Qte;
                            
                                    return $this;
                                }
                            }
                            

                            Mon controleur :

                                public function AjoutAccessoire(Request $request, int $id): Response
                                {
                                    $Echelle = $this->getDoctrine()->getRepository(Echelle::class)->find($id);
                                    $form = $this->createForm(AccessoireType2Type::class, $Echelle);
                                    $form->handleRequest($request);
                            
                                    /*if ($form->isSubmitted() && $form->isValid())
                                    {
                                        /*Recuperation des données du formulaire*/
                                        /*$Accessoire = $form->getData();
                                        $Accessoires = $Accessoire['id'];
                                        $tableau = count($Accessoires ,$mode = COUNT_NORMAL );*/
                                        
                                        /* Pour i allant de 0 jusqu'à le nombre de valeur sélectionnées, on ajoute chaque valeur une à une dans la relation entre Accessoire et Echelle
                                        for ($i = 0; $i < $tableau; $i++)
                                        {
                                            $EchelleAccessoire = new EchelleAccessoire();
                                            $EchelleAccessoire->setAccessoire($Accessoires[$i]);
                                            $EchelleAccessoire->setEchelle($Echelle);
                            
                                            $entityManager = $this->getDoctrine()->getManager();
                                            $entityManager->persist($EchelleAccessoire);
                                            $entityManager->flush();*/
                                        //}
                            
                                        /*return $this->redirectToRoute('ajoutChangementVolee', array('id'=> $id));
                                    }*/
                                    return $this->render('AccessoireAjout.html.twig',['Form' => $form->createView()]);
                            
                                }


                            Mon premier form (celui d'origine sans la collection) :

                            <?php
                            
                            namespace App\Form;
                            
                            use App\Entity\Echelle;
                            use App\Entity\Accessoire;
                            use App\Entity\EchelleAccessoire;
                            use Symfony\Bridge\Doctrine\Form\Type\EntityType;
                            use Symfony\Component\Form\AbstractType;
                            use Symfony\Component\Form\Extension\Core\Type\CollectionType;
                            use Symfony\Component\Form\Extension\Core\Type\NumberType;
                            use Symfony\Component\Form\Extension\Core\Type\TextType;
                            use Symfony\Component\Form\FormBuilderInterface;
                            use Symfony\Component\OptionsResolver\OptionsResolver;
                            
                            class AccessoireType extends AbstractType
                            {
                                public function buildForm(FormBuilderInterface $builder, array $options)
                                {
                                    $builder
                                    ->add('Accessoire', EntityType::class, [
                                        'class' => Accessoire::class,
                                        'choice_value' => 'id',
                                        'choice_label' => 'nomAccessoire',
                                        'expanded' => 'false'
                                    ])
                                    ->add('Qte', NumberType::class);
                                    
                                }
                            
                                public function configureOptions(OptionsResolver $resolver)
                                {
                                    $resolver->setDefaults([
                                        'data_class' => EchelleAccessoire::class,
                                    ]);
                                }
                            }


                            et enfin mon Formulaire qui appelle celui du dessus :

                            <?php
                            
                            namespace App\Form;
                            
                            use App\Entity\EchelleAccessoire;
                            use App\Entity\Accessoire;
                            use App\Entity\Echelle;
                            use App\Form\AccessoireType;
                            use Symfony\Bridge\Doctrine\Form\Type\EntityType;
                            use Symfony\Component\Form\AbstractType;
                            use Symfony\Component\Form\Extension\Core\Type\CollectionType;
                            use Symfony\Component\Form\Extension\Core\Type\NumberType;
                            use Symfony\Component\Form\FormBuilderInterface;
                            use Symfony\Component\OptionsResolver\OptionsResolver;
                            
                            class AccessoireType2Type extends AbstractType
                            {
                                public function buildForm(FormBuilderInterface $builder, array $options)
                                {
                                    $builder
                                    ->add('EchelleAccessoire', CollectionType::class, [
                                        'allow_add' => true,
                                        'label' => false,
                                        'by_reference' => false,
                                        'allow_delete' => true,
                                        'entry_type' => AccessoireType::class,
                                        'entry_options' => [
                                            'label' => false ]])
                            
                                    ;
                                }
                            
                                public function configureOptions(OptionsResolver $resolver)
                                {
                                    $resolver->setDefaults([
                                        'data_class' => Echelle::class,
                                    ]);
                                }
                            }
                            

                            Je vais essayer de tout simplement faire tourner ce que tu m'as donné dans un projet neuf. Je te tiens au courant !

                            EDIT 2 :

                            Bon c'est mal parti, je n'arrive meme pas à faire une migration pour creer automatiquement la base avec tes entités. Problème de driver php (extension=pdo_mysql).

                            EDIT 3 :

                            J'ai reussi à migrer, (probleme de type de base dans le .env) Actuellement, ça me rend une page 404 quand j'essaye la route de l'index. Je te tiens toujours au courant.

                            -
                            Edité par TheoGouchet 4 mars 2021 à 16:14:57

                            • Partager sur Facebook
                            • Partager sur Twitter
                              4 mars 2021 à 20:11:13

                              Hello,

                              C'est normal, il faut soit ajouter un .htaccess qui redirige tes requêtes, soit modifier ton VHOST pour faire pointer vers ton index.php ou sinon tu fais comme moi juste pour tester en dev, tu fais [ton-chemin-d'accès-vers-ton-dossier]/public/index.php/ladder/create

                              Regarde bien mon code, car celui-ci fonctionne parfaitement, y compris pour la partie jQuery.

                              La raison pour laquelle j'ai mis Echelle comme entité de data_class c'est parce que je me suis demandé ce que je voulais faire exactement. La réponse est : Je souhaite ajouter ou modifier les Accessoires d'une Echelle. Donc je dois modifier Echelle. Et j'ai construit du coup mes formulaires imbriqué comme ça.

                              Dans le formulaire de modification de l'Echelle, la seule propriété que je voulais modifier c'était les accessoires. Du coup je n'ai mis que cet attributs dans le formulaire principale.

                              Alors dans un modèle classique on aurait fait une ManyToMany classique car une Echelle peut avoir plusieurs Accessoires et un Accessoire peut appartenir à plusieurs Echelles. Je n'aurais donc pas eu d'entité intermédiaire et je n'en aurais donc que deux. Mais dans ton modèle, tu rajoutes sur la table de liaison un attribut supplémentaire qui est "quantité". Et avec Doctrine, le seul moyen d'arriver à ce résultat est d'avoir une entité intermédiaire qui va contenir cet attribut supplémentaire.

                              Du coup c'est pour ça que dans la hiérarchie de mes formulaires j'ai :

                              - Le formulaire principale qui est celui de l'Echelle avec pour champ, la seule valeur que je souhaite modifier. Ici, echelleAccessoires qui est une collection car j'en ai plusieurs.

                              - Le formulaire d'une EchelleAccessoire qui contient les deux attributs de mon entité que je veux définir. Ici la quantité et l'accessoire associé. Pour les accessoires je récupère la liste de ce dont j'ai besoin. J'aurais pu prendre que les accessoires d'un type particulier si je voulais pas tout.

                              Et avec ce code, tu verras que quand tu en auras ajouter une fois, ils seront présent à l'affichage automatiquement. Bon même si j'ai oublié d'enlever une redirection qui ne sert à rien.

                              -
                              Edité par skuti 4 mars 2021 à 20:35:45

                              • Partager sur Facebook
                              • Partager sur Twitter
                              $2b||!$2b
                                5 mars 2021 à 9:17:38

                                Oh oui excellent en effet c'est parfaitement ce que je veux faire. Ton code explique bien le tout. Je vais essayer de l'adapter à mon projet et je reviens vers toi. Merci infiniment !

                                EDIT : ça marche. Franchement merci infiniment pour ton aide apporté ! Une dernière question du coup. Est ce que tu pourrais m'expliquer le fonctionnement du code en JQuery ligne par ligne si c'est possible pour toi ? Je ne connais pas trop ce langage.

                                -
                                Edité par TheoGouchet 5 mars 2021 à 9:39:24

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  5 mars 2021 à 16:38:40

                                  Cool ! Et de rien :D

                                  Tu oublieras pas de mettre ton sujet en résolu :)

                                  Voila les explications:

                                  $(document).ready(function() {
                                      const $accessoriessCollectionHolder = $('ul.accessories'); // Je récupère l'élément qui va contenir ma liste d'accessoire
                                      $accessoriessCollectionHolder.data('index', $accessoriessCollectionHolder.find('input').length); // Je rajoute une meta donnée sur mon conteneur pour compter le nombre d'éléments que j'ai actuellement
                                      $('body').on('click', '.add_item_link', function(e) { // Je veux executer cette fonction à chaque fois que je clic sur le bouton d'ajout d'élément
                                          var $accessoriessCollectionHolder = $(e.currentTarget).data('collectionHolderClass'); // Je récupère la class de mon conteneur d'accessoires
                                          addFormToCollection($accessoriessCollectionHolder); // Je lance l'ajout d'un nouvel élément
                                      });
                                  
                                      $accessoriessCollectionHolder.find('li').each(function() { // Je boucle sur chaque élément déjà présent (dans le cas où il y a déjà des accessoires présent et j'éxecute la fonction donnée
                                          addTagFormDeleteLink($(this)); // Je lance l'ajout d'un bouton permettant de supprimer un accessoire (uniquement Javascript pas en BDD. Sa ça ce fait quand tu soumets le formulaire)
                                      });
                                  });
                                  
                                  function addFormToCollection($collectionHolderClass) {
                                      const $collectionHolder = $('.' + $collectionHolderClass); // Je récupère le conteneur d'accessoire
                                      const prototype = $collectionHolder.data('prototype'); // Je récupère le prototype du formulaire pour 1 accessoire (voir https://github.com/rsida/symfony-example-many-to-many-with-attribute/blob/master/templates/ladder/accessories.update.html.twig#L11)
                                      const index = $collectionHolder.data('index'); // Je récupère le nombre d'accessoires actuel dans le formulaire
                                      let newForm = prototype;
                                      newForm = newForm.replace(/__name__/g, index); // Je modifie le label pour rajouter un index
                                      $collectionHolder.data('index', index + 1); // Je modifie le compte pour dire qu'il y a un élément sup
                                      const $newFormLi = $('<li></li>').append(newForm); // Je crée une nouvelle ligne dans le formulaire où je colle le prototype du formulaire Accessoire. Cela va créer les éléments HTML.
                                      $collectionHolder.append($newFormLi); // J'ajoute la nouvelle ligne dans le conteneur d'accessoires
                                      addTagFormDeleteLink($newFormLi); // Je demande à ajouter le bouton pour supprimer la ligne sur cet élément
                                  }
                                  
                                  function addTagFormDeleteLink($accessoryFormLi) {
                                      const $removeFormButton = $('<button type="button">Delete this Accessory</button>'); // J'ajoute un bouton qui va servir à supprimer la ligne
                                      $accessoryFormLi.append($removeFormButton); // Je l'ajoute à la ligne
                                      $removeFormButton.on('click', function() { // Je souhaite exécuter la fonction donnée au clic sur ce bouton
                                          $accessoryFormLi.remove(); // Je demande à supprimer la ligne en supprimer l'élément DOM (HTML) de la ligne.
                                      });
                                  }

                                  Voila :)

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  $2b||!$2b

                                  [Symfony 5] Propriété portée, Ajouter Qte Form

                                  × 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