Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8966361
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T17:00:41+00:00 2026-06-15T17:00:41+00:00

In an application I’m building with Flex, I have a Flex Tree with XML

  • 0

In an application I’m building with Flex, I have a Flex Tree with XML as its data provider. The user needs to be able to create layers and folders to hold those layers (think Photoshop). The user also needs to be able to rearrange those items at will, and drag layers into folders (and folders into other folders if so desired, etc.).

Here is a test application I’ve made showcasing what I’m trying to do. I’ve stripped it down to be as basic as possible for simplicity’s sake.

(NOTE: I’m creating the XML in my code with a dummy node inside, and then deleting that node at runtime. This is the only way I’ve found that will have the Tree completely blank on startup. (Just having an empty root node causes that root node to be visible in the tree, even if showRoot is false.) If there’s a better way to achieve that effect, please let me know.)

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">

    <fx:Script>
        <![CDATA[
            import com.custom.model.service.XMLService;

            import mx.events.DragEvent;
            import mx.events.FlexEvent;
            import mx.utils.ObjectUtil;

            protected function treeInit(event:FlexEvent):void
            {
                layersTree.expandChildrenOf(layers_xml, true);

                /*delete the dummy XML node so that the tree is clean on startup 
                and doesn't show the root folder*/
                XMLService.deleteNodeById(layers_xml, 'dummy');
            }

            protected function newFolderClick(event:MouseEvent):void
            {
                // Form New XML Node..
                var xmlObj:Object = XMLService.formFolderXML();

                //...and add it to the XML file.
                if(!layers_xml.children()[0]){
                    //if there are no child nodes, add normally
                    layers_xml.source = xmlObj.xmlNode;
                }else{
                    //if there are child nodes, add them before the previous node
                    layers_xml.prependChild(xmlObj.xmlNode);
                }

                /*immediately expand the folders to allow them to be dragged into,
                closed folders cannot be dragged into*/
                layersTree.expandChildrenOf(layers_xml, true);
            }

            protected function newTextLayerClick(event:MouseEvent):void
            {
                // Form New XML Node..
                var xmlObj:Object = XMLService.formTextLayerXML();

                //...and add it to the XML file.
                if(!layers_xml.children()[0]){
                    //if there are no child nodes, add normally
                    layers_xml.source = xmlObj.xmlNode;
                }else{
                    //if there are child nodes, add them before the previous node
                    layers_xml.prependChild(xmlObj.xmlNode);
                }

                //programatically select THIS item so it highlights in the tree
                layersTree.selectedIndex = (layersTree.showRoot) ? 1 : 0;
            }

            protected function onDragDrop(event:DragEvent):void
            {
                trace('action:', event.action);
                trace('dragDrop', ObjectUtil.toString(layers_xml));
            }

            protected function onDragComplete(event:DragEvent):void
            {
                trace('action:', event.action);
                trace('dragComplete', ObjectUtil.toString(layers_xml));
            }

        ]]>
    </fx:Script>

    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->

        <fx:XML id="layers_xml">
            <layers label="root" id="root">
                <layer label="DummyLayer2" type="layer" id="dummy" isVisible="false" />
            </layers>
        </fx:XML>

    </fx:Declarations>

    <s:VGroup gap="0" width="100%">

        <mx:Tree id="layersTree" width="100%" minHeight="41" allowMultipleSelection="false"
                 borderVisible="false" creationComplete="treeInit(event)"
                 dataProvider="{layers_xml}" dragEnabled="true" dropEnabled="true" 
                 focusColor="#FFFFFF" labelField="@label"
                 rollOverColor="#D1EEEE" selectionColor="#D1EEEE" showRoot="false" 
                 dragDrop="onDragDrop(event)" dragComplete="onDragComplete(event)"/>

        <s:Group width="100%">
            <s:HGroup id="layerButtons" horizontalCenter="0">
                <s:Button id="newFolderBtn" label="Folder" buttonMode="true"
                         click="newFolderClick(event)"/>
                <s:Button id="newTextFieldBtn" label="TextLayer" buttonMode="true"
                    click="newTextLayerClick(event)" />
            </s:HGroup>
        </s:Group>

    </s:VGroup>

</s:Application>

Here is the class (XMLService) I’m using to generate the XML nodes to be inserted into the tree.

