Partage
  • Partager sur Facebook
  • Partager sur Twitter

Php dans Twig pour faire une condition ?

Symfony 4 et Twig

Sujet résolu
2 octobre 2019 à 10:09:39

C'est parce qu'il faut mettre un antislash devant, sinon il cherche dans l'espace de nom courant, (Il me semblait pourtant qu'il remontait automatiquement jusqu'à la racine en cas de besoin…)

Tu ne peux pas modifier cette requête, c'est Doctrine qui s'occupe de la générer quand tu effectues persist($location); flush(). Comme l'ordre importe peu, il faudra plus se concentrer sur le fait qu'apparemment il y a une valeur mal renseignée dans ton objet.

  • Partager sur Facebook
  • Partager sur Twitter
2 octobre 2019 à 11:35:39

Alors il ne me récupère pas le nombre de balises louées, est-ce que cela vient du fait que j'ai fait un input normal au lieu de prendre celui de Twig ?

 <div class="col-md-2"><input type="text" id="nbLoue" class="form-control" name="nbLoue" value="3"></div>

J'ai fait un input normal car j'avais besoin de lui donner un name pour récupérer l'information et la comparer à la valeur que je récupère avec ma requête.

Apparement il ne récupère pas l'id du loueur que je sélectionne. Ce qui est normal vu que je ne l'ai pas géré.

Je crée ma liste en js de cette façon :

function choiceList() {

                var table = document.getElementById("liste");

                for (var k = 0; k < listeObjects.length; k++) {
                    var id = listeObjects[k].id;
                    var nom = listeObjects[k].nom;
                    var cp = listeObjects[k].cp;
                    var ville = listeObjects[k].ville;
                    var distance = listeObjects[k].distance;
                    var nbDispo = listeObjects[k].nb;

                    var row = table.insertRow(k);
                    var cell1 = row.insertCell(0);
                    var cell2 = row.insertCell(1);

                    cell1.innerHTML = '<input type=radio name=choiceLoueur[] id=choiceLoueur value=' + id + '>';
                    cell2.innerHTML = '<label for=' + id + '>' + nom + '<br>' + cp + ' ' + ville + ' - ' + nbDispo + ' dispo' + '<br></label>';
                }
            }

Et dans mon twig :

 <table >
<tbody id="liste">
</tbody> 
</table>

Je dois gérer ou la selection ?

Et pour la valeur du dernier élément, elle s'incrémente toute seule donc j'en déduis que c'est bien l'id de l'utilisateur


-
Edité par ElodieMartin13 2 octobre 2019 à 14:13:12

  • Partager sur Facebook
  • Partager sur Twitter
2 octobre 2019 à 12:56:57

ElodieMartin13 a écrit:

Alors il ne me récupère pas le nombre de dial loués, est-ce que cela vient du fait que j'ai fait un input normal au lieu de prendre celui de Twig ?

Oui. Le nom donné par Symfony au champ de formulaire est prévu pour pouvoir récupérer correctement la donnée lors de handleRequest(). Il vaudrait mieux que tu adaptes ton JavaScript à ce nom qu'adapter le HTML à ton JavaScript.

La variable listeObjects, elle contient quoi ?

  • Partager sur Facebook
  • Partager sur Twitter
2 octobre 2019 à 13:58:01

La variable listeObjects :

