IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Requete Ajax sur onclick


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2009
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 109
    Par défaut Requete Ajax sur onclick
    Salut a tous,

    Je compte mettre en place un menu latéral hiérarchisé dans mon application ( idem a une arbo de fichier windows). J'aimerais que lorsqu'on clic sur un nœud de la hiérarchie, ses fils soient déroulés via une requête ajax.

    Le souci : Je débute en JS et en AJAX. J'ai lu la partie integration d'ajax sur symfony mais elle ne m'aide pas tellement.

    Je vous post les codes déjà créés, hésitez pas a me dire ce qui va pas tant au niveau syntaxe que concept.

    Affichage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	<li><a href="<?php echo url_for('Entreprise/index') ?>" >Liste des entreprises</a></li>
    		<ul>
    			<?php  foreach ($liste_entreprise as $entreprise) : ?>
    				<li><a href="<?php echo url_for('Entreprise/edit?id='.$entreprise->getId()) ?>" onclick="menu_ajax('<?php echo $entreprise->getId(); ?>','site') "><?php  echo $entreprise->getNom() ; ?> </a></li>
    			<?php endforeach ; ?>	
    		</ul>
    Fichier JS : Il doit sans doute manquer pas mal d'info, mais j'aimerai faire parvenir l'id et la table a dérouler à mon action MenuAjax du module : displayElements.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function menu_ajax(id,table)
    {
        $.post("displayElements/MenuAjax",  {myParam : id} , {myTable : table}  );
    }

    L'action (enfin il s'agit d'un component mais ca fonctionne pareil d'apres la doc) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
      public function executeMenuAjax() 
      {
        if ($request->isXmlHttpRequest())
        {
            $id = $request->getParameter('myParam');
            $table = $request->getParameter('myTable');
     
            if ($table == "site")
            {
            	$this->sites = Doctrine_Core::getTable('Site')
          			->createQuery('a')
          			->where("entreprise_id = $id")
          			->execute();
            }
            return $this->renderText($this->sites);
        }
      }
    Je voudrais comprendre ce qu'il me manque tant au niveau syntaxe qu'au niveau concept pour transférer les infos nécessaire au chargement des fils du nœud du menu. En l’occurrence : les fils de l’entreprise sont des sites.

    Merci d'avance

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Par défaut
    si tu fait le onclick sur un lien avec une url correcte, ta page va se charger et ajax va s'executer trop tard non?

    Mauvaise syntaxe de post sinon, c'est:
    Code jQuery : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $.post("<?php echo url_for("module/action")?>",
           {param1: value1, param2: value2},
           function(data){ /* ici tu t'amuses avec ton data fraichement retourné*/ }
    );

  3. #3
    Membre confirmé
    Inscrit en
    Octobre 2009
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 109
    Par défaut
    Citation Envoyé par gototog Voir le message
    si tu fait le onclick sur un lien avec une url correcte, ta page va se charger et ajax va s'executer trop tard non?

    Citation Envoyé par Maerlyn31
    Laquelle veux-tu atteindre exactement ? En allant un peu plus loin, quelles sont les routes associées a ces deux URL ?
    Effectivement, je deux URL c'est pas bon, je garde donc celle du onclick.
    Celle du on click : "displayElements/MenuAjax" donne sur le module : DisplayElements, et sur le component MenuAjax voici sa structure :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class displayElementsComponents extends sfComponents
    {
      public function executeMenu()
      {
          ...
      }
     
      public function executeMenuAjax() 
      {
         ...
      }
    Citation Envoyé par Maerlyn31
    De plus, la fonction $POST ne fait qu'envoyer une requête, sans en gérer le retour
    Exact, et là j'ai un souci de comprehension, imaginons que le retour est une collection doctrine contenant la liste des sites que je veux afficher. Comment organiser l'affichage retour. Au départ je pensais mettre un span apres la lien onclick , qui accueillerait le retour, mais comment faire le foreach qui va bien ? ( sachant que les sites aussi devront etre onclick(able).

    Merci de votre réactivité en tout cas.

  4. #4
    Membre confirmé
    Inscrit en
    Octobre 2009
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 109
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function menu_ajax(id,table)
    {
    	$.post("displayElements/MenuAjax",  {myParam : id, myTable: table}, function(data) { 
    	     $('#fils').html(data);
    	     } );
    }
    Et là je ne vois pas trop comment gerer le retour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <?php  foreach ($liste_entreprise as $entreprise) : ?>
    	<li><a href="" onclick="menu_ajax('<?php echo $entreprise->getId(); ?>','site') "><?php  echo $entreprise->getNom() ; ?> </a></li>
    	<span id="fils">
    		Comment faire le forech dans le data ? 
    	</span>
    <?php endforeach ; ?>

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Par défaut
    Au départ je pensais mettre un span apres la lien onclick , qui accueillerait le retour, mais comment faire le foreach qui va bien ?
    J'aurai fait comme toi.
    J'utilise des actions pour Ajax, je fais le foreach dans le template de l'action (ajaxMenuSuccess par exemple) et je renvoie tout ca que j'foure dans un span.


    (par contre j'ai pas de return ducoup dans mon action, je passe directement dans le template une fois ma collection d'entreprises recue.)

  6. #6
    Membre éprouvé Avatar de Maerlyn31
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2011
    Messages : 71
    Par défaut
    Hello,

    Le soucis avec AJAX, c'est que c'est une "méta-technologie" qui repose sur pas mal d'autres. Avant de faire tourner asynchrone, il faut bien comprendre tout le circuit d'une requête synchrone, et avec Symfony, c'est pas forcément évident

    On va reprendre le circuit de ta requête, dans l'ordre, comme ça tu va voir les points qui ne vont pas :

    1 - Tu as sur tes pages un lien comportant un appel javascript :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="#" onclick="menu_ajax('<?php echo $entreprise->getId(); ?>','site') "><?php  echo $entreprise->getNom() ; ?> </a>
    Au clic, la fonction menu_ajax( ... ) va être appelée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function menu_ajax(id,table)
    {
    	$.post("displayElements/MenuAjax",  {myParam : id, myTable: table}, function(data) { 
    	     $('#fils').html(data);
    	     } );
    }
    Que fait cette fonction ? Elle envoie une requête POST vers l'url "displayElements/MenuAjax".

    Premier problème, cette url n'est pas forcément valide : si tu changes d'environnement ou de serveur, tu risques d'avoir des surprises. Pour ma part, j'utilise la technique suivante : le passe l'url à atteindre en argument de ma fonction AJAX. Ce qui donne des choses comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function menu_ajax(url, id,table)
    {
    	$.post(url,  {myParam : id, myTable: table}, function(data) { 
    	     $('#fils').html(data);
    	     } );
    }
    et le lien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="#" onclick="menu_ajax('<?php echo url_for('@menuAjax') ?>', '<?php echo $entreprise->getId(); ?>','site') "><?php  echo $entreprise->getNom() ; ?> </a>

    Le reste de la fonction indique que le retour sera écrit dans le conteneur #fils, pour ça pas de problème, mais pour l'instant reprenons notre requête.

    La requête POST est envoyée vers ton appli Symfony. A partir de là, il faut bien comprendre que ton appli, jusqu'à ce que tu lui indiques l'inverse, réagit comme pour une requête "normale", synchrone.

    Tu dois donc, comme pour toute requête entrante, avoir une route prête à l'accueillir et à la renvoyer vers un couple action/module.

    Par exemple, on peut imaginer quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    menuAjax:
      url: /menu/ajax-reload
      params: { module: menu, action: menuAjax }
    A partir d'ici, il te faut une action (une route ne peut pas pointer vers un component)

    Tu vas donc définir une action (ici dans mon exemple, l'action menuAjax dans le module menu) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class menuActions extends sfActions
    {
      public function executeMenuAjax()
      {
          ...
      }
     
    }
    Arrivé là, Symfony va donc exécuter ton action, puis renvoyer vers le template menuAjaxSucces enrobé de ton layout, pour envoyer une réponse finale : une page entière ! Sauf que tu ne souhaites pas ce comportement. Il existe plusieurs manière de faire à ce niveau, pour ma part, je fais en général quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class menuActions extends sfActions
    {
      public function executeMenuAjax()
      {
          // ..... mon code d'action ....
          // Et j'indique explicitement que je ne souhaite renvoyer qu'un partial, et non toute une page avec layout + template
          return $this->renderPartial('menuAjax', array('param1', 'param2 ...));
      }
    }
    Tu n'as plus qu'à définir un partial, dans tonModule/templates/_menuAjax.php, qui contient ton code de vue (ton foreach donc).

    Au final, Symfony te renvoie donc uniquement le code [html + params de ton action], qui est intercepté par ta fonction $.post de départ (ce retour se retrouve stocké dans "data") et placé dans un conteneur de ton choix .... ouf !

    Ceci est bien sur une manière de faire de l'AJAX avec Symfony parmis tant d'autres, il y manque d'ailleurs beaucoup de choses (au niveau des contrôles principalement : quel est le type de requête ? Quel traitement si quelqu'un essaye de feinter ? Toutes ces choses sont importantes ). L'interêt est surtout de te montrer ceci : quand on fait de l'AJAX, le plus simple est de raisonner en terme de requête/réponse : retracer tout le circuit, bien définir ce que l'on souhaite obtenir et agir au bon endroit.

    Bon, le café est coulé, maintenant j'vais me mettre à taffer un peu

    Bon courage à toi !

  7. #7
    Membre éprouvé Avatar de Maerlyn31
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2011
    Messages : 71
    Par défaut
    Hello,

    Alors, tout d'abord, au niveau de l'organisation du code :
    - Ton lien entourant $entreprise->getNom() est fourni par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <?php echo url_for('Entreprise/edit?id='.$entreprise->getId()) ?>
    mais ensuite tu as dans le javascript :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "displayElements/MenuAjax"
    Que ce soit en AJAX ou non, le click sur ce lien doit envoyer une requête, vers une URL. Laquelle veux-tu atteindre exactement ? En allant un peu plus loin, quelles sont les routes associées a ces deux URL ?

    Concernant l'utilisation d'un component, cela dépend de ce que tu veux faire, mais si tu cherche a atteindre une route Symfony, elle pointera automatiquement vers une action dans un module, donc il faut que ton code soit dans une action.

    Ensuite concernant ton code javascript il ya une erreur de syntaxe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function menu_ajax(id,table)
    {
        $.post("displayElements/MenuAjax",  {myParam : id, myTable: table} );
    }
    De plus, la fonction $POST ne fait qu'envoyer une requête, sans en gérer le retour. Le code te convenant serait donc plutot quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function menu_ajax(id,table)
    {
        $.post("displayElements/MenuAjax",  {myParam : id, myTable: table}, function(data) { 
         $('#lendroit_ou_tu_veu_ton_retour').html(data);
         } );
    }
    Dans tous les cas, le mieux est de t'organiser par couche : d'abord du php simple, et ensuite, une fois que tout fonctionne, une surcouche javascript pour l'AJAX.

    Pour t'aider dans le debugging, utilise aussi FireBug (extension Firefox) : dans l'onglet Console, tu peux voir les requêtes AJAX qui sont envoyées. Ainsi, tu peux plus facilement voir quelle est la requête envoyée, vers quelle URL, avec quels paramètres, etc ...

Discussions similaires

  1. Requete AJAX sur serveur exterieur.
    Par ABandApart dans le forum jQuery
    Réponses: 2
    Dernier message: 19/09/2010, 21h37
  2. requete ajax sur un serveur web en java depuis php
    Par enzostar dans le forum Général JavaScript
    Réponses: 29
    Dernier message: 29/03/2010, 13h59
  3. Réponses: 4
    Dernier message: 27/02/2010, 22h04
  4. ajax sur onclick
    Par Nympheasi dans le forum jQuery
    Réponses: 3
    Dernier message: 04/02/2010, 16h56
  5. [AJAX] Requete ajax sur une meme page php
    Par Bownobo dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 22/06/2007, 11h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo