Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > symfony
symfony Forum d'entraide sur le framework PHP symfony. Avant de poster : cours symfony et FAQ symfony
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 12/07/2011, 15h28   #1
Candidat au titre de Membre du Club
 
Inscription : octobre 2009
Messages : 109
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 109
Points : 11
Points : 11
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 :
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 :
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 :
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
Knarf64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 15h52   #2
Membre habitué
 
Inscription : septembre 2009
Messages : 85
Détails du profil
Informations personnelles :
Âge : 22
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : septembre 2009
Messages : 85
Points : 101
Points : 101
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 :
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é*/ }
);
gototog est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 15h59   #3
Membre habitué
 
Avatar de Maerlyn31
 
Homme Baptiste Naudinat
Développeur Web
Inscription : mai 2011
Messages : 70
Détails du profil
Informations personnelles :
Nom : Homme Baptiste Naudinat
Localisation : France

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : mai 2011
Messages : 70
Points : 146
Points : 146
Hello,

Alors, tout d'abord, au niveau de l'organisation du code :
- Ton lien entourant $entreprise->getNom() est fourni par :
Code :
<?php echo url_for('Entreprise/edit?id='.$entreprise->getId()) ?>
mais ensuite tu as dans le javascript :
Code :
"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 :
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 :
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 ...
Maerlyn31 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 12/07/2011, 16h15   #4
Candidat au titre de Membre du Club
 
Inscription : octobre 2009
Messages : 109
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 109
Points : 11
Points : 11
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 :
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.
Knarf64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 16h17   #5
Candidat au titre de Membre du Club
 
Inscription : octobre 2009
Messages : 109
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 109
Points : 11
Points : 11
Code :
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 :
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 ; ?>
Knarf64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/07/2011, 08h10   #6
Membre habitué
 
Inscription : septembre 2009
Messages : 85
Détails du profil
Informations personnelles :
Âge : 22
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : septembre 2009
Messages : 85
Points : 101
Points : 101
Citation:
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.)
gototog est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/07/2011, 09h39   #7
Membre habitué
 
Avatar de Maerlyn31
 
Homme Baptiste Naudinat
Développeur Web
Inscription : mai 2011
Messages : 70
Détails du profil
Informations personnelles :
Nom : Homme Baptiste Naudinat
Localisation : France

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : mai 2011
Messages : 70
Points : 146
Points : 146
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 :
<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 :
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 :
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 :
<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 :
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 :
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 :
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 !
Maerlyn31 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/07/2011, 14h43   #8
Candidat au titre de Membre du Club
 
Inscription : octobre 2009
Messages : 109
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 109
Points : 11
Points : 11
Merci beaucoup de ces réponses, me voila bien mieux armé, je vais retenter de mettre en place la requête. Je vous tiens au jus.
Knarf64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/07/2011, 16h24   #9
Candidat au titre de Membre du Club
 
Inscription : octobre 2009
Messages : 109
Détails du profil
Informations forums :
Inscription : octobre 2009
Messages : 109
Points : 11
Points : 11
J'ai enfin un menu déroulant qui fonctionne bien, merci les gars.
En revanche je me suis heurté à un léger souci : lorsque j'utilisais la méthode onClick même si toutes les étapes étaient faites jusqu’à l’écriture dans le span #fils, symfony écrasait mon menu (et donc le résultat de ma requête). Il recharge le menu j'ai l'impression.

Mais en passant au JS comme ceci aucun problème :

Code :
1
2
3
4
5
 
<?php  foreach ($liste_entreprise as $entreprise) : ?>
        <li><a href="javascript:menu_ajax('<?php echo url_for('@menuAjax') ?>','<?php echo $entreprise->getId(); ?>','site');"    ><?php  echo $entreprise->getNom() ; ?> </a></li>
	<span id="fils"> </span>
<?php endforeach ; ?>
Un grand merci à ceux qui ont postés, j'ai moi même rajouté ce petit bout de code pour ceux qui rencontreront mon problème.
Knarf64 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 06h35.


 
 
 
 
Partenaires

Hébergement Web