liste (7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {id: "18", nom: "BANDOL - GRAND VALLAT", cp: "83150", ville: "BANDOL", latitude: 33.13933, …}
1: {id: "19", nom: "BANDOL - PLAGE DU CASINO", cp: "83150", ville: "BANDOL", latitude: 33.13758, …}
2: {id: "17", nom: "BANDOL - CENTRAL", cp: "83150", ville: "BANDOL", latitude: 33.13651, …}
3: {id: "20", nom: "BANDOL - RENÉCROS", cp: "83150", ville: "BANDOL", latitude: 33.13481, …}
4: {id: "68", nom: "LA LONDE - PLAGE MIRAMAR", cp: "83250", ville: "LA LONDE-LES-MAURES", latitude: 33.11538, …}
5: {id: "69", nom: "LA LONDE - TAMARIS", cp: "83250", ville: "LA LONDE-LES-MAURES", latitude: 33.11738, …}
6: {id: "67", nom: "LA LONDE - PLAGE DE L'ARGENTIÈRE", cp: "83250", ville: "LA LONDE-LES-MAURES", latitude: 33.12062, …}
length: 7__proto__: Array(0)

Par contre je n'ai plus d'erreurs mais ca ne s'enregistre pas en base.

Je viens de remarquer que la requête enregistre l'id du client mais je n'ai pas vu de paramètres pour les infos du client.

Est-ce que je dois faire un truc comme ca ?

public function form(Location $loc = null, Utilisateur $util, Request $request, ObjectManager $manager) {
        
        dump($request);
       
        $loc = new Location();
        $util = new Utilisateur();

        $form = $this -> createForm(LocationType::class, $loc);
        $form -> handleRequest($request);

        $formUtil = $this -> createForm(LocationType::class, $util);
        $formUtil -> handleRequest($request);

        if ($form->isSubmitted() && $form->isValid() && $formUtil->isSubmitted() && $formUtil->isValid()) {

            $manager->persist($loc, $util);
            $manager->flush();

            return $this->redirectToRoute('home');
        }

        return $this->render('loc/index.html.twig', [
            'controller_name' => 'LocController',
            'formLoc' => $form->createView(),
          
        ]);
    }




-
Edité par ElodieMartin13 2 octobre 2019 à 14:12:38

  • Partager sur Facebook
  • Partager sur Twitter
2 octobre 2019 à 14:02:56

:D pour le coup, je voulais juste une explication, pas un exemple.

Mais j'avais peur que ce soient des objets DOM.

  • Partager sur Facebook
  • Partager sur Twitter
2 octobre 2019 à 15:24:07

Ymox a écrit:

:D pour le coup, je voulais juste une explication, pas un exemple.

Mais j'avais peur que ce soient des objets DOM.


Tu es rassuré ?
  • Partager sur Facebook
  • Partager sur Twitter
2 octobre 2019 à 15:46:06

Oui.

Juste une chose : quand tu vois qu'il y a eu des réponses après que tu aies édité ton message pour ajouter des informations, supprime-les du message que tu as édité et mets-les dans une nouvelle réponse, c'est pas facile de suivre ensuite — surtout si tu changes carrément la réponse, auquel cas il faudrait revenir au message tel qu'il était avant qu'on lui réponde…

ElodieMartin13 a écrit:

Je viens de remarquer que la requête enregistre l'id du client mais je n'ai pas vu de paramètres pour les infos du client.

Si c'est un client existant pour la location, ça me paraît normal, un client est représentable par son ID, c'est d'ailleurs ce qui est utilisé par Doctrine pour les relations entre entités.
Si en revanche c'est pour un nouveau client, attention, le traitement devra être différent.

ElodieMartin13 a écrit:

Est-ce que je dois faire un truc comme ca ?

Pas nécessairement. Si tu ne souhaites pas devoir mettre à la main $location-&gt;setDateDebutLoc(…) et ainsi de suite pour chaque champ du formulaire (ce qui pourrait être la solution la plus simple, mais pas celle qui utiliserait tirerait le plus parti des outils de Symfony), oui, il faudrait faire un truc comme ça. Seulement, il faudra que les données de la requête soient envoyées "avec la bonne architecture".

-
Edité par Ymox 3 octobre 2019 à 14:40:35

  • Partager sur Facebook
  • Partager sur Twitter
2 octobre 2019 à 16:09:52

Oui ce sont de nouveaux clients. Le système n'a pas été pensé pour des clients existants étant donné qu'il n'y a pas d'enregistrement de clients ni de système de connexion à un espace client.

Comment doit être fait le traitement ?

Et dans le cas ou je souhaite utiliser les outils de symfony comme j'ai fait pour créer une nouvelle location. Comment je fais pour créer un nouvel utilisateur ? Je pensais que ca se ferait tout seul étant donné que j'ai inclu l'utilisateur dans le formulaire location. C'est un formulaire qui inclu deux entités.

  • Partager sur Facebook
  • Partager sur Twitter
3 octobre 2019 à 15:11:26

Le hic, c'est que le formulaire qui est généré par Symfony puis affiché avec Twig possède des attributs name précis, faisant que lors de la soumission les données sont structurées d'une manière proche de celle qu'on rencontrerait avec les objets, mais là sous forme de tableau. Et c'est sur cette structure que handleRequest() se base pour effectuer la liaison des données de la requête avec "l'entité mère".

Dans l'idéal, plutôt que de récupérer les valeurs de champs une à une, sérialise l'entier du formulaire. Tu trouveras des méthodes sur cette page notamment. Une autre version pour soumettre un formulaire par AJAX est disponible ici.

  • Partager sur Facebook
  • Partager sur Twitter
3 octobre 2019 à 15:27:29

EDIT : Alors on reprend tout car en fait j'ai rien compris.

Le serializeArray() si je comprends bien c'est pour renvoyer sous forme de tableau les valeurs d'un form sous Ajax.

Sauf que la valeur que je veux récupérer en JS n'est pas dans un formulaire mais dans un simple input.

function choiceList() {

                var table = document.getElementById("liste");

                for (var k = 0; k < listeObjects.length; k++) {
                    var id = listeObjects[k].id;
                    var nom = listeObjects[k].nom;
                    var cp = listeObjects[k].cp;
                    var ville = listeObjects[k].ville;
                    var distance = listeObjects[k].distance;
                    var nbDispo = listeObjects[k].nb;

                    var row = table.insertRow(k);
                    var cell1 = row.insertCell(0);
                    var cell2 = row.insertCell(1);

                    cell1.innerHTML = '<input type=radio name=choiceLoueur[] id=choiceLoueur value=' + id + '>';
                    cell2.innerHTML = '<label for=' + id + '>' + nom + '<br>' + cp + ' ' + ville + ' - ' + nbDispo + ' dispo' + '<br></label>';
                }
                
            }

J'ai trouvé ca : 

cell1.innerHTML = $('choiceLoueur :input').serializeArray();

Ca peut marcher ?

-
Edité par ElodieMartin13 4 octobre 2019 à 11:08:47

  • Partager sur Facebook
  • Partager sur Twitter
3 octobre 2019 à 16:41:04

J'en doute, serializeArray() ne va pas générer la bonne structure, c'est vraiment serialize() qui serait le plus adapté. Mais tout ça c'est uniquement si tu as un formulaire pour ton client.

A mon tour de ne plus te suivre. Tu nous parles de formulaire, mais « la valeur que je veux récupérer en JS n'est pas dans un formulaire mais dans un simple input ». Tu as une liste de clients, mais tu veux en saisir un nouveau.

  • Partager sur Facebook
  • Partager sur Twitter
3 octobre 2019 à 16:59:44

Une copie d'ecran sera plus parlante je pense.

La partie haute et basse est gerée par le builder. La partie centrale est gérée par le JS. Il faut que je récupère l'id du bouton radio et que je le fasse passer au handleRequest() pour persister la donnée en base.

C'est plus clair ?

-
Edité par ElodieMartin13 3 octobre 2019 à 17:00:21

  • Partager sur Facebook
  • Partager sur Twitter
3 octobre 2019 à 17:12:36

OK, alors la possibilité la plus simple que je verrais serait d'adapter ton JavaScript qui insère ces boutons radio pour avoir le name correct — si tu as besoin d'aide à ce propos, il nous faudra celui de heureDebutLoc par exemple — et tu soumets en AJAX le formulaire.

J'ai un script qui gère la soumission d'un formulaire en AJAX avec jQuery comme exemple, si jamais. Il est prévu pour gérer la soumission dans une modale et traiter des retours de manière particulière ainsi que pour lier un comportement si le retour contient une zone de texte par exemple, tu pourras nettoyer tout ça.

Au passage, au temps pour moi, j'utilise effectivement serializeArray(), et pas simplement serialize().

  • Partager sur Facebook
  • Partager sur Twitter
4 octobre 2019 à 9:16:59

RE EDIT :

J'ai fait ceci

 function choiceList() {

                var table = document.getElementById("liste");

                for (var k = 0; k < listeObjects.length; k++) {
                    var id = listeObjects[k].id;
                    var nom = listeObjects[k].nom;
                    var cp = listeObjects[k].cp;
                    var ville = listeObjects[k].ville;
                    var distance = listeObjects[k].distance;
                    var nbDispo = listeObjects[k].nb;

                    var row = table.insertRow(k);
                    var cell1 = row.insertCell(0);
                    var cell2 = row.insertCell(1);

                    cell1.innerHTML = '<input type=radio name=location[loueur] id=choice_loueurs'+ id +" " + 'value=' + id + '>';
                    cell2.innerHTML = '<label for=location_loueur' + id + '>' + nom + '<br>' + cp + ' ' + ville + ' - ' + nbDDispo + 'dispo' + '<br></label>';
                   
                }   
            
                var rad = document.getElementsByName("location[loueur]");
                //console.log(rad);
                var prev = null;
                for (var i = 0; i < rad.length; i++) {
                    rad[i].addEventListener('click', function() {
                        (prev) ? console.log(prev.value): null;
                        if (this !== prev) {
                            prev = this;
                        }
                        document.getElementById("location_loueur").innerHTML = '<option value=' + this.value + '>' + this.value + '<option>';
                        document.getElementById("location_loueur").value = this.value;
                        //console.log(this.value)    
                    });
}
            }



Apparement je récupère bien l'id du loueur.

Ensuite j'ai rajouté à mon formulaire le champs, qui est l'id du loueur :

->add('loueurs', EntityType::class, array(
                'class' => Location::class,
                'required' => false))

Je l'ai mis en champ caché dans mon Twig :

<div class="row">
        <div class="col-md-4"> {{ form_widget(formLoc.loueurs,  { 'attr' : { 'style':'display:none'} }) }} </div>

Apparement je la fais bien passé au champ caché :




J'ai plusieurs choses qui ne sont pas normales :

1 - Le select s'auto-rempli toujours ainsi à chaque chargement du formulaire alors que je n'ai pas encore fait afficher de loueur

2 - Et des requêtes se font alors que je n'ai pas cliquer sur le bouton valider :

-
Edité par ElodieMartin13 7 octobre 2019 à 10:42:16

  • Partager sur Facebook
  • Partager sur Twitter
6 octobre 2019 à 22:17:52

  1. Ce n'est pas une bonne pratique de faire ainsi. Comment récupères-tu l'ID du loueur à mettre dans ton formulaire ? Ne pourrais-tu pas le récupérer de la même manière pour l'ajouter à l'entité une fois que le formulaire est soumis et validé, sans qu'il ne re-transite par le client ? Parce que justement, ça fait une donnée de plus à vérifier si c'est la bonne. Or, si cette donnée est en session, mieux vaut l'enregistrer "au dernier moment". Si l'utilisateur peut la choisir, pourquoi ne pas permettre de le faire sur la même page ?
  2. C'est probablement normal, il doit y avoir des éléments qui ont besoin de certaines informations lorsque la page est générée. Il nous faudrait l'entier du code qui fait s'afficher la page du formulaire pour mieux expliquer. Et si ton entité utilisateur est liée d'une manière ou d'une autre aux balises, peut-être que c'est une des explications.
  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 10:31:03

Bonjour Ymox,

Comment récupères-tu l'ID du loueur à mettre dans ton formulaire ? 

La récupération de l'id Loueur est faite à la fin de la fonction choiceList(), premier code de mon message précédent.

Ne pourrais-tu pas le récupérer de la même manière pour l'ajouter à l'entité une fois que le formulaire est soumis et validé, sans qu'il ne re-transite par le client ?

Ce que j'ai voulu faire, c'est récupérer l'id du Loueur puis je l'ai transmis grâce au getElementById au champ du formulaire Twig que j'ai mis en caché.

Si l'utilisateur peut la choisir, pourquoi ne pas permettre de le faire sur la même page ?

L'utilisateur choisit le loueur en cochant le bouton radio et tout se fait sur la meme page.

Il nous faudrait l'entier du code qui fait s'afficher la page du formulaire pour mieux expliquer.

 /**
     * @Route("/loc", name="loc")
     */
    public function form(Location $loc = null, Request $request, ObjectManager $manager) {
        
        dump($request);
       
        $loc = new Location();

        $form = $this -> createForm(LocationType::class, $loc);
        $form -> handleRequest($request);

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


            $manager->persist($loc);
            $manager->flush();

            return $this->redirectToRoute('home');
        }

        return $this->render('loc/index.html.twig', [
            'controller_name' => 'LocController',
            'formLoc' => $form->createView(),
          
        ]);
    }


