PDA

View Full Version : Displaying selectedItem in Tree component


tevin
10-05-2007, 11:12 AM
Hi,

I have a custom component that, when clicked, calls a webservice which returns an XML hierarchy. I set this hierarchy to be the dataProvider for a Tree component, which is then added to the childlist. I am searching the XML for a node which matches a specific id, and setting this node to be my Tree's selectedItem. It is finding my requested node ok, but I can't get the Tree to expand this node's parent nodes so that the selectedItem is visible. Here's my code:

private var myTree:Tree;
private var buttonText:TextField;
private var myWebservice:WebService;

//ctor
public function myComponent()
{
buttonText = new TextField();
buttonText.addEventListener(MouseEvent.CLICK, setupTree);

// Setup state change
var treeShown:State = new State();
treeShown.name = "tree_shown";
var addTree:AddChild = new AddChild(this, myTree);
treeShown.overrides[0] = addTree;
states.push(treeShown);
}




// Calls webservice to build hierarchy
private function setupTree(event:MouseEvent):void
{
myWebservice.build_hierarchy.addEventListener(Resu ltEvent.RESULT, onHierarchy);
myWebservice.build_hierarchy.send();
}




// Populates tree and sets selectedItem
private function onHierarchy(event:ResultEvent):void
{
if (event.result != null) {
myTree.dataProvider = new XML(event.result).node;
myTree.labelField = "@label";

// Searches all descendants for matching attribute
var selectedId:String = "requested_node";
var selectedNodes:XMLList = XML(myTree.dataProvider)..node.(@id==selectedId);

// Expands all parents above the matching node and sets that node to be our selectedItem
if (selectedNodes[0] != null) {
expand_parents(selectedNodes[0]);
myTree.selectedItem = selectedNodes[0];
}

currentState = "tree_shown";

}

}




// Expands each parent above the selected node
private function expand_parents(node:XML):void
{
// Validates tree so that expandItem() works...
myTree.validateNow();

while (node.parent() != null) {
node = node.parent();
myTree.expandItem(node, true);
}

}



My XML looks something like:
<nodes>
<node label="World" id="TOT">
<node label="Europe" id="EUR">
<node label="UK" id="UK"/>
<node label="Germany" id="GER"/>
<node label="France" id="FRA"/>
</node>
</node>
</nodes>



Any help would be appreciated.

Jim Freer
10-05-2007, 02:21 PM
This is the code I use:


// Ensure selected item and parents are expanded
lvXml = lvXmlSelected.parent();
while( lvXml )
{
Tree1.expandItem( lvXml, true );
lvXml = lvXml.parent();
} // while


Jim
http://freerpad.blogspot.com/

tevin
10-05-2007, 03:05 PM
That code is the same as my expand_parents() method, but with the node = node.parent() and expandItem() calls the other way around. Your way didn't work either...

Jim Freer
10-05-2007, 03:58 PM
This is one of maybe a dozen applications where I use my code and they all work: There are subtle differences between my code and yours.


private function onChangeAdvancedDataGrid1
( avListEvent :ListEvent )
:void
{
var lvXml:XML = XML( AdvancedDataGrid1.selectedItem );

var lvId:String = lvXml.attribute( mvIdFieldName ).toString();

var lvXmlListCollection:XMLListCollection
= XMLListCollection( Tree1.dataProvider );

var lvXmlSelected:XML =
lvXmlListCollection.descendants().
(
attribute( mvIdFieldName ) == lvId
)[0];

// Ensure selected item and parents are expanded
lvXml = lvXmlSelected.parent();
while( lvXml )
{
Tree1.expandItem( lvXml, true );
lvXml = lvXml.parent();
} // while

Tree1.selectedItem = lvXmlSelected;

} // onChangeAdvancedDataGrid1


Jim
http://freerpad.blogspot.com/

tevin
10-05-2007, 05:09 PM
I have tried your method as well, but that still doesn't work. I think it might be something to do with the Tree and its dataProvider not being set up correctly (yet) during the onHierarchy method. Any ideas?

Jim Freer
10-05-2007, 06:39 PM
This code works. I'm wondering if you are simply trying to call the expand before everything is loaded. Try a callLater to do your expansion.


<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:VBox width="100%" height="100%" >
<mx:TextArea width="100%" height="100%" id="lbl"/>
<mx:Tree width="100%" height="100%" id="Tree1" />
<mx:Button click="expand( 'GER' )"/>
</mx:VBox>
<mx:Script>
<![CDATA[
private function onCreationComplete
()
:void
{
var lvXml:XML =
<nodes>
<node label="World" id="TOT">
<node label="Europe" id="EUR">
<node label="UK" id="UK"/>
<node label="Germany" id="GER"/>
<node label="France" id="FRA"/>
</node>
</node>
</nodes>;

Tree1.labelField = "@label";
Tree1.dataProvider = lvXml.node;

} // onCreationComplete

// ---------------------------------------------------------------------
// expand
// ---------------------------------------------------------------------

private function expand
( avId :String )
:void
{
var lvXmlListCollection:XMLListCollection
= XMLListCollection( Tree1.dataProvider );

var lvXmlSelected:XML =
lvXmlListCollection.descendants().
(
attribute( "id" ) == avId
)[0];

lbl.text = lvXmlSelected.toXMLString() + "\n";

// Ensure selected item and parents are expanded
var lvXml:XML = lvXmlSelected.parent();
while( lvXml )
{
lbl.text += lvXml.toXMLString();
Tree1.expandItem( lvXml, true );
lvXml = lvXml.parent();
} // while

Tree1.selectedItem = lvXmlSelected;

} // menuItem

]]>
</mx:Script>
</mx:Application>


Jim
http://freerpad.blogspot.com/

Jim Freer
10-05-2007, 06:53 PM
Sorry while editing I left off:

import mx.collections.XMLListCollection;

tevin
10-08-2007, 10:23 AM
Ah-ha, I've discovered the problem. I was setting the dataProvider property of the Tree to the webservice result. I was then trying to use the dataProvider to get my selectedItem and using it as the reference to expand the tree. What I needed to do was store the result from the webservice in a separate variable and then use this as the reference for everything else. I also needed to use the callLater() method. Thanks for your help.