Sunday, April 4, 2010

Populate flex tree control on demand...

First, I am sorry if the same post is already posted here but after spending 30 minutes or may be more I could not find the solution.

By the way I have two problems. 1.) I am new to flex which I know if my own problem and soon I will handle it.

2.) This is major problem for me. I have to populate Tree control from database and I used HTTPService to get the data from database.

I created a object of HTTPService and on load of Tree control I am calling a function which calls the HTTP URL and returns me the first level of node for my Tree.

When I click on any node a function is called again using HTTPService and result is appended to the currently selected node. The same goes until n level and it works fine. I was happy with my results. I am stuck in new problem. The problem is if the tree is already populated on my browser and I make some add/update/delete any node or child node, the flex doesn't make a call to HTTP URL and I am not getting updated data.

The mxml code is below (this code has some extra things too).

%26lt;?xml version=''1.0'' encoding=''utf-8''?%26gt;
%26lt;mx:Application xmlns:mx=''http://www.adobe.com/2006/mxml''
layout=''vertical''?backgroundGradientAlphas=''[1.0, 1.0]''
backgroundGradientColors=''[#000000, #868686]'' %26gt;
%26lt;mx:Script%26gt;
?%26lt;![CDATA[
import mx.utils.StringUtil;
import mx.rpc.http.HTTPService;
import mx.events.ListEvent;
import mx.binding.utils.BindingUtils;
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.collections.XMLListCollection;
import mx.utils.ObjectProxy;
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
import mx.utils.ArrayUtil;

[Bindable]
public var datalist:XMLListCollection = new XMLListCollection();

[Bindable]
public var xmlFromDatabase:HTTPService=new HTTPService();

[Bindable]
private var xmlForChildren:HTTPService;

private function resultHandler( event:ResultEvent ):void
{
var x:XML = event.result as XML;?
var xl:XMLList = XMLList( x );
}

private function faultHandler( event:FaultEvent ):void
{
?Alert.show(event.message.toString());
}

private function display():void
{
?var params:Object = {};
?params[''parent''] = ''0'';

?xmlFromDatabase.url = ''http://localhost:8080/GrailsFlex/department/tree'';
?xmlFromDatabase.method = ''GET'';
?xmlFromDatabase.resultFormat = ''e4x'';
?xmlFromDatabase.useProxy = false;
?xmlFromDatabase.send(params);
?xmlFromDatabase.addEventListener(ResultEvent.RESULT,displyTree,false,0,false);
}


private function displyTree(event:ResultEvent):void
{
?XMLtree1.dataProvider =?event.result;
?XMLtree1.labelField = ''@name'';
}

private function getChilds(event:ListEvent):void
{
?try
?{
var xmlTree:Tree = event.currentTarget as Tree;

var node:XML = xmlTree.selectedItem as XML

var params:Object = {};

params[''parent''] = node.@id;
?
xmlForChildren = new HTTPService();
xmlForChildren.url = ''http://localhost:8080/GrailsFlex/department/tree'';


xmlForChildren.method = ''GET'';
xmlForChildren.resultFormat = ''e4x'';
xmlForChildren.useProxy = false;
xmlForChildren.send(params);

xmlForChildren.addEventListener(ResultEvent.RESULT,appendChild,false,0,false);
xmlForChildren.addEventListener(ListEvent.ITEM_CLICK,getChilds,false,0,false);
?}
?catch (E:Error)
?{
Alert.show(''getChilds Error:-- '' + E.message);
?}
}

private function deleteTreeNode(xmlItem:XML):void
{
?var xmlParent:XML = XML(xmlItem).parent();
?
?if (xmlParent.@parent == null || StringUtil.trim(xmlParent.@parent) == '''')
?{
xmlParent.@parent = ''0'';
?}
?
?if (xmlParent.@parent != ''0'')
?{
//Recursive call until I get reach to children of root node
deleteTreeNode(xmlParent);
?}
?else
?{
// Now I am at root.
var xmlRoot:XML = XML(xmlParent).parent();

var bActualRoot:Boolean = false;

if (xmlRoot == null)
{
?xmlRoot = xmlParent;
?bActualRoot = true;
}

if (bActualRoot)
{
?if (xmlRoot.@parent == ''0'')
?{
try
{
?for each (var xl:XML in xmlParent.children())
?{
if (xl.@name != xmlItem.@name)
{
?for (var cn:int=xl.children().length()-1; cn %26gt;=0; cn--)
?{
delete xl.children()[cn];
?}
}
?}
}
catch (ex:Error)
{
?Alert.show(''error Real Root: '' + ex.toString());
}
?}
}
else
{
?for each (var nodexm:XML in xmlRoot.children() )
?{
if (nodexm.@name != xmlParent.@name )
{
?try
?{
for (var cu:int=nodexm.children().length()-1; cu %26gt;=0; cu--)
{
?delete nodexm.children()[cu];
}
?}
?catch (ex:Error)
?{
Alert.show(''error No Real Root: '' + ex.toString());
?}
}

?}
}


?}
}

private function appendChild(event:ResultEvent):void
{
?
?var node:XML = event.result as XML
?
?var sItem: XML = XMLtree1.selectedItem as XML;
?
?if (sItem.children().length() %26gt; 0)
?{
delete sItem.children();
?}
?
?
?for(var i:int=0; i %26lt; node.children().length(); i++)
?{
?var item:XML = node.children()[i];

?XMLtree1.selectedItem.appendChild(item);
?XMLtree1.expandItem(XMLtree1.selectedItem,true,true);
?}
?
?deleteTreeNode(XML(XMLtree1.selectedItem));
}
?]]%26gt;
%26lt;/mx:Script%26gt;



%26lt;mx:Tree id=''XMLtree1'' width=''350'' height=''470''
?showRoot=''false'' creationComplete=''display()'' itemClick=''getChilds(event)''?/%26gt;


%26lt;/mx:Application%26gt;

Thanks in advance

Populate flex tree control on demand...

Looks like nobody knows how to do it.

Populate flex tree control on demand...

I am also interested in this solution.?I'm trying to accomplish something a little different, but any insight into your solution should help me with mine. I'm trying to populate a tree via webservice.?For me the backend is standard SOAP WebService implemented in ASP.NET.?I suspect my problem has something to do with mapping the datastructure I am returning to that of the tree, but I am at a loss for how right now.?Anyway, I hope you do get an answer to yours.?Sorry I couldn't help.

-- Matthew

try this

%26lt;mx:Tree id=''XMLtree1'' width=''350'' height=''470''
?showRoot=''false'' change=''display()'' itemClick=''getChilds(event)''?/%26gt;

this should work when you add or delete a node.

also, make sure to populate the tree at the first time.

Thanks buddy for the answer.

Unfortunately the answer came after quite long time of posting the message. Anyway I was able to open a tree on demand using HttpService and due to my new requirement I changed it to RemoteObject.

I my latest change I am able to populate tree nodes on demand and also the same solution if getting update from server via JMS using Consumer object.

I kind a like this solution because it took me good amount of effort to find the right solution.

If any one is intersted the he/she can reply to the post and I can provide code here or may at some location so that it can be easily downloaded.

The solution is Flex-Grails combination.

Thanks everybody.

No comments:

Post a Comment