8 Replies Latest reply on Aug 10, 2007 2:08 PM by ntsiii

    Expanding Tree Item for Tree with showRoot="false"

    Josh Johnson
      So using the example in the docs I created an example application for expanding an item in a tree, and with a little tweaking, it works great. I then wanted to reapply the process to my project, which has multiple root level nodes. Since the dataProvider has to have a root node, I set that to a dummy node and set showRoot to 'false' on the Tree component.

      Problem is that when I make this change, the expandItem action stops working and I can't figure out why. Here's the example code that exhibits the same behaviour. If you remove the 'showRoot="false"' attribute, it works as expected.

      <?xml version="1.0"?>
      <!-- dpcontrols/TreeEvents.mxml -->
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml">
      <mx:Script>
      <![CDATA[
      import flash.events.*;
      import mx.events.*;
      import mx.controls.*;

      private function changeEvt(event:Event):void {
      forChange.text = event.currentTarget.selectedItem.@label;
      forChangeData.text = event.currentTarget.selectedItem.@data;
      if(XMLTree1.selectedIndex) {
      indexNum.text = XMLTree1.selectedIndex.toString();
      }
      }
      private function itemOpenEvt(event:TreeEvent):void {
      forOpen.text = event.item.@label;
      }
      private function itemCloseEvt(event:TreeEvent):void {
      forClose.text = event.item.@label;
      }
      private function initTree():void {
      XMLTree1.expandItem(MailBox.getItemAt(0), true);
      forOpen.text=XMLTree1.openItems[0].@label;
      }
      ]]>
      </mx:Script>

      <mx:Tree id="XMLTree1" width="150" height="170"
      labelField="@label" itemOpen="itemOpenEvt(event);"
      change="changeEvt(event);" showRoot="false" >
      <!--creationComplete="initTree();"> -->
      <mx:XMLListCollection id="MailBox">
      <mx:XMLList>
      <node label="Mail" data="100">
      <node label="Inbox" data="70">
      <node label="Urgent" data="2"/>
      <node label="Normal" data="3"/>
      </node>
      <node label="Personal Folder" data="10">
      <node label="Business" data="2"/>
      <node label="Demo" data="3"/>
      <node label="Personal" data="0" isBranch="true" />
      <node label="Saved Mail" data="5" />
      </node>
      <node label="Sent" data="15"/>
      <node label="Trash" data="5"/>
      </node>
      </mx:XMLList>
      </mx:XMLListCollection>
      </mx:Tree>
      <mx:Button label="Open" click="initTree();" />

      <mx:Form>
      <mx:FormItem label="Change Event Target:">
      <mx:TextInput id="forChange" width="90" />
      </mx:FormItem>
      <mx:FormItem label="Change Event Target:">
      <mx:TextInput id="forChangeData" width="90" />
      </mx:FormItem>
      <mx:FormItem label="Last Opened Node:" >
      <mx:TextInput id="forOpen" width="90" />
      </mx:FormItem>
      <mx:FormItem label="Last Closed Node:">
      <mx:TextInput id="forClose" width="90" />
      </mx:FormItem>
      <mx:FormItem label="Index Number:">
      <mx:TextInput id="indexNum" width="90" text="{XMLTree1.selectedIndex}" />
      </mx:FormItem>
      </mx:Form>
      </mx:Application>
        • 1. Re: Expanding Tree Item for Tree with showRoot=&quot;false&quot;
          ntsiii Level 3
          Josh, is there a specific reason you are using XMLListCollection instead of pure XML? XML is inherently hierarchical, and perfectly suited to the tree, where XMLListCollection is essentially a list with embeded lists. The docs incorrectly imply that XML should not be used for dynamically updated dataProviders, but it works fine.

          Additionally, "..dataProvider has to have a root node.." is not correct. Your XMLListCollection does not have a root node so i am not sure what the effect of setting the 'showRoot' property is.

          Try simplifying this by using XML with a root, and showRoot="false".

          Then, in initTree, break up the code a big by getting a reference to the node you want in a variable, then verifying it by tracing with toXMLString()

          Tracy
          • 2. Re: Expanding Tree Item for Tree with showRoot=&quot;false&quot;
            Josh Johnson Level 1
            Thanks Tracy. I'll try this out. I took this from the docs, so it looks like the docs led me astray. :)
            • 3. Re: Expanding Tree Item for Tree with showRoot=&quot;false&quot;
              Josh Johnson Level 1
              OK, I did some simplifying as you suggested, but I'm still seeing the same behaviour. If I showRoot, the expandItem function works. If I set showRoot='false', the expandItem function ceases to work.

              Here's the updated code:

              <mx:Script>
              <![CDATA[
              import flash.events.*;
              import mx.events.*;
              import mx.controls.*;

              private function changeEvt(event:Event):void {
              forChange.text = event.currentTarget.selectedItem.@label;
              forChangeData.text = event.currentTarget.selectedItem.@data;
              if(XMLTree1.selectedIndex) {
              indexNum.text = XMLTree1.selectedIndex.toString();
              }
              }
              private function itemOpenEvt(event:TreeEvent):void {
              forOpen.text = event.item.@label;
              }
              private function itemCloseEvt(event:TreeEvent):void {
              forClose.text = event.item.@label;
              }
              private function initTree():void {
              XMLTree1.expandItem(XMLTree1.dataProvider.getItemAt(0), true);
              forOpen.text=XMLTree1.openItems[0].@label;
              }
              ]]>
              </mx:Script>

              <mx:Tree id="XMLTree1" width="150" height="170"
              labelField="@label" itemOpen="itemOpenEvt(event);"
              change="changeEvt(event);" showRoot="false" >
              <mx:XML xmlns="">
              <node label="root">
              <node label="RSS" data="100">
              <node label="Feed 1" data="70"/>
              <node label="Feed 2" data="10"/>
              </node>
              <node label="Mail" data="100">
              <node label="Inbox" data="70">
              <node label="Urgent" data="2"/>
              <node label="Normal" data="3"/>
              </node>
              <node label="Personal Folder" data="10">
              <node label="Business" data="2"/>
              <node label="Demo" data="3"/>
              <node label="Personal" data="0" isBranch="true" />
              <node label="Saved Mail" data="5" />
              </node>
              <node label="Sent" data="15"/>
              <node label="Trash" data="5"/>
              </node>
              </node>
              </mx:XML>
              </mx:Tree>
              <mx:Button label="Open" click="initTree();" />

              This code will fail, but if you remove the showRoot property, it works.
              • 5. Re: Expanding Tree Item for Tree with showRoot=&quot;false&quot;
                ntsiii Level 3
                Ok, that is a bit weird. What i expected to work didn't, and I am not sure why. Here is a workaround, though. Replace initTree code with this:

                var xmlNode:XML = XML(XMLTree1.dataProvider).node[0];
                XMLTree1.selectedItem = xmlNode;
                XMLTree1.expandItem(XMLTree1.selectedItem, true);
                forOpen.text=XMLTree1.openItems[0].@label;

                Just using xmlNode in the expandItem argument does not work. Odd.

                And don' t forget to call initTree on the Tree creationComplete event.
                • 6. Re: Expanding Tree Item for Tree with showRoot=&quot;false&quot;
                  ntsiii Level 3
                  I just learned something else. If you instantiate the xml in a variable, then use the variable in the initTree code, it works without having to use selectedItem. there is certainly more going on here than I understand.
                  Tracy

                  <?xml version="1.0" encoding="utf-8"?>
                  <!-- dpcontrols/TreeEvents.mxml -->
                  <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml"
                  initialize="initApp()">
                  <mx:Script><![CDATA[
                  import flash.events.*;
                  import mx.events.*;
                  import mx.controls.*;

                  [Bindable]private var _xmlTreeData:XML;

                  private function initApp():void
                  {
                  _xmlTreeData =
                  <node label="root">
                  <node label="RSS" data="100">
                  <node label="Feed 1" data="70"/>
                  <node label="Feed 2" data="10"/>
                  </node>
                  <node label="Mail" data="100">
                  <node label="Inbox" data="70">
                  <node label="Urgent" data="2"/>
                  <node label="Normal" data="3"/>
                  </node>
                  <node label="Personal Folder" data="10">
                  <node label="Business" data="2"/>
                  <node label="Demo" data="3"/>
                  <node label="Personal" data="0" isBranch="true" />
                  <node label="Saved Mail" data="5" />
                  </node>
                  <node label="Sent" data="15"/>
                  <node label="Trash" data="5"/>
                  </node>
                  </node>;
                  }//initApp

                  private function changeEvt(event:Event):void {
                  forChange.text = event.currentTarget.selectedItem.@label;
                  forChangeData.text = event.currentTarget.selectedItem.@data;
                  if(XMLTree1.selectedIndex) {
                  indexNum.text = XMLTree1.selectedIndex.toString();
                  }
                  }
                  private function itemOpenEvt(event:TreeEvent):void {
                  forOpen.text = event.item.@label;
                  }
                  private function itemCloseEvt(event:TreeEvent):void {
                  forClose.text = event.item.@label;
                  }
                  private function initTree():void {
                  var xmlNode:XML = _xmlTreeData.node[0];
                  XMLTree1.expandItem(xmlNode, true);
                  forOpen.text=XMLTree1.openItems[0].@label;
                  }
                  ]]></mx:Script>

                  <mx:Tree id="XMLTree1" width="150" height="170"
                  dataProvider="{_xmlTreeData}"
                  labelField="@label" itemOpen="itemOpenEvt(event);"
                  change="changeEvt(event);" showRoot="false"
                  creationComplete="initTree()" >
                  </mx:Tree>
                  <mx:Button label="Open" click="initTree();" />


                  <mx:Form>
                  <mx:FormItem label="Change Event Target:">
                  <mx:TextInput id="forChange" width="90" />
                  </mx:FormItem>
                  <mx:FormItem label="Change Event Target:">
                  <mx:TextInput id="forChangeData" width="90" />
                  </mx:FormItem>
                  <mx:FormItem label="Last Opened Node:" >
                  <mx:TextInput id="forOpen" width="90" />
                  </mx:FormItem>
                  <mx:FormItem label="Last Closed Node:">
                  <mx:TextInput id="forClose" width="90" />
                  </mx:FormItem>
                  <mx:FormItem label="Index Number:">
                  <mx:TextInput id="indexNum" width="90" text="{XMLTree1.selectedIndex}" />
                  </mx:FormItem>
                  </mx:Form>
                  </mx:Application>
                  • 7. Re: Expanding Tree Item for Tree with showRoot=&quot;false&quot;
                    Josh Johnson Level 1
                    Thanks Tracy. I appreciate you taking the time to work through this.
                    • 8. Re: Expanding Tree Item for Tree with showRoot=&quot;false&quot;
                      ntsiii Level 3
                      Sure. A simple, runnable demo app with a repeatable problem is almost irresistable!

                      Tracy