Menu Dynamique recursif php/mysql

Menu Dynamique recursif php/mysql - PHP - Programmation

Marsh Posté le 17-03-2011 à 12:47:44    

Bonjour,
 
je n'ai pas l'habitude de demander de l'aide sur les forums, car la plupart du temps je trouve les réponses à mes questions.
Mais la, il s'agit d'un problème complexe et n'étant pas un AS dans ce domaine je fais appelle à vôtres indulgence et à vos connaissances.
 
Rentrons dans le vif du sujet :
 
Je développe actuellement un site web, php/mysql, pour le menu, je pensais récupérer le menu dropdown que j'avais fait il y a des années en ajoutant la connexion à la base de données, une récursivité qui m'affichait un genre de Template pour chaque entrée trouvé :
 
javascript :

Code :
  1. function sw(div, img) {
  2.       var d = document.getElementById(div);
  3.       var i = document.getElementById(img);
  4.       if (d.style.display == 'none') {
  5.          d.style.display = 'block';
  6.          i.src = '../images/arrow-down.png';
  7.       } else {
  8.          d.style.display = 'none';
  9.          i.src = '../images/arrow-right.png';
  10.       }
  11.    }


 
php :
 

Code :
  1. $cnx = mysql_connect( "localhost", "user", "password" );
  2. $db= mysql_select_db( "site" );
  3. $sql = "SELECT * FROM menu";
  4. $requete = mysql_query( $sql, $cnx ) or die( "ERREUR MYSQL numéro: ".mysql_errno()."<br>Type de cette erreur: ".mysql_error()."<br>\n" );
  5. while( $result = mysql_fetch_array( $requete ) )
  6. {
  7. ?>
  8. <div onclick="sw('<?php echo $result["titlem"]; ?>', '<?php echo $result["id"]; ?>')"><img src="../images/arrow-right.png" border="0" id="<?php echo $result["id"]; ?>"<a href="#"><?php echo $result["titlem"]; ?></a></div>
  9. <div style="display:none;" id="<?php echo $result["titlem"];?>"
  10. <p class="sub-menu"><a href="#"><?php echo $result["title-submenu"];?></a></p>
  11. </div>
  12. <img src="../images/portal-break.png">
  13. <?php
  14. }


 
Et effectivement cela fonctionne, sauf que ça ne fonctionne que pour les menus pas pour les sous-menus.
Après pas mal de recherches sur le net, j'ai trouvé une solution qui fonctionne parfaitement :
 

Code :
  1. <?php
  2. $cnx = mysql_connect( "localhost", "user", "password" );
  3. $db= mysql_select_db( "site" );
  4. $query = "SELECT id, parent, nom FROM menu ORDER BY nom ASC";
  5. $result = mysql_query($query);
  6. $categories = array();
  7. while($row = mysql_fetch_array($result)) {
  8.         $categories[] = array(
  9.         'parent_id' => $row['parent'],
  10.         'categorie_id' => $row['id'],
  11.         'nom_categorie' => $row['nom']
  12.         );
  13. }
  14. function afficher_menu($parent, $niveau, $array) {
  15. $html = "";
  16. $niveau_precedent = 0;
  17. if (!$niveau && !$niveau_precedent) $html .= "\n<ul>\n";
  18. foreach ($array AS $noeud) {
  19.         if ($parent == $noeud['parent_id']) {
  20.         if ($niveau_precedent < $niveau) $html .= "\n<ul>\n";
  21.         $html .= "<li><a href=\"?categorie=" . $noeud['categorie_id'] . "\">" . $noeud['nom_categorie'] . "</a>";
  22. //$html .= "<li>" . $noeud['nom_categorie'];//
  23.         $niveau_precedent = $niveau;
  24.         $html .= afficher_menu($noeud['categorie_id'], ($niveau + 1), $array);
  25.         }
  26. }
  27. if (($niveau_precedent == $niveau) && ($niveau_precedent != 0)) $html .= "</ul>\n</li>\n";
  28. else if ($niveau_precedent == $niveau) $html .= "</ul>\n";
  29. else $html .= "</li>\n";
  30. return $html;
  31. }
  32. ?>
  33. <?php echo afficher_menu(0, 0, $categories);?>


 
