3 Replies Latest reply on Aug 6, 2006 9:03 AM by BlueRealm

    expandItem super weird behavior

    takak
      Okay, now this will stump a few of you:

      I have a Tree. Simple, right? So far, yes. BUT I want to update that tree's dataProvider when I press a button. Now the tricky thing is that when I update the dataProvider the data comes back and it might be in a different order and the folders (branches) and nodes (leafs) will not be in the same index position as before.

      So, I need to basically iterate through tree.openItems, store the id's of the relevant items that are open in the tree and then store those values in an array. Then, after my tree is updated, loop through that array and based on the values in the array (the id's which always stay the same, no matter what position or index the branches/leaves have) open the items which were opened before I updated the dataProvider.

      Simple in theory, but in application, I get very weird behavior. My code looks like this:

      public var catOpened:Array = new Array();
      public var updateItems:Boolean = false;

      <!-- This is the function that gets called when you click on the button that updates the dataProvider -->
      public function updateCategory():void{
      for(var x:String in cat_tree.openItems){
      catOpened[x] = cat_tree.openItems[x].@id;
      //Alert.show(cat_tree.openItems[x].@id);
      }
      updateItems = true;
      categories_list_http.send();
      }

      <!-- This is the function that gets called on render -->
      public function updateCategoriesTree():void{
      if(updateItems == true){
      for(var x:String in catOpened){

      //Alert.show(categories_list.node.(@id==catOpened[x])[0]);
      cat_tree.validateNow();
      cat_tree.expandItem(categories_list.node.(@id==catOpened[x]),true,false,false);
      }
      updateItems = false;
      }
      }

      My HTTPService's result format is e4x. This should work, right?

      But what I get back is a weird named folder in each of the previously opened items, named something like "E31781EA-D5D2-0301-151E-BB3412BF099C" and in that folder a node called exactly the same thing. The good news is that it isn't totally off the mark because it at least puts that weird folder inside the folder which expandItems is actually supposed to open.

      I posted a screenshot at: http://able.org/dev/screenshot2.jpg

      The "Applied Scholastics" and "Criminon" folders were the folders that were opened before updating the dataProvider, when updated they don't reopen, but just have weird folders, I opened them myself for the purpose of the screenshot.

      Any ideas? I'm stumped.

      Thanks!

        • 1. Re: expandItem super weird behavior
          takak Level 1
          Wow, everybody don't all reply at once!

          Okay, so I figured it out by myself. I don't know why the other method wasn't working, but if I change my code for expandItem to read as:

          cat_tree.expandItem(categories_list.node[categories_list.node.(@id==catOpened[x]).childInd ex()],true,false,false);

          it works fine. Beats me... maybe this is a bug that somebody on the Flex Developer team should check out.

          Anyways, moving on. I just have one last thing to figure out now, basically if I have an opened folder 3 levels down, it obviously won't work as above because what I would really have to do would be something like:

          cat_tree.expandItem(categories_list.node.node.node[categories_list.node.node.node(@id==cat Opened[x]).childIndex()],true,false,false);

          but it would have to detect the level automatically or I would have to add some sort of a while statement in there or something. Does e4x support something that would handle this?

          Anyways, if somebody figures it out before I do (doubtful if its stays the way it's been) then please let me know!

          I posted the answer cause I thought it would probably help a few people out who might be having a similar problem or tyring to figure out the same thing.

          - Taka
          • 2. Re: expandItem super weird behavior
            takak Level 1
            Okay, I figured it ALL out now (finally).

            I am (once again) posting the answer so that anybody who tries such a feat in the future won't have to go through what I went through.

            It all lies in one (SIMPLE - well, somewhat simple) line of code. This has got to be longest it has taken me to figure out how to do something which only really took one line of code! Well, here it is:

            cat_tree.expandItem(categories_list..node.(@id==catOpened[x]).parent().node[categories_lis t..node.(@id==catOpened[x]).childIndex()],true,false,false);

            And that's probably one of the longest lines of codes without whitespaces, you will ever see.

            So, my functions now look like:

            public var catOpened:Array = new Array();
            public var AlreadyOpened:Array = new Array();
            public var updateItems:Boolean = false;

            public var catVScroll:Number = 0;
            public var catHScroll:Number = 0;

            // CATEGORY TREE FUNCTIONS

            public function addCategory():void{
            if(updateItems === false){
            captureCatTreeSettings();

            var rVars:Object = new Object();
            rVars.category = cat_tree.selectedItem.@id;
            rVars.add_cat = true;
            categories_list_http.send(rVars);
            }
            }

            private function captureCatTreeSettings():void{
            catOpened = new Array();
            for(var x:String in cat_tree.openItems){catOpened.push(cat_tree.openItems[x].@id);}
            catHScroll = cat_tree.horizontalScrollPosition;
            catVScroll = cat_tree.verticalScrollPosition;
            }

            public function removeCategory():void{
            if(updateItems === false){
            // You can't delete a category with groups in it as you could cause serious harm to the database and people wold go "missing".
            if(groups_list.children().length() == 0 && cat_tree.selectedItem..children().length() == 0){
            captureCatTreeSettings();
            var rVars:Object = new Object();
            rVars.category = cat_tree.selectedItem.@id;
            rVars.remove_cat = true;
            categories_list_http.send(rVars);
            }
            else{
            Alert.show("Cannot delete an unempty category!");
            }
            }
            }

            private function updateCategory():void{
            if(updateItems === false){
            captureCatTreeSettings();
            var new_name:String = TextInput(cat_tree.itemEditorInstance).text;

            var rVars:Object = new Object();
            rVars.category = cat_tree.selectedItem.@id;
            rVars.new_name = new_name;
            categories_list_http.send(rVars);
            }
            }

            public function updateCategoriesTree():void{
            if(updateItems === true){
            cat_tree.invalidateDisplayList();
            AlreadyOpened = new Array();
            for(var x:String in catOpened){
            if(AlreadyOpened.indexOf(catOpened[x]) === -1){
            cat_tree.expandItem(categories_list..node.(@id==catOpened[x]).parent().node[categories_li st..node.(@id==catOpened[x]).childIndex()],true,false,false);
            }
            }
            cat_tree.validateDisplayList();
            cat_tree.verticalScrollPosition = catVScroll;
            cat_tree.horizontalScrollPosition = catHScroll;
            updateItems = false;
            }
            }

            And my categories_list_http HTTPService tag looks like:

            <mx:HTTPService id="categories_list_http" url="data/xml/categories_list.php" useProxy="false" resultFormat="e4x" method="POST" result="updateItems=true"/>

            And my cat_tree Tree tag looks like:

            <mx:Tree id="cat_tree" dataProvider="{categories_list}" editable="false" labelField="@label" showRoot="false" width="375" height="250" change="event.currentTarget.editable=false;updateGroups()" itemClick="event.currentTarget.editable=true" itemEditEnd="event.currentTarget.editable=false;updateCategory()" updateComplete="updateCategoriesTree()"/>

            Wow! It was as simple as that. The key lies in the ".." (descendant) descriptor. e4x is actually pretty darn cool when you start to get the hang of it.

            Talk about a learning curve, it's probably better classified as a learning "right angle". I am glad I took the time I took to figure that out though, as I learned A LOT along the way.

            Well, hope that helps somebody in the future.

            Over and out - Taka
            • 3. expandItem super weird behavior
              BlueRealm
              I ran into the same issue with the tree not being able to resore the open items. I came up with a solution that may be a little easier to read and manage that your posted solutions. Just thought i would post it for anyone else running into this issue.

              XML EXAMPLE:

              <node label="Mail" data="100">
              <node label="Inbox" data="70" level="0"/>
              <node label="Personal Folder"data="10" level="0">
              <node label="Business" data="2" level="1"/>
              <node label="Demo" data="3" level="1">
              <node label="test" data="6" level="2"/>
              <node label="test 1" data="73" level="2"/>
              <node label="test 3" data="75" level="2">
              <node label="test 4" data="76" level="3"/>
              <node label="test 5" data="77" level="3"/>
              </node>
              <node label="test 2" data="74" level="2"/>
              </node>
              <node label="Personal" data="0" level="1"/>
              <node label="Saved Mail" data="5" level="1"/>
              </node>
              <node label="Sent" data="15" level="0"/>
              <node label="Trash" data="5" level="0"/>
              </node>


              CODE EXAMPLE:

              <?xml version="1.0" encoding="utf-8"?>
              <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns:t="*" layout="absolute" creationComplete="DP.send()">
              <mx:Script>
              <![CDATA[

              [Bindable]
              private var tempObject:XMLList;
              private var tempOpen:Object = new Object();
              private var openItems:Array = new Array;
              private var selectedItems:String = "";

              private function initFunc():void
              {
              tempObject = DP.lastResult.node;
              }

              private function saveOpen():void
              {
              var id:String;
              var i:int = 0;
              if(this.myTree.selectedItem != null){
              this.selectedItems = this.myTree.selectedItem.@data;
              }
              openItems = new Array;
              for each(var item:XML in this.myTree.openItems){
              id = item.@data;
              openItems[i++] = id;
              }
              }
              private function initOpen():void
              {
              var id:String;
              var j:int;
              var prnt:XML;
              for each(var item:XML in tempObject){
              id = item.@data;
              if(openItems.indexOf(id) >= 0){
              this.myTree.expandItem(item,true);
              }
              if (this.selectedItems == id){
              this.myTree.selectedItem = item;
              }
              for each(var chld:XML in item.descendants()){
              id = chld.@data;
              if(openItems.indexOf(id) >= 0){
              this.myTree.expandItem(chld,true);
              }
              if (this.selectedItems == id){
              this.myTree.selectedItem = chld;
              }
              }
              }
              }


              ]]>
              </mx:Script>


              <mx:HTTPService
              url="test.xml" concurrency="single"
              resultFormat="e4x"
              id="DP"
              makeObjectsBindable="true" result="initFunc();"/>

              <mx:VBox width="400" height="400" >
              <mx:Tree
              id="myTree"
              width="100%"
              labelField="@label"
              height="100%"
              dataProvider="{tempObject}"
              itemClose="saveOpen();"
              itemOpen="saveOpen();"
              itemClick="saveOpen();"
              valueCommit="initOpen();"/>
              <mx:Button label="refresh data" click="DP.send()"/>
              </mx:VBox>
              </mx:Application>