Dragging and Dropping

Enabling Drag and Drop Internally

The advancedTree component has built-in capabilities to handle drag and drop functionality. By setting the component's draggable property to true, a developer can allow nodes to be dragged internally within the tree. In this case all dropped nodes are considered valid drops, meaning that the component will allow any node to be moved and dropped anywhere else in the tree structure. The exceptions are that the root node can never be dragged and nodes cannot be dragged "into" themselves, or into any of their children (i.e., a parent node cannot be dragged and dropped into its first child node). To limit which nodes can be dragged and where they may be dropped, developers can use the advancedTree's validator, discussed in the Validation section of this guide.

To enable drag and drop within a advancedTree instance, set its draggable property to true in either the Component Inspector panel, the Properties panel or through ActionScript, as in the following example:

// enables drag and drop within the tree
tree.draggable = true;

Enabling Dropped Nodes from Other Trees

To handle drag and drop, the advancedTree component instatiates and utilizes a global DragManager object. The developer can take advantage of this same object to enable a advancedTree instance to listen and respond to the drag and drop of nodes from other advancedTree instances. The steps to do this are as follows:
  1. To use the DragManager, a advancedTree instance needs to already be instantiated on the stage, either through attachMovie or by manual placement in the IDE.
  2. // attaches two tree instances to the stage
    attachMovie("advancedTree", "tree_1", 0);
    attachMovie("advancedTree", "tree_2", 1);

  3. Add the advancedTree instances as listeners to the global DragManager. To simply enable drag and drop from any other tree without any additional validation, use the following code:
  4. // enables tree_1 and tree_2 to have draggable nodes internally
    tree_1.draggable = true;
    tree_2.draggable = true;

    // enables tree_1 and tree_2 to receive nodes from other trees
    DragManager.addListener(tree_1, "TreeNode", "onDragNode", "onDropNode", "external");
    DragManager.addListener(tree_2, "TreeNode", "onDragNode", "onDropNode", "external");

Overriding the Default Drag and Drop Functionality

As hinted at in the previous section, it is possible to override the default functionality of a advancedTree component instance's drag and drop, both for internal and external node drops. This is useful if additional validation or user confirmation is required before the tree can be updated. For instance, you may wish for the application to prompt the user before committing a drop.

Developers can simply pass the names of developer-defined functions to the DragManager in the addListener call, which was explained in the last section. For overriding internal drag and drop, the final parameter would be "internal" as opposed to "external". The function names passed in this method must reside on the instance itself, as demonstrated in the following steps.
  1. To use the DragManager, a advancedTree instance needs to already be instantiated on the stage, either through attachMovie or by manual placement in the IDE.
  2. // attaches a tree instance to the stage
    attachMovie("asdvancedTree", "tree", 0);

  3. Add the advancedTree instance as a listener to the global DragManager. To override the default drag and drop functionality, pass in the names of developer-defined functions to the call.
  4. // enables tree to have draggable nodes internally
    tree.draggable = true;

    // overrides the calling of the internal method when a node is dropped so that a developer-defined method may be called
    // the onDragNode method is NOT overridden, as in this instance the default functionality is desired
    DragManager.addListener(tree, "TreeNode", "onDragNode", "onValidateDrop", "internal");

  5. The new method is defined in the scope of the advancedTree instance. Note the arguments automatically sent to this method.
  6. import com.flashloaded.ui.controls.lists.TreeNode;

    // a new method that will be called when a node is dropped internally in the tree
    // NOTE: this method represents exactly what happens internally by default
    // NOTE: you would only override this if you wanted to change the default functionality
    tree.onValidateDrop = function(
      draggedClip:MovieClip, // clip being dragged on stage
      node:TreeNode, // the TreeNode instance being dragged and represented by the draggedClip
      position:Object, // an object with x and y properties holding the global position of the draggedClip
    ):Void {
      var scrollPos:Object = this.getScrollPosition(); // the current position of the scrollbars
      this.removeDropLine(); // removes visual cue from tree
      this.deselectNodes(); // deselects all nodes in tree
      var newNode:TreeNode = node.copyNode(); // copies dragged node
      this.addNodeAt(this.dropInfo.node, newNode, this.dropInfo.index); // adds copied node to dropped position
      node.remove(); // removes dragged node
      this.refresh(); // refreshes view of tree
      this.setScrollPosition(scrollPos.x, scrollPos.y); // puts scrollbars back to position before the refresh
    };

    Note the removeDropLine() method, which should be called when overriding the drag and drop functionality, as well as deselectNodes(). Also, dropInfo can be accessed, which holds the relevant information about the dragged/dropped node, such as the index to drop at and the node on which to drop (the new parent).