Cela fonctionne et c'est génial, sauf que voila, j'aimerais pouvoir modifier le code pour l'intégrer dans mon premier script ou alors pouvoir le modifier avec des types spéciaux css, et une fonction dropdown en java comme mon premier script.
 
Je vous remercie par avance pour vos réponses, en espérant trouver et surtout comprendre la solution.
 
Amicalement,
Fabien493

Reply

Marsh Posté le 17-03-2011 à 12:47:44   

Reply

Marsh Posté le 17-03-2011 à 14:34:56    

- ajoute des classes css dans le code, en ajoutant en suffixe le 'niveau' ($niveau dans la récursion) : avec ça tu peux gérer l'habillage de ton site.
- pour ton menu déroulant, difficile de répondre, ça dépend de ce que tu veux faire.
mais t'as la variable $html qui est remplie au fil des appels récursifs, il suffit d'ajouter les appels javascripts aux niveaux qui t'intéressent...

Reply

Marsh Posté le 17-03-2011 à 16:37:15    

Bonjour PunkRod et merci pour ta réponse.
 
J'ai essayé de modifier les ul et li avec une class directement dans la boucle, mais apparement ça ne fonctionne pas.  
je n'ai pas très bien compris la façons d'ajouter en suffixe le niveau pour les récuperer pour le CSS, veux-tu dire d'ajouter des classes css directement dans la variable $niveau ?  
 
n'y a t'il pas la possiblité de recuperer la variable $html, qui affiche au format html le menu et ensuite dy integrer les classes css ?
 
je me posais une autres question, le menu du site contiendra environs 100 à 500 entrée, est-ce-qu'un recursivité ne sera pas trop lourde pour le site ?
 
merci d'avance,
Fabien493

Reply

Marsh Posté le 17-03-2011 à 17:59:38    

Tu ne peux pas récupérer le html et y intégrer après les classes : sinon ça veut dire que tu n'as pas besoin de créer d'une fonction récursive pour la création.
 
pour les suffixes si tu mets dans chaque <li> une balise css, ex :
<li class="niveau_<?php echo $niveau; ?>">
ça te donne en html : <li class="niveau_1"> (2, 3, 4 etc.)
et ça en css tu peux le gérer : niveau 1 = marge à gauche de 10px, niveau 2 = 20px etc.
 
Quand aux perfs : à priori pas d'inquiétude à avoir

Reply

Marsh Posté le 18-03-2011 à 00:36:09    

Re bonjour,
 
Effectivement PunkRod, j'avais mal formaté en utilisant " " au lieu de ' '
Je peux maintenant travailler dessus via le CSS je te remercie.
 
Concernant la possibilité de caché les sous-menus et de le les afficher en cliquant sur les menus, j'ai trouvé bizarrement un topic qui reprends le même code içi
Mais il semblerais qu'ils aient refait tout la partie dite récursive pour pouvoir l'adapter, de plus je n'ai pas réussi à l'adapter avec une connexion à la base mysql ( oui je sais je suis nul...).
 
voici le code qu'ils ont modifiés :
 

Code :
  1. <html>
  2. <head>
  3. <script type="text/javascript">
  4. <!--
  5. function showhide(elmt) {
  6. var menu = elmt.parentNode.childNodes[1];
  7. if (menu.style.display == 'none') {
  8.  menu.style.display = '';
  9. } else {
  10.  menu.style.display = 'none';
  11. }
  12. }
  13. //-->
  14. </script>
  15. </head>
  16. <body>
  17. <?php
  18. $cat[0] = array("id" => 1, "parent" => 0, "nom" => "Informatique_racine" );
  19. $cat[1] = array("id" => 2, "parent" => 1, "nom" => "ss-info" );
  20. $cat[2] = array("id" => 3, "parent" => 1, "nom" => "Internet/Messagerie" );
  21. $cat[3] = array("id" => 4, "parent" => 3, "nom" => "FTP" );
  22. $cat[4] = array("id" => 5, "parent" => 3, "nom" => "Acces WIFI client" );
  23. $cat[5] = array("id" => 6, "parent" => 2, "nom" => "test" );
  24. $cat[6] = array("id" => 7, "parent" => 0, "nom" => "test-racine" );
  25. function afficher_menu($arr, $id_parent = 0) {
  26. $html = "<ol>";
  27. foreach ($arr AS $k => $v) {
  28.  if ($v['parent'] == $id_parent) {
  29.   $child = afficher_menu($arr, $v['id']);
  30.   if (!empty($child) && $chield != "<ol></ol>" ) {
  31.    $html .= "<li><a href=\"#\" class=\"menu\" onclick=\"showhide(this); return false;\">".$v['nom']."</a>";
  32.   } else {
  33.    $html .= "<li>".$v['nom'];
  34.   }
  35.   $html .= $child;
  36.   $html .= "</li>";
  37.  }
  38. }
  39. if( $html != "<ol>" ) {
  40.  $html .= "</ol>\r\n";
  41. } else {
  42.  $html = "";
  43. }
  44. return $html;
  45. }
  46. echo afficher_menu($cat);
  47. ?>
  48. </body>
  49. </html>


 
