0 Replies Latest reply on Jul 21, 2009 7:18 AM by Vrellin

    Allow conditional drag and drop per node on XML tree

    Vrellin

      I have struggled for 2 days wondering how I could apply a conditional drag and a conditional drop depending where I stood in my XML tree. I have been searching on internet for a solution but didn't found any that was replying to my issue.

       

      Therefore I post here under my solution in case it is useful to other people:

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
         
          <mx:Script>
              <![CDATA[
                  import mx.controls.Alert;
                  import mx.managers.*;
                  import mx.events.*;
                 
                  private var itemDragged:Array = [null,null];
                  private var myDragTarget:String = new String;
                  private var myDropTarget:String = new String;
                 
                  private function dragOverHandler(e:DragEvent):void {
                      e.currentTarget.showDropFeedback(e);
                      // find out which node you are rolling over from the DragEvent
                      var dropIndex:int = tree.calculateDropIndex(e);
                      var currentHover:XML = XML(tree.indexToItemRenderer(dropIndex).data);
                      var currentHoverType:String = currentHover.name().toString();
                      // store for output.text purposes
                      itemDragged[1] = currentHover;
                      myDropTarget = (itemDragged[1] as XML).@label;
                      // Your conditions wether the tree is dropEnabled or not
                      if (currentHoverType == "planet" && currentHover.children().length() == 0) {
                          tree.dropEnabled = true;
                      } else if (currentHoverType == "moon" && (currentHover.parent() as XML).name().toString() == "planet") {
                          tree.dropEnabled = true;
                      } else {
                          tree.dropEnabled = false;
                          DragManager.showFeedback(DragManager.NONE);
                      }
                      output.text = "Hover type: "+currentHoverType+", Drag: "+tree.dragEnabled+", Dragged Node: "+myDragTarget+", Drop: "+tree.dropEnabled+", Drop Node: "+myDropTarget;
                  }
                 
                  private function onItemRollOver(e:ListEvent):void {
                      // tree needs to start dropEnabled or you wont be able to receive the dragOver event
                      tree.dropEnabled = true;
                      // find out which node you are rolling over from the ListEvent
                      var dragIndex:int = tree.indicesToIndex(e.columnIndex,e.rowIndex);
                      var currentHover:XML = XML(tree.indexToItemRenderer(dragIndex).data);
                      var currentHoverType:String = currentHover.name().toString();
                      // store for output.text purposes
                      itemDragged[0] = currentHover;
                      myDragTarget = (itemDragged[0] as XML).@label;
                      // Your conditions wether the tree is dragEnabled or not
                         switch (currentHoverType) {
                             case "moon" :
                                 tree.dragEnabled = true;
                                 break;
                             default :
                                 tree.dragEnabled = false;
                                 break;
                         }
                         output.text = "Hover type: "+currentHoverType+", Drag: "+tree.dragEnabled+", Dragged Node: "+myDragTarget+", Drop: "+tree.dropEnabled+", Drop Node: "+myDropTarget;
                  }
              ]]>
          </mx:Script>
         
          <!-- drag&drop moons inside a planet folder to reorder them -->
         
          <mx:XML id="solarSystem">
              <solarSystem label="Système solaire">
                  <planet label="Planet 1" isBranch="true"/>
                  <moon label="Moon 1.1"/>
                  <moon label="Moon 1.2"/>
                  <moon label="Moon 1.3"/>
                  <planet label="Planet 2" isBranch="true"/>
                  <moon label="Moon 2.1"/>
                  <moon label="Moon 2.2"/>
                  <moon label="Moon 2.3"/>
              </solarSystem>
          </mx:XML>
         
          <mx:Tree id="tree" width="300" height="300" labelField="@label"
              dataProvider="{solarSystem}" itemRollOver="onItemRollOver(event)" dragOver="dragOverHandler(event)"
              dropEnabled="true"/>
          <mx:Text id="output"/>
      </mx:Application>

       

      If someone knows an easier way to do this I'll be pleased to hear about. In the meantime the solution above works fine.

       

      Cheers,

       

      Olivier.