Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Symfony 5] Propriété portée ajout avec Entitytype

    8 juin 2021 à 15:15:22

    Bonjour, j'ai déja fait un post précédent sur lequel on m'avait indiqué une réponse qui fonctionne, cependant les besoins ont changé. J'ai 3 entités : Echelle, Accessoire, et EchelleAccessoire qui contient l'id de l'echelle, l'id de l'accessoire et la Qte d'accessoire. Mon but est de faire comme suit :

    graphiquement, cela fonctionne me direz-vous. Mais le problème c'est que la liste des accessoires vient d'une entitytype avec laquelle j'ai fait un for sur le twig. Les champs quantité ne sont que des input mis en dur dans le code : 

    {% 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>
            <table class="table table-striped table-bordered table-sm ">
        {{ form_start(Form) }}
        {% for key, type in Form.Accessoire %}
        <tr>
        <td>
          {{ form_widget(type) }}
          </td>
          <td>
          <input type="textarea" name="Quantite" id="qte" placeholder="Quantité">
          </td>
          </tr>
        {% endfor %}
        </table>
            <a styke="color:black" class="btn bg-warning" href="#">Precedent</a>
        <button class="btn bg-warning">Suivant</button>
        {{ form_end(Form) }}
        </div>
        </div>
    <div>
    <br>
    </div>
    <br>
    
    {% endblock %}
    
    {% block progression %}
    {{ include('ProgressionBar.html.twig') }}
    {% endblock %}

    La solution qu'on m'a déja proposé était une collection de form mais le soucis c'est que cela m'affichait une ligne de choix d'accessoire, plus un champ pour la quantité, et un bouton pour ajouter à nouveau les deux champs précédents. Pour ma part, il me faut tous les accessoires avec chacuns, une ligne pour renseigner la quantité.

    N'hésitez pas à me demander plus de code s'il y en a besoin.

    Merci à vous !

    • Partager sur Facebook
    • Partager sur Twitter
      8 juin 2021 à 18:13:31

      Bonjour,

      Pour ma compréhension fonctionnelle,

      Comment proposes tu d'ajouter un accessoire à une échelle ? par le fait que tu as coché un radio bouton ET mis une quantité ?

      Comment proposes tu de supprimer un accessoire déjà relié à une échelle ?

      Combien d'accessoires as tu ? Car je suppose de la manière dont tu le fais que tu présentes tous les accessoires possibles et ce sont les boutons précédents et suivants qui permettent de dérouler le catalogue des accessoires ?

      A+

      -
      Edité par monkey3d 8 juin 2021 à 18:14:19

      • Partager sur Facebook
      • Partager sur Twitter
        9 juin 2021 à 9:06:30

        Salut ! C'est une petite erreur d'image, a la place des radio boutons, ce sont des checkbox. En effet, lorsque l'utilisateur coche une case et met une quantité, la on peut ajouter l'accessoire -> insertion dans EchelleAccessoire en renseignant l'accessoire selectionné, l'echelle (on la connait deja dans mon exemple) et la quantité choisie. Les boutons suivants et précédent ne sont la que pour revenir à une autre étape ou passer à la suivante, qui n'a rien à voir avec mon problème. Ici, c'est un affichage de tous les accessoires que l'ont peut rajouter qui m'intéresse. L'utilisateur choisit clique sur suivant et tout est ajouté.

        Je t'ai refait une image pour que tu comprenne :

        -
        Edité par TheoGouchet 9 juin 2021 à 9:13:40

        • Partager sur Facebook
        • Partager sur Twitter
          9 juin 2021 à 12:13:24

          Hey !

          Vu que tu es sous symfony 5, j'imagine que tu utilises un formBuilder non ? Tu pourrais nous montrer le controller à quoi il ressemble lorsque tu crées ce formulaire stp ? Normalement tu as un form_start etc... Donc tu n'es pas censé mettre d'input à moins que tu ais envie de personnaliser l'affichage de ton formulaire normalement.

          Ensuite, tu as juste à faire une validation du formulaire 

          if ($form->isSubmitted() && $form->isValid()) 
          {
              ...
          }

          Et pour lé redirection, tu mets tout simplement la page suivante je pense ^^



          • Partager sur Facebook
          • Partager sur Twitter
            9 juin 2021 à 14:05:43

            MattAmsellem a écrit:

            Hey !

            Vu que tu es sous symfony 5, j'imagine que tu utilises un formBuilder non ? Tu pourrais nous montrer le controller à quoi il ressemble lorsque tu crées ce formulaire stp ? Normalement tu as un form_start etc... Donc tu n'es pas censé mettre d'input à moins que tu ais envie de personnaliser l'affichage de ton formulaire normalement.

            Ensuite, tu as juste à faire une validation du formulaire 

            if ($form->isSubmitted() && $form->isValid()) 
            {
                ...
            }

            Et pour lé redirection, tu mets tout simplement la page suivante je pense ^^



            Salut ! Mon problème est plus complexe que ça. J'avais déja reussi à faire un choix d'accessoire avec un formulaire imbriqué et du javascript (On choisit l'accessoire que l'on veut, on met la quantité et si on veut ajouter un autre accessoire on clique sur un bouton + par exemple qui nous affiche une nouvelle fois ce Form) Sauf qu'ici au lieu de choisir un accessoire via une liste déroulante et en mettant sa quantité. Puis en ajouter un autre via le bouton, je veux que tout soit affiché directement sans liste deroulante avec sa quantité associé que l'on peut choisir. Vois-tu ce dont je veux parler ?

            • Partager sur Facebook
            • Partager sur Twitter
              9 juin 2021 à 14:15:35

              Donc tu veux bien que tout soit affiché et que tu mettes les accéssoires en une fois ?

              Si c'est ça que tu veux faire, c'est plus simple que la liste déroulante, et du coup, c'est ce que je t'ai dit de faire pour le coup ^^

              Dit moi si j'ai bien comprit ou non le soucis :)

              • Partager sur Facebook
              • Partager sur Twitter
                9 juin 2021 à 14:22:28

                Oui c'est ça tout en une fois. Seulement, je vois comment mettre tous les accessoires en une fois puisque c'est une entitytype que l'ont peut mettre en expended et multiple mais pour mettre un champs quantité  chaque fois à coté ? J'ai trouvé la solution de mettre un <input> directement mais c'est bien evidemment superflux et illogique pour moi car si il y a des Form dans symfony ce n'est pas pour rien. Tu saurais m'éclairer peut-être ?

                -
                Edité par TheoGouchet 9 juin 2021 à 14:23:23

                • Partager sur Facebook
                • Partager sur Twitter
                  9 juin 2021 à 14:24:43

                  J'ai fait un truc de ce genre et je suis passé par du javascript.

                  Je donne l'approche de ma solution qui est opérationnelle depuis plus de 2 ans.

                  Tu listes les accessoires comme tu l'as fait et tu ajoutes sur les checkboxs et les input quantité des EventListener.

                  https://developer.mozilla.org/fr/docs/Web/API/EventListener

                  Donc à chaque manip sur un composant "graphique", tu vas récupérer les infos que tu traites ensuite par de l'ajax pour mettre à jour le côté serveur entité EchelleAccessoire.

                  Tu peux ainsi traiter le coché / décoché, la variable quantité .... sans rafraîchir la page où avoir un bouton de submit.

                  Néanmoins, je ne dis pas que ce ne soit pas possible avec un form de Symfony.

                  Nota : pourquoi des input de type text ? le type number ne serait-il pas plus approprié ?

                  https://developer.mozilla.org/fr/docs/Web/HTML/Element/Input/number

                  A+

                  -
                  Edité par monkey3d 9 juin 2021 à 14:33:33

                  • Partager sur Facebook
                  • Partager sur Twitter
                    9 juin 2021 à 14:33:12

                    monkey3d a écrit:

                    J'ai fait un truc de ce genre et je suis passé par du javascript.

                    Je donne l'approche de ma solution qui est opérationnelle depuis plus de 2 ans.

                    Tu listes les accessoires comme tu l'as fait et tu ajoutes sur les checkboxs et les input quantité des EventListener. Donc à chaque manip sur un composant "graphique", tu vas récupérer les infos que tu traites ensuite par de l'ajax pour mettre à jour le côté serveur entité EchelleAccessoire.

                    https://developer.mozilla.org/fr/docs/Web/API/EventListener

                    Je ne dis pas que ce ne soit pas possible avec un form de Symfony.

                    Nota : pourquoi des input de type text ? le type number ne serait-il pas plus approprié ?

                    https://developer.mozilla.org/fr/docs/Web/HTML/Element/Input/number

                    A+

                    -
                    Edité par monkey3d il y a 2 minutes


                    Je vais voir ta solution ! Le type text c'était simplement pour montrer un exemple de ce que je voulais que ça donne :)

                    Tu pense que c'est possible sans javascript ? Symfony doit bien avoir une solution pour ça non ?

                    -
                    Edité par TheoGouchet 9 juin 2021 à 14:35:17

                    • Partager sur Facebook
                    • Partager sur Twitter
                      9 juin 2021 à 14:37:49

                      Avec un type number cela donne quasiment la même présentation et même plus subtil puisque tu peux intrinsèquement contrôler les valeurs.

                      Si tu adoptes ma solution, il ne faut finalement pas écrire beaucoup de code js et php mais faut bien identifier chaque composant.

                      Et peut-être que MattAnsellem a une solution toute faite avec Symfony ... moi je n'ai pas trouvé directement dans ce cadre ... d'où le sujet m'intéresse. ;)

                      Bien-sûr la collection de formulaires que tu ne prends pas je l'utilise aussi mais pour d'autres besoins.

                      A+

                      -
                      Edité par monkey3d 9 juin 2021 à 14:41:28

                      • Partager sur Facebook
                      • Partager sur Twitter
                        9 juin 2021 à 14:40:44

                        Selon si la réponse de monkey est bonne, tu pourras peut-être voir ma solution.

                        Le plus simple, c'est de le faire justement avec le formBuilder sur ton entité EchelleAccessoires que tu cherches. Tu récupères tout les éléments possibles, (Vis, Ecrou, etc...), puis pour chaque élément, dans ton formBuilder, tu vas lui mettre NumberType.

                        Voici un exemple : 

                        $form = $this->createFormBuilder();
                        
                        $array[options] // Contient toutes tes options, donc tu peux l'initialiser avant avec les entités comme clé, et leur libelle comme options
                        
                        foreach ($array as $key, $option)
                        {
                           $form->add($key, NumberType::class, [
                              'required' => false,
                              ]
                           );
                        }
                        
                        $form->handleRequest($req);
                        
                        if ($form->isSubmitted &&...)
                        {
                           foreach ($array as $key, $option)
                           {
                              $temp = $form->get($key)->getData()
                              if ($temp != null && $temp > 0)
                              {
                                  // Tu instancies un nouvel EchelleAccessoires avec $temp comme valeur, et tu associes l'echelle avec l'accessoire (du coup $key il me semble pck les clés sont une entité accéssoire)
                              }
                           }
                        }

                        J'espère que c'est assez clair :D

                        EDIT : Je suis juste perdu entre les clés et valeurs associés, mais si l'un ne marche pas, c'est que c'est l'autre ^^

                        -
                        Edité par MattAmsellem 9 juin 2021 à 14:45:15

                        • Partager sur Facebook
                        • Partager sur Twitter
                          9 juin 2021 à 15:03:47

                          MattAmsellem a écrit:

                          Selon si la réponse de monkey est bonne, tu pourras peut-être voir ma solution.

                          Le plus simple, c'est de le faire justement avec le formBuilder sur ton entité EchelleAccessoires que tu cherches. Tu récupères tout les éléments possibles, (Vis, Ecrou, etc...), puis pour chaque élément, dans ton formBuilder, tu vas lui mettre NumberType.

                          Voici un exemple : 

                          $form = $this->createFormBuilder();
                          
                          $array[options] // Contient toutes tes options, donc tu peux l'initialiser avant avec les entités comme clé, et leur libelle comme options
                          
                          foreach ($array as $key, $option)
                          {
                             $form->add($key, NumberType::class, [
                                'required' => false,
                                ]
                             );
                          }
                          
                          $form->handleRequest($req);
                          
                          if ($form->isSubmitted &&...)
                          {
                             foreach ($array as $key, $option)
                             {
                                $temp = $form->get($key)->getData()
                                if ($temp != null && $temp > 0)
                                {
                                    // Tu instancies un nouvel EchelleAccessoires avec $temp comme valeur, et tu associes l'echelle avec l'accessoire (du coup $key il me semble pck les clés sont une entité accéssoire)
                                }
                             }
                          }

                          J'espère que c'est assez clair :D

                          EDIT : Je suis juste perdu entre les clés et valeurs associés, mais si l'un ne marche pas, c'est que c'est l'autre ^^

                          -
                          Edité par MattAmsellem il y a 11 minutes

                          Je stagne juste sur le array option. Je dois faire un findall() pour associé à l'array tous les accessoires dans ma bd ?
                          C'est à dire que je suis sur une creation de form avec un fichier directement, pas dans le controller :

                          <?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('Accessoire', EntityType::class, [
                                      'class' => Accessoire::class,
                                      'choice_label'=> 'nomAccessoire',
                                          'choice_value'=>'id',
                                          'expanded' => true,
                                          'multiple' => true])
                                  ->add('Extra', NumberType::class, [
                                      'mapped' => false,
                                  ])
                                  ;
                              }
                          
                              public function configureOptions(OptionsResolver $resolver)
                              {
                                  $resolver->setDefaults([
                                      'data_class' => EchelleAccessoire::class,
                                      'allow_extra_fields' => true,
                                  ]);
                              }
                          }



                          -
                          Edité par TheoGouchet 9 juin 2021 à 15:47:12

                          • Partager sur Facebook
                          • Partager sur Twitter
                            10 juin 2021 à 11:50:26

                            Ahh d'accord. Oui tu fais le formulaire comme ça d'accord.

                            Perso, je trouve cette façon un peu plus compliqué.

                            Pour remplir ton array avec tout tes accéssoires, tu fais comme cela :

                            $data = $accessoireRepo->findAll(); // Selon ce que tu veux récupérer
                            
                            $array_accessoires = []; // Tu initialises pour avoir l'accès en dehors du foreach
                            foreach ($data as $accessoire)
                            {
                                // Tu mets le string de l'accessoire en clé, et l'entité clé comme valeur associée
                                $array_accessoires[$accessoire->getNom()] = $accessoire;
                            }

                            Tu initialises ton tableau comme ça, puis tu fais le formulaire comme je te l'ai dit. Ce qui donnerai je pense :

                            // Création du formulaire
                            $foreach ($array_accessoires as $key, $value)
                            {
                               $form->add($key, NumberType::class, [
                                  'required' => false,
                               ]);
                            }
                            
                            $form->handleRequest($req);
                            
                            if ($form->isSubmitted && ...)
                            {
                               foreach($array_accessoires as $key, $value)
                               {
                                  $data_key = $form->get($key)->getData(); // Juste pour éviter de répéter $form->get... Dans la condition
                                  if ($data_key != null && $data_key > 0)
                                  {
                                     $new_echelle_accessoire = new EchelleAccessoire($data_key, $ton_echelle, $value /* qui contient l'entité accessoire associée)*/); 
                                     // Après tu fais instancies ton entité EchelleAccessoire comme toi tu l'as fait hein, moi je ne m'en sers que d'exemple car je ne sais pas comment tu as fait ton entité)
                                     // Puis tu la mets dans ta base de données avec le persist et flush
                                  }
                               }
                            }



                            Je sais pas si du coup ça répond à ta question, mais ça te simplifierai le travail je pense ^^

                            Là pour le coup je le ferai directement dans le controller, mais je pense que tu peux adapter ma méthode pour le faire dans ton fichier php à pars.

                            Matt

                            -
                            Edité par MattAmsellem 10 juin 2021 à 11:53:35

                            • Partager sur Facebook
                            • Partager sur Twitter
                              10 juin 2021 à 13:23:11

                              Salut,

                              Il faut passer par collection, tu n'es pas obligé d'avoir un bouton + puisque tu as la possibilité de charger les données de la collection. Peux-tu montrer le code que tu as fait en utilisant une collection ?

                              • Partager sur Facebook
                              • Partager sur Twitter
                              le bienfait n'est jamais perdu
                                10 juin 2021 à 14:15:11

                                Salut ! Voici ce que j'ai fait :

                                Mon controller :

                                public function AjoutAccessoire(Request $request, int $id): Response
                                    {
                                
                                        $session = $this->get('session');
                                        if($session->get('valeurverification') == 1 || $session->get('valeurverification') == 2)
                                        {
                                        $Echelle = $this->getDoctrine()->getRepository(Echelle::class)->find($id);
                                        $form = $this->createForm(AccessoireType2Type::class, $Echelle);
                                        $form->handleRequest($request);
                                
                                        if ($form->isSubmitted() && $form->isValid())
                                        {   
                                            $this->getDoctrine()->getManager()->flush();
                                            return $this->redirectToRoute('ajoutChangementVolee', array('id'=> $id));
                                        }
                                        return $this->render('AccessoireAjout.html.twig',['Form' => $form->createView()]);
                                    }
                                    else{
                                        return $this->render('Denied.html.twig');
                                    }
                                    }

                                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(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 class="text-dark btn bg-warning" type="submit">Suivant</button></td>
                                                <td><button type="button" class="add_item_link text-dark btn bg-warning" data-collection-holder-class="accessories">+</button></td>
                                            </tr>
                                        </table>
                                    {{ form_end(Form) }}
                                
                                    
                                    
                                        </div>
                                    </div>
                                
                                {% endblock %}
                                
                                {% block javascripts %}
                                    <script>
                                        $(document).ready(function() {
                                            const $accessoriessCollectionHolder = $('ul.accessories');
                                            $accessoriessCollectionHolder.data('index', $accessoriessCollectionHolder.find('input').length);
                                            $('body').on('click', '.add_item_link', function(e) {
                                                var $accessoriessCollectionHolder = $(e.currentTarget).data('collectionHolderClass');
                                                addFormToCollection($accessoriessCollectionHolder);
                                            });
                                            $accessoriessCollectionHolder.find('li').each(function() {
                                                addTagFormDeleteLink($(this));
                                            });
                                        });
                                        function addFormToCollection($collectionHolderClass) {
                                            const $collectionHolder = $('.' + $collectionHolderClass);
                                            const prototype = $collectionHolder.data('prototype');
                                            const index = $collectionHolder.data('index');
                                            let newForm = prototype;
                                            newForm = newForm.replace(/__name__/g, index);
                                            $collectionHolder.data('index', index + 1);
                                            const $newFormLi = $('<li></li>').append(newForm);
                                            $collectionHolder.append($newFormLi);
                                            addTagFormDeleteLink($newFormLi);
                                        }
                                        function addTagFormDeleteLink($accessoryFormLi) {
                                            const $removeFormButton = $('<button class="text-dark btn bg-warning" type="button">-</button>');
                                            $accessoryFormLi.append($removeFormButton);
                                            $removeFormButton.on('click', function() {
                                                $accessoryFormLi.remove();
                                            });
                                        }
                                    </script>
                                {% endblock %}
                                
                                {% block progression %}
                                {{ include('ProgressionBar.html.twig') }}
                                {% endblock %}


                                Mes deux formulaires :

                                <?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,
                                        ]);
                                    }
                                }
                                
                                <?php
                                
                                namespace App\Form;
                                
                                use App\Entity\Echelle;
                                use App\Entity\Accessoire;
                                use App\Entity\EchelleAccessoire;
                                use App\Repository\AccessoireRepository;
                                use Doctrine\ORM\EntityRepository;
                                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',
                                            'query_builder' => function(EntityRepository $er)
                                            {
                                            return $er->createQueryBuilder('a')
                                            ->andWhere('a.Commercialise = :val')
                                            ->setParameter('val', 1)
                                            ->orderBy('a.id', 'ASC');
                                            }
                                        ])
                                        ->add('Qte', NumberType::class);
                                        
                                    }
                                
                                    public function configureOptions(OptionsResolver $resolver)
                                    {
                                        $resolver->setDefaults([
                                            'data_class' => EchelleAccessoire::class,
                                        ]);
                                    }
                                }
                                





                                • Partager sur Facebook
                                • Partager sur Twitter
                                  10 juin 2021 à 14:23:18

                                  Ton code ci-dessus c'est avec une collection de form selon quasiment l'exemple de la doc de Symfony : je croyais que tu n'en voulais pas ?

                                  Pour la solution que je t'ai proposé qui n'a rien à voir, en fait il suffit juste de poser un EventListener sur le input quantité et cela fait tout ... quantité différente de 0 alors c'est un ajout ou une modif par rapport à une quantité déjà existante. Quantité revient à 0 alors supprimer l'objet déjà existant en base. Inutile de cocher ou décocher les checkbox dans ces cas, cela n'apporte rien. C'est donc vraiment simple me semble t-il : une fonction javascript qui appelle en ajax une fonction sur le serveur.

                                  Mais je ne revendique pas que ma solution soit la seule et encore moins la bonne (ce qui n'a pas non plus beaucoup de sens)

                                  A+

                                  -
                                  Edité par monkey3d 10 juin 2021 à 14:25:00

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    10 juin 2021 à 15:52:25

                                    monkey3d a écrit:

                                    Ton code ci-dessus c'est avec une collection de form selon quasiment l'exemple de la doc de Symfony : je croyais que tu n'en voulais pas ?

                                    Pour la solution que je t'ai proposé qui n'a rien à voir, en fait il suffit juste de poser un EventListener sur le input quantité et cela fait tout ... quantité différente de 0 alors c'est un ajout ou une modif par rapport à une quantité déjà existante. Quantité revient à 0 alors supprimer l'objet déjà existant en base. Inutile de cocher ou décocher les checkbox dans ces cas, cela n'apporte rien. C'est donc vraiment simple me semble t-il : une fonction javascript qui appelle en ajax une fonction sur le serveur.

                                    Mais je ne revendique pas que ma solution soit la seule et encore moins la bonne (ce qui n'a pas non plus beaucoup de sens)

                                    A+

                                    -
                                    Edité par monkey3d il y a environ 1 heure


                                    Salut ! C'était pour répondre à WillyKouassi. Pour ton exemple, Je me renseigne actuellement sur les eventlistener justement, ça me sera utile pour le problème que tu cite "Si la quantité n'est pas renseigné alors pas besoin de cet accessoire".

                                    MattAmsellem a écrit:

                                    Ahh d'accord. Oui tu fais le formulaire comme ça d'accord.

                                    Perso, je trouve cette façon un peu plus compliqué.

                                    Pour remplir ton array avec tout tes accéssoires, tu fais comme cela :

                                    $data = $accessoireRepo->findAll(); // Selon ce que tu veux récupérer
                                    
                                    $array_accessoires = []; // Tu initialises pour avoir l'accès en dehors du foreach
                                    foreach ($data as $accessoire)
                                    {
                                        // Tu mets le string de l'accessoire en clé, et l'entité clé comme valeur associée
                                        $array_accessoires[$accessoire->getNom()] = $accessoire;
                                    }

                                    Tu initialises ton tableau comme ça, puis tu fais le formulaire comme je te l'ai dit. Ce qui donnerai je pense :

                                    // Création du formulaire
                                    $foreach ($array_accessoires as $key, $value)
                                    {
                                       $form->add($key, NumberType::class, [
                                          'required' => false,
                                       ]);
                                    }
                                    
                                    $form->handleRequest($req);
                                    
                                    if ($form->isSubmitted && ...)
                                    {
                                       foreach($array_accessoires as $key, $value)
                                       {
                                          $data_key = $form->get($key)->getData(); // Juste pour éviter de répéter $form->get... Dans la condition
                                          if ($data_key != null && $data_key > 0)
                                          {
                                             $new_echelle_accessoire = new EchelleAccessoire($data_key, $ton_echelle, $value /* qui contient l'entité accessoire associée)*/); 
                                             // Après tu fais instancies ton entité EchelleAccessoire comme toi tu l'as fait hein, moi je ne m'en sers que d'exemple car je ne sais pas comment tu as fait ton entité)
                                             // Puis tu la mets dans ta base de données avec le persist et flush
                                          }
                                       }
                                    }



                                    Je sais pas si du coup ça répond à ta question, mais ça te simplifierai le travail je pense ^^

                                    Là pour le coup je le ferai directement dans le controller, mais je pense que tu peux adapter ma méthode pour le faire dans ton fichier php à pars.

                                    Matt

                                    -
                                    Edité par MattAmsellem il y a environ 3 heures

                                    Ta solution a l'air d'être assez compliqué, je ne suis pas très à l'aise avec tous les foreach que tu m'indique (les $keys). J'attend la reponse de Willy pour voir si ça correspondrais plus à ce que je cherche, mais ce sera une piste à explorer pour moi si je n'ai pas de solutions :)

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      10 juin 2021 à 16:37:00

                                      Tu as une manière bizarre de nommer tes propriétés (début avec majuscule)  , et apparemment tes OneToMany ne sont pas au pluriel (echelleAccessoires ici par exemple) et ton indentation est aussi bizarre, bref soit cohérent dans ton code

                                      Pour revenir à ma proposition

                                      public function AjoutAccessoire(Request $request, int $id, AccessoireRepository $accessoireRepository, EntityManagerInterface $em): Response
                                      {
                                          //Liste des accessoires pour une echelle
                                          $accessoires = $accessoireRepository->findByEchelle($id);
                                          foreach ($accessoires as $accessoire) {
                                             $echelleAccessoire = new EchelleAccessoire();
                                             $echelleAccessoire->setAccessoire($accessoire);
                                             $echelle->addEchelleAccessoire($echelleAccessoire);
                                          }
                                      
                                          $form = $this->createForm(...., $echelle);     
                                      }


                                      Bon tu l'auras remarqué j'ai retiré certaines parties avec ça, tu auras autant de lignes dans ta collection que d'accessoires qui concernent l'échelle.

                                      Dans ta vue, la partie form_widget(accessory.Accessoire) sera une liste déroulante avec une valeur par défaut, tu peux la cacher avec 

                                      <div style="display:none">{{ form_widget(accessory.Accessoire) }}</div>

                                      Et rajouter juste en bas 

                                      {{ accessory.vars.data.Accessoire.nomAccessoire|default('') }}
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      le bienfait n'est jamais perdu
                                        11 juin 2021 à 11:23:12

                                        WillyKouassi a écrit:

                                        Tu as une manière bizarre de nommer tes propriétés (début avec majuscule)  , et apparemment tes OneToMany ne sont pas au pluriel (echelleAccessoires ici par exemple) et ton indentation est aussi bizarre, bref soit cohérent dans ton code

                                        Pour revenir à ma proposition

                                        public function AjoutAccessoire(Request $request, int $id, AccessoireRepository $accessoireRepository, EntityManagerInterface $em): Response
                                        {
                                            //Liste des accessoires pour une echelle
                                            $accessoires = $accessoireRepository->findByEchelle($id);
                                            foreach ($accessoires as $accessoire) {
                                               $echelleAccessoire = new EchelleAccessoire();
                                               $echelleAccessoire->setAccessoire($accessoire);
                                               $echelle->addEchelleAccessoire($echelleAccessoire);
                                            }
                                        
                                            $form = $this->createForm(...., $echelle);     
                                        }


                                        Bon tu l'auras remarqué j'ai retiré certaines parties avec ça, tu auras autant de lignes dans ta collection que d'accessoires qui concernent l'échelle.

                                        Dans ta vue, la partie form_widget(accessory.Accessoire) sera une liste déroulante avec une valeur par défaut, tu peux la cacher avec 

                                        <div style="display:none">{{ form_widget(accessory.Accessoire) }}</div>

                                        Et rajouter juste en bas 

                                        {{ accessory.vars.data.Accessoire.nomAccessoire|default('') }}

                                        Salut ! J'ai peur de ne pas comprendre ta solution : Dans ton exemple tu attribue des accessoires à l'échelle avant de faire le form. Le but de mon code est justement de savoir quels accessoires l'utilisateur souhaite associer à l'échelle. Je ne te suis pas. De même pour le {{ accessory.vars.data........ }} Ici ce n'est que le nom, il n'y a pas de quantité à rajouter dans le twig ?
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          14 juin 2021 à 15:30:40

                                          Je fais juste une initialisation de la collection, si tout se passe bien, tu auras autant de lignes que d'accessoires dans ta vue et à l'utilisateur de faire le choix. Tu peux te passer des checkbox, une quantité non renseignée ou zéro peut être considérée comme non associée à l'échelle.

                                          Dans mon code au lieu de findBy , utilise plutôt findAll . Le {{ accessory.vars.data }} c'est pour juste afficher un libellé , je n'ai pas retiré le champ quantité

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          le bienfait n'est jamais perdu

                                          [Symfony 5] Propriété portée ajout avec Entitytype

                                          × 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