Apparemment la partie javascript fonctionne, sauf qu'au lancement de la page le menu reste déplié.( peut-être une simple erreur)
 
J'ai testé plusieurs adaptations des différents codes que j'ai pus trouver sur le net mais je n'ai pas réussi.
 
Je me demande quand même si il n'ai pas possible de récupérer le résultat de la récursivité pour le mettre dans des variables exemple récupérer les MENU qui ont un niveau de 0 et les sous menus qui ont un code niveau de 1 et de l'adapter au mon premier script :

Code :
  1. # <div onclick="sw('NOMDUMENU')>', '<IDDUMENU>')"><img src="../images/arrow-right.png" border="0" id="<IDDUMENU>"<a href="#"><NOMDUMENU></a></div>
  2. # <div style="display:none;" id="<NOMDUMENU>"
  3. # <p class="sub-menu"><a href="#"><NOMDUSOUSMENU></a></p>
  4. # </div>


 
Juste pour info le code du menu récursif je l'avais vue sur ce site :
 
 
Voila sinon je suis un peux désespérer.  
 
Merci encore,
Amicalement,
Fabien493

Reply

Marsh Posté le 12-05-2011 à 16:34:12    

Salut, j'utilise aussi cette fonction pour générer mes menus. Bon ma version est 'un peu' modifiée pour coller a mes besoins mais en gros ça donne ça :
 

Code :
  1. <?php
  2. function getMenu($parent, $niveau, $array) {
  3. $html = "";
  4. $niveau_precedent = 0;
  5. if (!$niveau && !$niveau_precedent) $html .= "";
  6. foreach ($array AS $noeud) {
  7. if ($parent == $noeud['parent_id']) {
  8. if ($niveau_precedent < $niveau) $html .= "\n<ul>\n";
  9. $html .= "<li class=\"" . $noeud['url'] . "" . $noeud['active'] . "\"><a href=\"" . $noeud['linkurl'] . "\">" . $noeud['nom_categorie'] . "</a>";
  10. $niveau_precedent = $niveau;
  11. $html .= getMenu($noeud['categorie_id'], ($niveau + 1), $array);
  12. }
  13. }
  14. if (($niveau_precedent == $niveau) && ($niveau_precedent != 0)) $html .= "</ul>\n</li>\n";
  15. else if ($niveau_precedent == $niveau) $html .= "</ul>\n";
  16. else $html .= "</li>\n";
  17. return $html;
  18. }
  19. /////////////////////////////////////////////////////////////////////////////////////
  20. $sql="SELECT * FROM menu WHERE publish='1' ORDER BY position ASC";
  21. $req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());
  22. $datamenu = array();
  23. while($row = mysql_fetch_array($req)) {
  24.  $row['baseurl']=$baseurl;
  25.  if($row['idlink'] == $id || $row['idlink'] == $catid && $catid!=0){
  26.  $row['active']=' current';
  27.  }elseif($row['catmenu'] == $belongto){
  28.  $row['active']='';
  29.  }elseif($row['typepage'] == 'contact.php' && $row['urlmenu'] == $url){
  30.  $row['active']=' current';
  31.  }else{
  32.  $row['active']='';
  33.  }
  34.  if($urlrewriting==0){
  35.   if($row['typepage']=='index.php'){
  36.   $row['linkurl']=''.$row['baseurl'].''.$row['typepage'].'?id='.$row['idlink'].'';
  37.   }elseif($row['typepage']=='contact.php'){
  38.   $row['linkurl']=''.$row['baseurl'].''.$row['typepage'].'';
  39.   }elseif($row['typepage']=='news.php'){
  40.   $row['linkurl']=''.$row['baseurl'].''.$row['typepage'].'?id='.$row['idlink'].'';
  41.   }
  42.  }else{
  43.   if(($row['typepage']=='index.php')&&($row['catmenu']==0)){
  44.   $row['urlrw']= ''.$row['idlink'].'-'.$row['urlmenu'].'';
  45.   }elseif(($row['typepage']=='index.php')&&($row['catmenu']!=0)){
  46.   $row['urlrw']= ''.$row['caturl'].'/'.$row['idlink'].'-'.$row['urlmenu'].'';
  47.   }elseif($row['typepage']=='contact.php'){
  48.   $row['urlrw']= ''.$row['urlmenu'].'';
  49.   }
  50.   if($row['typepage']=='index.php'){
  51.   $row['linkurl']=''.$row['baseurl'].''.$row['urlrw'].'';
  52.   }elseif($row['typepage']=='contact.php'){
  53.   $row['linkurl']=''.$row['baseurl'].''.$row['urlrw'].'';
  54.   }elseif($row['typepage']=='news.php'){
  55.   $row['linkurl']=''.$row['baseurl'].''.$row['urlrw'].'';
  56.   }
  57.  }
  58.  $datamenu[] = array(
  59.  'parent_id' => $row['catmenu'],
  60.  'categorie_id' => $row['id'],
  61.  'link_id' => $row['idlink'],
  62.  'active' => $row['active'],
  63.  'linkurl' => $row['linkurl'],
  64.  'baseurl' => $row['baseurl'],
  65.  'nom_categorie' => $row['titremenu'],
  66.  'url' => $row['urlmenu']
  67.  );
  68. }
  69. /////////////////////////////////////////////////////////////////////////////////////
  70.         echo "<ul class=\"menu\">";
  71. echo getMenu(0, 0, $datamenu);
  72. ?>


 
