Flash output
| |
Complex Tree and DataGrid example
This example corresponds with the file TreeExample.fla that is supplied with the component. The following code loads the XML file sample.xml, parses it using the BgxDesObject class and then populates an instance of the Macromedia Tree component called bgxTree with the folder and page nodes of the XML.
It assigns click actions that display the label name and an active hyperlink in case of page nodes, a DataGrid with the list of child pages in case od folder nodes.
It further assigns double-click actions that expand/collapse folder nodes and load the associated page for page nodes.
Note: The Tree component allows very easy population of a tree by simply binding the XML directly to it, with XML elements containing label, data and isBranch attributes. Apart from the fact that it might not suit you to have those attributes in the XML or it would mean previous recursive parsing of the XML to add them, you cannot add complex data as treeNode data via a data attribute. The code below adds the node objects themselves as treeNode data. Therefore, if a node is clicked all data associated with that node is instantly available (see the line var newNode = treeNode.addTreeNode(nodeName,elementsArray[i]);)
Note also that within the setDisplay() function the nodeName property, added automatically if addNodeName is set to true, is used to determine whether a treeNode corresponds to an element of type folder (see if (dataObject.nodeName == "folder")).
The following is only one way how a tree can be populated. It will depend on the actual structure of the XML data or other parameters, like what kind of interaction is needed, do determine the best route on a case by case basis.
//import the class
import bgx.BgxDesObject;
import mx.controls.Tree;
//hide DataGrid
dgPages._visible = false;
//global variable to hold deserialized sample data
var SampleData:Object;
initDisplay();
//load xml from external file
var sampleXML:XML = new XML();
sampleXML.ignoreWhite = true;
sampleXML.onLoad = parseSampleData;
sampleXML.load("sample.xml");
//parse sample data
function parseSampleData() {
var rootNode:XMLNode = sampleXML.firstChild;
SampleData = new BgxDesObject();
SampleData.xmlNode = rootNode;
SampleData.onParsed = populateTree;
SampleData.parse();
}
function populateTree(includeRoot:Boolean)
{
//Variation 1: add all pages and folders below the root
node
addTreeNodes(SampleData,bgxTree);
//Variation 2: start with the site root and add all
pages
//and folders beneath it
//var newNode = bgxTree.addTreeNode( SampleData.label,
SampleData);
//addTreeNodes(SampleData,newNode);
}
function addTreeNodes(elements:Object,treeNode:Tree)
{
for (var element in elements)
{
//get the elements of the original
XML, which are arrays within the parsed
//SampleData and therefore of
type "object"
//also filter out "bgx_cln_comment"
and "exampleNode"
if (typeof elements[element]
== "object" &&
element
!= "bgx_cln_comment" &&
element
!= "exampleNode")
{
//loop
through the elements array to add each item as tree node
var
elementsArray = elements[element];
for
(var i = 0; i < elementsArray.length; i++)
{
//use
the label property as nodeName
var
nodeName = elementsArray[i].label;
//add
the node to the tree, setting the whole object as its data
var
newNode = treeNode.addTreeNode(nodeName,elementsArray[i]);
//make
sure that folder nodes appear as branches, even if they
//don't
have further children in the XML
var
isBranch = (element == "folder");
bgxTree.setIsBranch(newNode,isBranch);
//recursive
call to add child nodes
addTreeNodes(elementsArray[i],newNode);
}
}
}
}
function initDisplay()
{
//assign tree change event to setDisplay()
treeListenerObject = new Object();
treeListenerObject.change = function(evtObject){
setDisplay(bgxTree.selectedNode,evtObject.target.selectedItem.attributes.data);
}
bgxTree.addEventListener("change", treeListenerObject);
//identify the attributes that shall appear in the DataGrid
columns
dgPages.columnNames= ["label", "URL"];
//define some display parameters
dgPages.getColumnAt(0).width = 170;
dgPages.getColumnAt(1).width = 320;
dgPages.getColumnAt(0).headerText = "Pages";
dgPages.getColumnAt(1).headerText = "URL";
//define an event listener that loads the page URL
//when a row is double-clicked.
var dgListener = new Object();
dgListener.cellPress = function(event) {
//you can use the itemIndex
that is submitted by the event
//to identify the page data
within the SampleData Object
var itemData = dgPages.dataProvider[event.itemIndex];
if (checkDblClick(itemData))
getURL(itemData.URL,"_blank");
};
dgPages.addEventListener("cellPress", dgListener);
}
function setDisplay(treeNode,dataObject)
{
//double-click action
if (checkDblClick(dataObject))
{
//load pages if the have an
URL
if (typeof dataObject.URL !=
"undefined")
{
getURL(dataObject.URL,"_blank");
}
//toggle branches on double-click
if (bgxTree.getIsBranch(treeNode))
bgxTree.setIsOpen(treeNode,!bgxTree.getIsOpen(treeNode));
}
//set display
itemTitle.text = dataObject.label;
//display pages in the DataGrid for folders
if (dataObject.nodeName == "folder")
{
dgPages.dataProvider = dataObject.page;
dgPages._visible = true;
itemURL.text = "";
}
else
{
dgPages._visible = false;
}
//display the URL as Hyperlink for pages
if (dataObject.nodeName != "page")
{
itemURL.text = "";
}
else
{
itemURL.htmlText = "<a
href='" + dataObject.URL + "' target='_blank'><u>" +
dataObject.URL + "</u></a>";
}
}
//----Utility double-click
//global variables
var lastClick = 0;
var lastSelected;
//check if an object was double-clicked
function checkDblClick(pObj):Boolean
{
var clickTime = getTimer();
var dClick = ((clickTime-lastClick<400) &&
(lastSelected == pObj));
lastClick = clickTime;
lastSelected = pObj;
return dClick;
}
//----End utility double-click
History
5 June 2004
Changed the datatype of treeNode in the line function addTreeNodes(elements:Object,treeNode:Tree)
from XML to Tree (I couldn't find a type TreeNode for the Tree component). This
also requires to add import mx.controls.Tree; at the
top of the code.
Reason: This example works fine in both cases but I worked on other tree examples since that require the identification of a Treenode's parent. As the Tree component does not provide an interface for that I use the parentNode attribute (added by the BgxDesObject Class) of the object stored as data. If treeNode is typed as XML this does not return the parentNode the BgxDesObject Class created. Francly the type should not have been XML in the first place.
BG