Le code JS qui va rechercher les loueurs n'est lancé que lorsqu'on clic sur search. A l'affichage du formulaire la carte et le liste ne s'affiche pas.

-
Edité par ElodieMartin13 7 octobre 2019 à 10:43:42

  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 12:17:44

Une des requêtes vient du fait que le EntityType "caché" (en CSS — pour moi un champ caché c'est un type="hidden") doit être rempli de la liste complète des loueurs.

Attention : pour la valeur d'un <input />, c'est l'attribut value de la balise auto-fermante qui est utilisé, pas un texte placé entre les balises ouvrante et fermante comme tu l'illustres. Après, peut-être que c'est une manière de ton navigateur pour afficher ça, mais c'est trompeur.

Je ne comprends pas pourquoi il faut un champ caché pour l'ID du loueur. Si tu as des boutons radio avec les bons attributs name (ce qui semble être le cas), pas besoin d'aller mettre la valeur dans un autre champ. C'est certes un peu moins pratique pour aller chercher la valeur choisie, mais il n'y a pas besoin de recréer un champ supplémentaire alors que, quel que soit son type, s'il existe au moins un champ avec le même name, il est considéré comme existant déjà, et la dernière valeur remplacera la première — sauf en cas de champ où plusieurs valeurs sont possibles.

J'ai cru comprendre que la liste des loueurs s'affichait dynamiquement. J'imagine que tu souhaites qu'elle soit vide tant que tu n'as pas choisi les dates et heures de location ?
Dans ce cas, je te propose de changer quelques paramètres de ton EntityType pour les loueurs : on va lui mettre 'expanded' => true pour avoir toute une liste des loueurs sous forme de case à cocher (il faudra déplacer ce "champ caché" là où tu as mis tes boutons radio). En JavaScript, quand mets l'écouteur d'événements sur le click du bouton SEARCH (oui, avant l'événement et non uniquement dedans), tu vas supprimer toutes ces cases à cocher qui seront par défaut affichées. Le reste va se comporter de la même manière que maintenant, à ceci près que tu pourras récupérer le choix directement depuis les boutons radio.
Pour l'instant, à chaque erreur, le formulaire se réaffichera avec la liste complète des loueurs, mais le choix sera conservé. A voir quel comportement tu souhaites, suivant comment on va devoir passer par un FormEventListener pour conserver la liste restreinte.

-
Edité par Ymox 7 octobre 2019 à 12:21:32

  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 12:52:56

Le fonctionnement actuel :

La liste de l'affichage dynamique est vide à l'affichage du formulaire. Par contre l'id loueur il y a 3 loueurs alors que la liste en contient plus de 200 et il y a un doublon. Dois-je faire tout ce que tu expliques dans ton dernier paragraphe du coup ?

Si j'ai rajouté le champs twig id Loueur c'est parce que je me suis aperçue que même en donnant le même name et le même id que Twig, la requête ne prenait pas la valeur en compte (test fait sur le champs nb de balise).

Attention : pour la valeur d'un <input />, c'est l'attribut value de la balise auto-fermante qui est utilisé, pas un texte placé entre les balises ouvrante et fermante comme tu l'illustres. Après, peut-être que c'est une manière de ton navigateur pour afficher ça, mais c'est trompeur.

J'utilise chrome en navigateur. Du coup ca signifie qu'il n'est pas récupéré ? Je pensais que si vu que la valeur change chaque fois que je clic mais tu dois avec raison puisque la requête considère la valeur null ! Du coup qu'est ce qui ne va pas dans mon code ?

-
Edité par ElodieMartin13 7 octobre 2019 à 12:53:55

  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 13:09:05

En fait, tu as besoin du champ loueur avec EntityType, sans quoi Symfony ne pourra effectivement pas lier la demande de location avec le loueur correctement. Seulement, avec ce que tu as, je serais plus pour l'utiliser un peu différemment que ce que tu fais actuellement, et oui, je te propose l'avant-dernier paragraphe du message précédent, premier de la dernière section.

Pour ce qui est de l'affichage de la valeur et du navigateur, cela explique très probablement que celle-ci n'est pas récupérée. Attention cependant : je ne crois pas qu'il y ait de navigateur qui mette à jour ce qu'on voit quand on change la valeur d'un champ, on ne peut donc pas se baser là-dessus.

  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 13:59:15

Ymox a écrit:

En fait, tu as besoin du champ loueur avec EntityType, sans quoi Symfony ne pourra effectivement pas lier la demande de location avec le loueur correctement. Seulement, avec ce que tu as, je serais plus pour l'utiliser un peu différemment que ce que tu fais actuellement, 

Faire différement c'est à dire ? 

Pour ce qui est de l'affichage de la valeur et du navigateur, cela explique très probablement que celle-ci n'est pas récupérée. 

Une idée d'ou vient le problème dans mon code ?

  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 14:26:28

ElodieMartin13 a écrit:

Faire différement c'est à dire ?

Ymox a écrit:

[…] je te propose l'avant-dernier paragraphe du message précédent, premier de la dernière section.

Je note cependant à l'instant que tu as les attributs qui contiennent loueurs au pluriel. Si tu as bien une relation *(Location)ToMany(Loueur), il nous faudra encore autre chose. Si non, c'est là qu'on peut voir que les pluriels inutiles ne sont pas de très bonnes idées.  :D

ElodieMartin13 a écrit:

Une idée d'ou vient le problème dans mon code ?

Probablement de ce que tu ajoutes des balises <option> à une balise <input>, en fait. Ce qui explique aussi que la valeur se retrouve comme un nœud dans la balise <input>.

-
Edité par Ymox 7 octobre 2019 à 14:26:58

  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 15:36:41

Alors pour le pluriel je plaide coupable, j'avais mis une relation manyToMany alors que c'était un OneToMany, du coup il reste peut être des erreurs.

En fait on ne peut louer une balise qu'à un seul loueur.

Suite aux changement que tu m'as dit, voici le résultat. (J'ai mis le champ censé être en caché en visible pour les tests) Il y a bien une liste, mais c'est toujours la même.

Voici mon entityType si j'ai bien compris ce que tu m'as dis :

   ->add('nbLoue')
            ->add('loueur', EntityType::class, array(
                'class' => Location::class,
                'expanded' => true,
                'required' => false))
            ->add('save', SubmitType::class, array('label' => 'Louer une balise'))

Le champ au même endroit que l'affichage de ma liste js :

  <table>
        <tr>  
            <td border="1px, solid, black">
                <form action=" " method="POST">
                    <table >
                        <tbody id="liste">
                         <!-- Ici s'affichera la liste des loueurs à proximité de la ville -->
                         <div class="row">
                            <div class="col-md-4"> {{ form_widget(formLoc.loueur) }} </div>   
                        </div> 
                        </tbody> 
                    </table>
                </form>
            </td>
            <td>
                <div id="map">
                        <!-- Ici s'affichera la carte -->
                </div>
            </td>
        </tr>
    </table>

L'affichage suite à la sélection d'un loueur :

fL'option a bien une value :


Mais elle n'est toujours pas reconnue par la requête :



L'option est ajouté à la balise select du champs idLoueur géré par Twig

  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 15:48:16

ElodieMartin13 a écrit:

->add('loueur', EntityType::class, array(
    'class' => Location::class,
    'expanded' => true,
    'required' => false))

Ça ne te gêne pas de dire que ton champ Location#loueur contient des locations ? C'est pourtant ce que tu dis avec la seconde ligne… Le paramètre 'class' est pour dire quelle entité sera utilisée par le champ, pas par le formulaire dans lequel se trouve ledit champ.  ^^

Le champ caché que tu as mis en visible, dans mon idée, il devrait remplacer la liste que tu as à côté de la carte. Plus besoin de le cacher ni de le remplir avec du JavaScript, vu que la valeur est déjà choisie par l'utilisateur par le biais des boutons radio.

-
Edité par Ymox 7 octobre 2019 à 15:51:29

  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 16:16:12

Ymox a écrit:

Ça ne te gêne pas de dire que ton champ Location#loueur contient des locations ? C'est pourtant ce que tu dis avec la seconde ligne… Le paramètre 'class' est pour dire quelle entité sera utilisée par le champ, pas par le formulaire dans lequel se trouve ledit champ.  ^^

Ben je crois que l'on est sur la même longueur d'onde. J'ai voulu dire "l'attribut loueur" que l'on trouve dans l'entité "Location".

/**
     * @ORM\OneToOne(targetEntity="App\Entity\Loueur", inversedBy="locations")
     * @ORM\JoinColumn(nullable=false)
     */
    private $loueur;

Et vu que j'ai mis un OneToOne, une location a un seul loueur.

Tu sais quoi ? Tu m'as encore perdue du coup !

Le champ que j'ai mis en caché ne comporte que l'id du Loueur.

La liste que j'ai sur le côté comporte les boutons radios, donc si je l'enlève pour ne laisser que le champ id Loueur, mon utilisateur ne pourra plus faire de choix  :(



  • Partager sur Facebook
  • Partager sur Twitter
7 octobre 2019 à 16:58:45

Je maintiens qu'entre :

  • le code de l'entité Location que tu mentionnes ci-dessus (où tu dis avec les mappings targetEntity="App\Entity\Loueur" que la propriété Location#loueur est un objet Loueur)
  • et le code de LocationType (code que j'ai cité deux messages plus haut, et où tu dis avec le paramètre 'class' => App\Entity\Location::class que la même propriété va contenir un objet Location)

il y a quelque chose qui ne joue pas.

Mais il y a autre chose qui doit m'échapper. Les deux fois tu fournis un affichage avec la liste des balises et la carte, et tu dis que ça s'affiche après la sélection d'un loueur. Il n'y a donc pas que le choix des dates et heures de début et de fin de location qui influe sur la liste de balises, il y a aussi un choix de loueur, et ici par loueur on ententd propriétaire de balise ?

Je crois qu'il me faudrait que tu réexpliques en français non technique ce que l'utilisateur doit pouvoir faire/ce qu'il doit se passer.
Comme si tu parlais à quelqu'un qui ne connaît rien à PHP ni en HTML.

-
Edité par Ymox 7 octobre 2019 à 17:26:17

  • Partager sur Facebook
  • Partager sur Twitter
8 octobre 2019 à 11:17:17

Merci d'être si patient. J'ai compris que j'avais mal compris à quoi servait le paramètre class. Je croyais qu'il fallait que je lui dise à quelle entité il appartenait alors que je devais lui dire à quelle entité il renvoyait.

Du coup maintenant l'enregistrement de la location et de l'utilisateur se fait bien en base. Il manque une dernière chose, c'est lorsque je choisis le loueur, il faut que je liste les balises disponibles et fonctionnelles du loueur et que le système en attribue le nombre demandé par l'utilisateur.

Ou est-ce que je dois gérer ca stp ?

  • Partager sur Facebook
  • Partager sur Twitter
8 octobre 2019 à 11:23:29

Ça, c'est un peu plus complexe à mon avis. Je vois deux possibilités :

  1. au choix d'un loueur, tu lances une nouvelle requête AJAX qui te retourne les informations des balises, et tu génères la carte à ce moment-là ;
  2. quelque part dans les attributs du bouton radio ou du <label>, on met les informations sur les balises sous forme de JSON, mais ça implique de les avoir déjà lors du rendu des boutons radio, avec tout ça je ne sais plus si c'est le cas.
Edit

Pour ce qui est de l'attribution, ça devrait se passer comment ? On prend ce qu'il y a de libre tant qu'il y en a, et c'est tout, ou il y a un processus plus subtil ?

-
Edité par Ymox 8 octobre 2019 à 11:31:50

  • Partager sur Facebook
  • Partager sur Twitter
8 octobre 2019 à 11:49:48

Choix 1 : La carte doit s'afficher au moment ou la liste apparait afin que l'utilisateur puisse visualiser l'emplacement des différents loueurs et faire un choix. Une fois que le choix a été fait la carte n'a plus d'utilité.

L'attribution des balises doit passer inapercu pour l'utilisateur.

Choix 2 : Dans la requête on a récupéré l'id des balises puisqu'on les compte mais ensuite on regroupe par loueur, du coup je ne sais pas si les id sont conservés.

 $query = $this->createQueryBuilder('lou'); 
        $query  -> select('PARTIAL lou.{id, nom, cp, ville, latitude, longitude}')
                -> addSelect($query->expr()->count('bal.id') . ' AS nb_balises')
                -> leftJoin('lou.balise', 'bal')
                -> leftJoin('bal.locations',
                            'loc',
                            \Doctrine\ORM\Query\Expr\Join::WITH,
                                $query->expr()->orX(
                                    $query->expr()->between(':dateDebutLoc', 'loc.dateDebutLoc', 'loc.dateFinLoc'),
                                    $query->expr()->between(':dateFinLoc', 'loc.dateDebutLoc', 'loc.dateFinLoc')
                                ))

                -> where($query->expr()->eq('bal.fonctionnel', $query->expr()->literal(true)))
                -> andWhere($query->expr()->isNull('loc.dateDebutLoc'))
                -> groupBy('lou.id')
                -> setParameter ('dateDebutLoc', $dateDebutLoc)
                -> setParameter ('dateFinLoc', $dateFinLoc);
        $results = $query -> getQuery() -> getResult();


Pour l'attribution il n'y a pas de règle spécifique, on prend une balise libre et fonctionnelle dans la liste. Et on en attribut autant que l'utilisateur en a loué. Puis on l'enregistre en base de données.

-
Edité par ElodieMartin13 8 octobre 2019 à 14:05:50

  • Partager sur Facebook
  • Partager sur Twitter
8 octobre 2019 à 11:58:54

OK, donc ce ne sont pas les balises qui s'affichent, mais les loueurs, j'avais mal compris.

Du coup, cette histoire de répartition peut se faire dans le contrôleur, après validation du formulaire et avant persistance de la location. Tu récupères les balises du loueur, tu boucles dessus autant de fois que souhaité et tu as de quoi attribuer. Pour la requête, elle sera très similaire à ce que tu as déjà fait pour avoir les loueurs libres et leur nombre, simplement il n'y aura plus de regroupement par loueur et tu as l'ID de ce dernier comme paramètre supplémentaire.

Question cependant : le nombre de balises, si le loueur n'en a pas assez, tu fais comment ? Actuellement tu filtres quand même pour n'afficher que les loueurs qui ont assez de balises libres, ou non ? Si oui, tu filtres à quel moment/par quel moyen ?

  • Partager sur Facebook
  • Partager sur Twitter
8 octobre 2019 à 14:05:31

Ok, donc je fais ma requête dans le controller, dans mon if et avant le manager->persist(loc), c'est bien celà ?

 public function form(Location $loc = null, Request $request, ObjectManager $manager) {
        
        dump($request);
       
        $loc = new Location();

        $form = $this -> createForm(LocationType::class, $loc);
        $form -> handleRequest($request);

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


            $manager->persist($loc);
            $manager->flush();

            return $this->redirectToRoute('home');
        }

        return $this->render('loc/index.html.twig', [
            'controller_name' => 'LocController',
            'formLoc' => $form->createView(),
          
        ]);
    }


Je gère la vérification de la quantité dans mon js, et seuls les loueurs ayant assez de quantités disponibles apparaissent dans la liste avec les boutons radios.

  • Partager sur Facebook
  • Partager sur Twitter