Après j'associe le résultat avec le plugin Jquery superfish, quelques modification rapides dans le fichier css et tu devrais avoir rapidement le résultat que tu souhaites. Voila, en espérant t'avoir aidé.

Reply

Marsh Posté le 09-02-2012 à 18:08:29    

waw c trop compliqué


Message édité par lima2012 le 09-02-2012 à 18:09:27

---------------
Creation site web Maroc agence web maroc
Reply

Marsh Posté le 20-03-2012 à 13:59:37    

Bonjour,
 
J'ai un souci avec une fonction qui affiche l'arboresences de pages de mon site dans une liste déroulante, peut être pouvez-vous m'aider?
 
J'ai une BDD avec les infos des pages de mon site(Id_page, Id_parent, Contenu, Trie, Titre).  
Pour modifier celles-ci j'ai une interface administrateur, dans laquelle il y a une page de modification (modif_page.php) contenant un formulaire qui reprend les infos de la page dont l'Id est envoyé dans l'url depuis la page liste_page.php (dans la bdd). $Id_parent (parent de la page en cours de modification)
 
Dans cette page de modification la liste déroulante doit permettre de modifier la catégorie parente de la page.  
 
Pour afficher l'arborescence tout va bien, j'ai utilisé:
 
function liste_deroulante_parent($parent, $niveau, $array) {
$html = "";
 
foreach ($array AS $noeud) {
//si on rencontre une catégorie qui a un lien de parenté avec une autre
if ($parent == $noeud['parent_id']) {
for ($i = 0; $i < $niveau; $i++) $html .= "--";
$html .= " " . $noeud['nom_page'].$noeud['Id_page'];
$html .="</option>";
$html .= liste_deroulante_parent($noeud['Id_page'], ($niveau + 1), $array);
}
}
 
Mais....
 
1) Comment selectionner la catégorie parente, par défaut, de la page en cours de modification dans cette liste déroulante.
J'ai tenté (entre autre) avec :
 
if($Id_parent == $noeud['Id_page'])
{
$html .= "<option value=".$noeud['Id_page']."selected=\"selected\">";
} else {
$html .= "<option> ";
}  
ça marche pas!!!  
 
2) comment faire pour que si variable $Id_parent (de la page en cours de modification) =0 alors on attribue "aucun parent" dans la liste?
 
Une aide serait vraiment la bienvenue...  
 
Je vous remercie d'avance!

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed