1 Reply Latest reply on Dec 17, 2007 6:16 PM by ntsiii

    AdvancedDataGrid ItemOpener how-to

    binkerboy
      Hi. I need a way to show the ADG open and close pointers, even if there are no children (or another idea on how to this). What I am trying to do is populate the ADG when the user makes two combo box selections with XML. This is ONLY the parents. No children at this time. When the user clicks on one of the itemOpen arrows to expand the item and see its children, I will then make a call to the database, get the children, add them to the XML at the appropriate spot and refresh the ADG. The problem I have right now is that parents are not aware of whether there are children in the database (I guess we could change this). I don't want to tax the server, asking it if there are x children per parent if.

      The reason is that we can have a lot of parents and children, potentially thousands, but the user may only need to see into one item and its descendants, so we don't want to push all the data over the wire. I have included some testing code. As you can see, when you get to the third child, there is no arrow.

      Oh, also, is there a way to delete a child from the XML? I thought about returning a "dummy" child, which, on itemOpen, is removed and replaced with the real children.

      I am open to suggestions. Thanks.

      (skinnied down version for testing, with combo's removed and fake XML)

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initMakeXML()" width="1000" height="1000">

      <mx:Script>
      <![CDATA[

      import mx.utils.*
      import mx.collections.*;
      import mx.controls.Alert
      import mx.core.UIComponent;
      import mx.events.AdvancedDataGridEvent


      [Bindable]
      public var mainTree:XML;

      private function initMakeXML():void {
      //lets make some parent XML
      mainTree = new XML("<HIERARCHY NAME = 'Test Parent'></HIERARCHY>");
      var PKIDcount:int = 99
      var PKIDcount1:int = 299
      var PKIDcount2:int = 499

      for (var i:int = 0; i < 100; i++)

      {
      PKIDcount = (PKIDcount + 1)
      PKIDcount1 = (PKIDcount1 + 1)
      PKIDcount2 = (PKIDcount2 + 1)
      var newnode:XML = new XML();
      newnode =

      <node NAME={"Parent " + i} PKID={PKIDcount} MASS="100" WEIGHT="150" LENGTH="40">

      <node NAME="1 - TestMakeChildPlaceHolder" PKID={PKIDcount1}
      DESCRIPTION="This causes the little arrow for the item opener to show.">

      <node NAME="2 - TestMakeChildPlaceHolder" PKID={PKIDcount2}
      DESCRIPTION="This causes the little arrow for the item opener to show.">
      </node>

      </node>

      </node>;

      mainTree = mainTree.appendChild(newnode);

      }

      adgHierarchy.dataProvider = new HierarchicalData(mainTree);
      rawXML.text = mainTree.toXMLString();
      adgHierarchy.validateNow();
      callLater(expandFirstNode);

      /* called by callLater to ensure that the tree is ready to have expandItem called on it. Works. From Tracy.*/
      function expandFirstNode():void
      {
      adgHierarchy.expandItem(mainTree, true); //expand the node
      }
      }


      public var alreadyOpened:Array = new Array;
      public var alreadyOpenedAC:ArrayCollection = new ArrayCollection(alreadyOpened);

      private function addChildXML(evt:AdvancedDataGridEvent):void {
      var containsPKID:Boolean = alreadyOpenedAC.contains(evt.item.@PKID.toString()); //lets see if the PKID is in the array

      if (containsPKID == false) { //if it contains the PKID, skip running the code below

      alreadyOpenedAC.addItemAt(evt.item.@PKID.toString(), 0); //if we do open the tree item, add the PKID so we will skip opening it next time
      txtPKID.text = alreadyOpenedAC.toString(); //view the array as it grows

      txtChildPositionXML.text = mainTree.descendants().(@PKID == evt.item.@PKID.toString());

      }

      }

      ]]>
      </mx:Script>

      <mx:AdvancedDataGrid width="900" height="291" editable="true"
      id="adgHierarchy" x="6.5" y="10" itemOpen="addChildXML(event)"
      >
      <mx:columns>
      <mx:AdvancedDataGridColumn dataField="@NAME"
      headerText="Name" editable="true" width="300" />
      <mx:AdvancedDataGridColumn dataField="@DESCRIPTION"
      headerText="Description" editable="true"/>
      <mx:AdvancedDataGridColumn dataField="@PKID"
      headerText="PKID" editable="false"/>
      <mx:AdvancedDataGridColumn dataField="@MASS"
      headerText="Mass" editable="false"/>
      <mx:AdvancedDataGridColumn dataField="@WEIGHT"
      headerText="Weight" editable="false"/>
      <mx:AdvancedDataGridColumn dataField="@LENGTH"
      headerText="Length" editable="false"/>
      </mx:columns>
      </mx:AdvancedDataGrid>

      <mx:Label x="10" y="309" text="mainTree XML" color="#FFFFFF" fontStyle="normal" fontWeight="bold"/>
      <mx:TextArea x="10" y="338" height="90" id="rawXML" width="900"/>

      <mx:Label x="10" y="453" text="mainTreeChildren XML" color="#FFFFFF" fontStyle="normal" fontWeight="bold"/>
      <mx:TextArea x="10" y="479" height="90" id="rawXML0" width="900"/>

      <mx:Label x="10" y="577" text="Child Position in XML" color="#FFFFFF" fontWeight="bold"/>
      <mx:TextArea x="10" y="603" height="123" id="txtChildPositionXML" width="900"/>

      <mx:Label x="10" y="734" text="Child Position in Grid" color="#FFFFFF" fontWeight="bold"/>
      <mx:TextArea x="10" y="760" height="23" id="txtChildPositionGrid" width="572"/>

      <mx:Label x="10" y="791" color="#FFFFFF" fontWeight="bold" text="PKIDs"/>
      <mx:TextArea x="10" y="817" height="54" id="txtPKID" width="572"/>

      </mx:Application>

        • 1. Re: AdvancedDataGrid ItemOpener how-to
          ntsiii Level 3
          I'll take the easy one. To delete a node from XML, use the delete operator:
          delete myXml.myNode.(@myAttr=myValue)[0];

          Yes, this is really the way. E4x has no "removeChild" method, amazingly.

          Note, you CANNOT do this delete with a variable, you will get an error if you try.

          If you are using an XMLListCollection, you can use removeChildAt()

          Tracy