Forum Programmation.web Menu arborescent pliable et conservation de l'état lors de la navigation

Posté par .
Tags : aucun
0
7
mai
2006
Bonjour cher forum,

Je souhaiterais de faire un menu arborescent pliable à plusieurs niveaux comme ceci :
*A
   *AA
   *AB
   *AC
      *ACA
      *ACB
      *ACC
*B
   *BA
   *BB
*C
   *CA
*D
   *DA
   *DB

Avec un peu de javascript et de CSS (propriétés display:block and display:none) j'arrive à plier/déplier correctement mon arbre en cliquant sur les n½uds. Par défaut, seuls les n½uds supérieurs sont visibles :
*A
*B
*C
*D

Jusque là tout allait bien. Voici mon problème. Admettons que l'utilisateur a cliqué sur C, puis D, l'arbre devient:
*A
*B
*C
   *CA
*D
   *DA
   *DB

Maintenant, s'il clique sur DB par exemple, alors le menu est totalement replié lors du chargement de la nouvelle page :
*A
*B
*C
*D

Je voudrais conserver l'état de l'arbre avant le clic. Comment faut-il faire ?

Merci d'avance,

Med
  • # Tres Lourd

    Posté par . Évalué à 2.

    Alors, la dans ma tete, j'ai 2 solutions

    Soit mettre ton menu dans une frame/iframe (pabo pabo pabo)

    Sinon, tu genere un CSS en PHP/ce_que_tu_veux, que tu sauvegarde dans la session


    Sinon jvoit pas
  • # Cookies

    Posté par (page perso) . Évalué à 4.

    Quand l'utilisateur clique, tu enregistre un cookie sur l'état du menu. À son retour, dans onload tu exécutes une fonction qui récupère tout les états et les affichent comme il faut. En une heure ou moins c'est fait.
    • [^] # Re: Cookies

      Posté par . Évalué à 1.

      Merci à vous deux. Finalement je me suis rabattu sur la solution du cookie qui après quelques tâtonnements marche finalement très bien. Pour ceux qui veulent avoir quelques détails, lors de l'évènement onUnLoad je parcours récursivement l'arbre de mon menu et j'ajoute dans un tableau les id de tous les éléments d'une classe que j'appelle « submenu » et qui ont la propriété display:block. Je sauve ensuite ce tableau dans un cookie. Lors de l'évènement onLoad il suffit alors de récupérer le cookie et d'appliquer display:block à tous les éléments dont le id est contenu dans le cookie. Et voilà !

      Merci encore,

      Med
      • [^] # Re: Cookies

        Posté par (page perso) . Évalué à 2.

        On peut voir le code ou du moins ce que ca donne? je suis interéssé
        • [^] # Re: Cookies

          Posté par . Évalué à 2.

          Bien sûr. Je tiens cependant à dire que c'est la première fois de ma vie que je fais du javascript, ce n'est certainement pas dans les règles de l'art ni sans bug.

          Voilà la partie javascript (les deux premières fonctions ne sont pas de moi) :

          <script type="text/javascript">
          <!--

          function setcookie(name, value, expire) {
              var timestamp=new Date(expire);
              document.cookie=name + "=" + escape(value) + "; expires=" + timestamp.toGMTString();
          }

          function getcookie(name) {
              var cookies = document.cookie.split(/;/);
              for(var i=0; i < cookies.length; i++){
                  var mycook = cookies[i].split(/=/);
                  if(mycook[0]==name)return unescape(mycook[1]);
              }
          }

          function getOpenMenuNodes(d,list) {
              if (d) {
                  var nodes = d.childNodes;

                  for(var i=0;i<nodes.length;i++) {
                      if(nodes[i].hasChildNodes()) getOpenMenuNodes(nodes[i],list);
                      if(nodes[i].className == "submenu" && nodes[i].style.display == "block") list.push(nodes[i].id);
                  }
              }
          }

          function saveMenu() {
          var list = new Array();
          getOpenMenuNodes(document.getElementById("menu"),list);
          setcookie("menustate",list,(new Date(2042, 12).getTime()));
          }

          function restoreMenu() {
              var openNodes = getcookie("menustate");
              openNodes = new String(openNodes.toString());
              openNodes = openNodes.split(',');

              if (openNodes != undefined)
                  for (var i in openNodes) {
                      node = document.getElementById(openNodes[i]);
                      node.style.display = "block";
                  }
          }

          function showhide(id) {
          var d = document.getElementById(id);
          if (d) {
              if (d.style.display=="block") {
                  d.style.display="none";
              } else {
                  d.style.display="block";
              }
          }
          }
          //-->
          </script>


          Mon menu est contruit de la sorte :


          <li class='menu-top'><span onclick="javascript:showhide('menu-a');">A</span>
          <ul class='submenu' id='menu-a'>
            <li class='menu-leaf'><a href="?page=AA">AA</a></li>
            <li class='menu-dir'><span onclick="javascript:showhide('menu-ab');">AB</span>
            <ul class='submenu' id='menu-ab'>
              <li class='menu-leaf'><a href="?page=ABA">ABA</a></li>
              <li class='menu-leaf'><a href="?page=ABB">ABB</a></li>
            </ul>
            </li>
            <li class='menu-leaf'><a href="?page=AC">AC</a></li>
            <li class='menu-leaf'><a href="?page=AD">AD</a></li>
          </ul>
          </li>
          <li class='menu-top'><span onclick="javascript:showhide('menu-b');">B</span>
          <ul class='submenu' id='menu-b'>
            <li class='menu-leaf'><a href="?page=BA">BA</a></li>
            <li class='menu-leaf'><a href="?page=BB">BB</a></li>
          </ul>
          etc.


          Il suffit alors d'avoir une balise body comme ceci et le tour est joué:

          <body onLoad="javascript:restoreMenu();" onUnLoad="javascript:saveMenu();">


          Ça marche parfaitement dans Firefox. En revanche avec Konqueror, le menu n'est pas sauvé lorsqu'on ferme l'onglet ou le navigateur, cela marche cependant normalement pour la navigation. C'est apparemment à cause de ce bug : http://bugs.kde.org/show_bug.cgi?id=78331 , pour les kdeistes auxquels il reste des votes ... Opera souffre du même défaut apparemment. Je n'ai pas testé sous IE par flemme de rebooter l'ordi.
          • [^] # Re: Cookies

            Posté par (page perso) . Évalué à 3.

            Si tu veut, voici le code que nous a fournit notre prof d'algo en debut d'année (oui on a des cours de javascript dans ma formation \o/ )


            // Fonctions pour stocker les cookies sur l'ordinateur client
            function SetCookie (name, value)
            {
            var argv=SetCookie.arguments;
            var argc=SetCookie.arguments.length;
            var expires=(argc > 2) ? argv[2] : null;
            var path=(argc > 3) ? argv[3] : null;
            var domain=(argc > 4) ? argv[4] : null;
            var secure=(argc > 5) ? argv[5] : false;
            document.cookie=name+"="+escape(value)+
            ((expires==null) ? "" : ("; expires="+expires.toGMTString()))+
            ((path==null) ? "" : ("; path="+path))+
            ((domain==null) ? "" : ("; domain="+domain))+
            ((secure==true) ? "; secure" : "");
            }

            // Fonction pour lire le cookie sur l'ordinateur client a partir
            // de son rang (offset)
            function getCookieVal(offset)
            {
            var endstr=document.cookie.indexOf (";", offset);
            if (endstr==-1)
            endstr=document.cookie.length;
            return unescape(document.cookie.substring(offset, endstr));
            }

            // Fonction qui permet de trouver le rang du cookie a partir de
            // son nom
            function GetCookie (name)
            {
            var arg=name+"=";
            var alen=arg.length;
            var clen=document.cookie.length;
            var i=0;
            while (i<clen) {
            var j=i+alen;
            if (document.cookie.substring(i, j)==arg)
            return getCookieVal (j);
            i=document.cookie.indexOf(" ",i)+1;
            if (i==0) break;}
            return null;
            }

            var pathname=location.pathname;
            var myDomain=pathname.substring(0,pathname.lastIndexOf('/')) +'/';
            var date_exp = new Date();
            date_exp.setTime(date_exp.getTime()+(365*24*3600*1000));
            // Ici on définit une durée de vie de 365 jours


            Apres il suffit de faire un
            SetCookie("nomducookie",valeurducookie,date_exp,myDomain);
            et
            GetCookie("nomducookie");

            Le date_exp pouvant être changé, le myDomain se determinant tout seul comme un grand.

            (pub honteuse) Des exemples à la pelle ici:
            http://src.momo.servegame.org/algo/

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.