Nested Tree Nav

This snippet takes xml and builds a multi-tiered navigation based on how nodes are nested etc...:

So that something like this:

XML:
  1. var menu:XML=<nav>
  2.    <element label="one">
  3.        <element label="a" />
  4.    <element label="b" />
  5.    <element label="c" />
  6. </element>
  7. <element label="two">
  8.      <element label="three">
  9.      <element label="aa">
  10.        <element label="zevan" />
  11.      </element>
  12.      <element label="bb" />
  13.      <element label="cc" />
  14.  </element>
  15.  </element>
  16. </nav>;

Turns into an expandable and collapsible menu that looks like this:

Here is the timeline code:

Actionscript:
  1. var menu:XML=<nav>
  2.    <element label="one">
  3.        <element label="a" />
  4.    <element label="b" />
  5.    <element label="c" />
  6. </element>
  7. <element label="two">
  8.      <element label="three">
  9.      <element label="aa">
  10.        <element label="zevan" />
  11.      </element>
  12.      <element label="bb" />
  13.      <element label="cc" />
  14.  </element>
  15.  </element>
  16. </nav>;
  17.  
  18. var elements:Array = new Array();
  19. setupMenu();
  20.  
  21. function setupMenu():void {
  22.     parse(menu);
  23.     // hide child elements
  24.     for (var i:int = 0; i<elements.length; i++) {
  25.         var mc:MovieClip = elements[i];
  26.         if (mc.parents != 1) {
  27.             removeChild(mc);
  28.         }
  29.     }
  30.     arrangeY();
  31. }
  32.  
  33. function parse(m:XML):void {
  34.     for each (var d:XML in m.children()) {
  35.         makeBtn(d, numParents(d));
  36.         parse(d);
  37.     }
  38. }
  39.  
  40. function makeBtn(d:XML, offsetX:int):void {
  41.     var btn:MovieClip = new MovieClip();
  42.     btn.x = offsetX * 20;
  43.     btn.y = numChildren * 20;
  44.     btn.data = d;
  45.     btn.parents = offsetX;
  46.     btn.value = d.@label;
  47.  
  48.     var txt:TextField = new TextField();
  49.     txt.text = d.@label;
  50.     txt.selectable = false;
  51.     txt.border = true;
  52.     txt.width = 100;
  53.     txt.mouseEnabled = false;
  54.     txt.height = 19;
  55.     btn.addChild(txt);
  56.     btn.buttonMode= true;
  57.     addChild(btn);
  58.    
  59.     // store references to btn
  60.     elements.push(btn);
  61.     elements[d.parent().@label+"_"+d.@label] = btn
  62.  
  63.     btn.addEventListener(MouseEvent.CLICK, onClick);
  64. }
  65.  
  66. function onClick(evt:MouseEvent):void {
  67.     showHide(MovieClip(evt.currentTarget));
  68.     arrangeY();
  69.     trace(evt.currentTarget.value);
  70. }
  71.  
  72. function showHide(btn:MovieClip, forceHide:Boolean=false):void {
  73.     for each (var d:XML in btn.data.children()) {
  74.         var mc:MovieClip = elements[btn.data.@label+"_"+d.@label];
  75.         if (contains(mc)) {
  76.             removeChild(mc);
  77.             showHide(mc, true);
  78.         } else if (forceHide == false) {
  79.             addChild(mc);
  80.         }
  81.     }
  82. }
  83.  
  84. function arrangeY():void {
  85.     var inc:Number = 0;
  86.     for (var i:int = 0; i<elements.length; i++) {
  87.         if (contains(elements[i])) {
  88.             elements[i].y = inc * 20;
  89.             inc++;
  90.         }
  91.     }
  92. }
  93.  
  94. function numParents(e:XML):int {
  95.     var num:int = 0;
  96.     while (e.parent()!= null) {
  97.         num++;
  98.         e = e.parent();
  99.     }
  100.     return num;
  101. }

This is one of those snippets I've had laying around but never got around to posting. Next time I need to do a multi-tiered nav I'll wrap it up into a nice class (the wondeful class was done just by using my script that auto-converts timeline code to doc class code).

This entry was posted in Uncategorized. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

2 Comments

  1. Bryce Bigger
    Posted March 2, 2010 at 8:33 am | Permalink

    How about adding some animation to it? That’s the icing on the cake! Keep up the awesome snippets!

  2. Posted March 2, 2010 at 8:36 am | Permalink

    i may post a revised version of it tomorrow… with some animation… would be easy enough to do with tweenlite….

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*