package com.custom.model.service
{
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;

public class XMLService extends EventDispatcher
{

    private static var _folderLayerCount:int = 0;
    private static var _textLayerCount:int = 0;
    private static var _layerName:String;
    private static var _layerId:String;


    public function XMLService(target:IEventDispatcher=null)
    {
        super(target);
    }


    private static function randomId(length:int = 9):String{
        //function to generate randomId for XML
        var chars:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        var num_chars:Number = chars.length - 1;
        var randomChar:String = "";

        for (var i:Number = 0; i < length; i++){
            randomChar += chars.charAt(Math.floor(Math.random() * num_chars));
        }
        return randomChar;
    }


    public static function formTextLayerXML(name:String = null):Object {
        //this static function forms the xml node for text layers.
        _textLayerCount++;
        _layerId = randomId();
        _layerName = (name != null) ? name : ('Text Layer ' + _textLayerCount);

        var textNode:XML = new XML('<layer label="' + _layerName + '" type="textlayer" id="'+ _layerId +'" isVisible="true" />');

        //returns the node and the unique id as a string    
        return {xmlNode : textNode, id : _layerId};
    }

    public static function formFolderXML():Object {
        //this static function forms the xml node for folders.
        _folderLayerCount++;
        _layerId = randomId();
        _layerName = 'Folder ' + _folderLayerCount;

        var folderNode:XML = new XML('<folder label="' + _layerName + '" type="folder" id="'+ _layerId +'" isBranch="true" isVisible="true" />');
        //isBranch = true makes the node behave as a folder, even if it's empty

        //returns the node and the unique id as a string
        return {xmlNode: folderNode, id: _layerId}; 
    }

    public static function deleteNodeById(xml:XML, idToDelete:String):void {

        var count:int = 0; /*have to keep track of our own count
        because targeting will not work for xml deletes */
        var descendNodes:XMLList = xml.descendants();

        for each (var layer:XML in descendNodes) {
            if(descendNodes[count].@id == idToDelete) {
                delete descendNodes[count];
            }
            count++;
        }
    }

}
}

The problem I’m having is that when a folder and layer is created, and a layer is dragged into a folder, once that folder is dragged back out of the folder, a copy of the layer is created instead of the layer being moved.

A folder and a layer being dynamically created:

A folder and a layer being dynamically created

Dragging a layer inside of the folder:

Dragging a layer inside of the folder

What happens if the layer is now dragged OUTSIDE (and above) the folder:

What happens if the layer is now dragged OUTSIDE (and above) the folder

You can see this happen in the XML while tracing layers_xml on a dragComplete.

<layers label="root" id="root">
  <layer label="Text Layer 1" type="textlayer" id="GMccFXr5m" isVisible="true"/>
  <folder label="Folder 1" type="folder" id="JfoN1yo1I" isBranch="true" isVisible="true">
    <layer label="Text Layer 1" type="textlayer" id="GMccFXr5m" isVisible="true"/>
  </folder>
</layers>

The text layer (“Text Layer 1”) that was in “Folder 1” was copied outside of the folder node instead of being moved outside the folder node.

Now here’s the weird part.

This issue goes away if showRoot is set to true in the Tree Flex component. The problem is that the root node being visible in the tree is undesirable.

We make this small change to the Tree component:

showRoot="true"

Now take a look at layers_xml being traced if the very same steps are taken while showRoot is true:

<layers label="root" id="root">
  <layer label="Text Layer 1" type="textlayer" id="nwdwAwlML" isVisible="true"/>
  <folder label="Folder 1" type="folder" id="TdVbaPvPB" isBranch="true" isVisible="true"/>
</layers>

Have I run into a bug in Flex? Or is something in my code causing this to happen?

While any response or explaination of why this is happening is appreciated, answers that suggest I using any type of dataProvider other than XML won’t be of much help, as the application I’m building with this is too far into its final stages to make such a drastic change.

Thanks for the help!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T17:00:43+00:00Added an answer on June 15, 2026 at 5:00 pm

    After some more research, the issue has been solved.

    The cause of this issue is indeed a bug in Flex, as Flex gets wonky when dynamically adding items to the Tree control (as opposed to having a fixed data set which you can rearrange at will).

    The way around this is to capture a snapshot of the current openItems and scrollPosition, then manually reattach the dataProvider and re-validate the whole thing, so Flex doesn’t get confused on the current structure of the tree.

    I’ve built that function and called the function on a dragComplete event.

    protected function onDragComplete(event:DragEvent):void {
         //resetting the entire tree after every drag completes
        forceTreeRedraw(layersTree, layers_xml);
    }
    
    private function forceTreeRedraw(tree:Tree, dataProvider:Object):void {
        var scrollPosition:Number = tree.verticalScrollPosition;
        var openItems:Object = tree.openItems;
        tree.dataProvider = dataProvider;
        tree.openItems = openItems;
        tree.validateNow();
        tree.verticalScrollPosition = scrollPosition;
    }
    

    Problem magically solved, fluffy bunnies are frolicking and all is right with the world.

    All credit goes to the answer posted here:
    Flex: Updating a Tree control

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

My application now needs to create and then write files to a temp directory
Application: This is a workshop proposal system for a conference. A user can create
application design/architecture question for a project that I am building. I have a main
Application, have a TextBlock and two Buttons, the text is displayed TextBlock by clicking
Application is running in my local system app.config file <add key=dbconn value=Data Source=(local);database=VTech;User ID=sa;Password=sa;
Application stores configuration data in custom section of configuration file. This information is used
Application able to record error in OnError, but we are not able to do
Application requests KML data through AJAX from server. This data is stored in javascript
Application running in django, apache, python and mysql: I want to create global variable
Application uses Entity Framework 4.1 with database first approach. I have in database a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.