Retourner aux forums || Retourner au forum Programmation.web

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

Posté par med (page perso, ) le 06 mai 2006
0
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

> Lire le message (6 commentaires, moyenne: 2,3).  

Cette discussion est archivée, il n'est plus possible de laisser des commentaires.

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

Tres Lourd

Posté par Acetik () le 07/05/2006 à 08:26. (lien). É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 Pooly (page perso, ) le 07/05/2006 à 09:08. (lien). É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 med (page perso, ) le 07/05/2006 à 13:14. (lien). É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 Uld (page perso, ) le 07/05/2006 à 13:38. (lien). Évalué à 2.

      On peut voir le code ou du moins ce que ca donne? je suis interéssé

      --
      Ubuntu is an ancient african word meaning : "I can't configure Debian".
      • [^]Re: Cookies

        Posté par med (page perso, ) le 07/05/2006 à 14:33. (lien). É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 Jean-Philippe (page perso, ) le 07/05/2006 à 16:33. (lien). É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/

Revenir en haut de page || Retourner aux forums || Retourner au forum Programmation.web