<mx:Script>
<![CDATA[
private function openAllNodes():void {
tree.openItems = dp..node;
}
private function closeAllNodes():void {
tree.openItems = [];
}
]]>
</mx:Script>
<mx:XML id="dp">
<root>
<node label="Parent 1">
<node label="Child 1" />
<node label="Child 2">
<node label="Grandchild 1" />
<node label="Grandchild 2" />
</node>
<node label="Child 3" />
<node label="Child 4" />
</node>
</root>
</mx:XML>
<mx:ApplicationControlBar dock="true">
<mx:Button label="Open all nodes" click="openAllNodes();" />
<mx:Button label="Close all nodes" click="closeAllNodes();" />
</mx:ApplicationControlBar>
<mx:Tree id="tree"
dataProvider="{dp}"
showRoot="false"
labelField="#label"
width="200" />
Unless or other wise i click my parent list, the child or the next list must be in a disabled state.
I click on Child 1, then only Child 2 Must be able to select.
Please Help Me.
It sounds like you might want to extend the tree class and override some of the methods to implement your special functionality. Look at overriding the drawItem, mouseClickHandler, and possibly the expandItem functions.
Related
I want to customize the scrollbars on a mx|Tree component is Flex 4.
I would like to mimic this functionality: http://flexponential.com/2009/10/09/changing-the-position-of-the-scroll-bars-in-a-spark-list/
Any thoughts or reccomendations?
This can work, add your own error checking/styling, but you get the idea:
<s:VGroup gap="-1">
<s:Button width="100%" label="Scroll up" click="{tree.verticalScrollPosition--}" />
<mx:Tree id="tree" labelField="#label" showRoot="false" width="300" height="150"
verticalScrollPolicy="off">
<mx:dataProvider>
<fx:XML>
<root>
<node label="Parent 1">
<node label="Child 1" />
<node label="Child 2">
<node label="Grandchild 1" />
<node label="Grandchild 2" />
</node>
<node label="Child 3" />
<node label="Child 4" />
<node label="Child 5" />
<node label="Child 6" />
<node label="Child 7" />
<node label="Child 8" />
<node label="Child 9" />
</node>
</root>
</fx:XML>
</mx:dataProvider>
</mx:Tree>
<s:Button width="100%" label="Scroll Down" click="{tree.verticalScrollPosition++}"/>
</s:VGroup>
you could also try to use verticalScrollBarStyleName/horizontalScrollBarStyleName with a css style. But ofc it lacks the comfort of spark skins. ;)
This is my XML data in a file named nodesAndStuff.xml.
<?xml version="1.0" encoding="utf-8"?>
<root>
<node label="One" />
<node label="Two" />
<node label="Three" />
<node label="Four" />
<node label="Five" />
<node label="Six" />
<node label="Seven" />
<node label="Eight" />
<node label="Nine" />
</root>
The component using this data source is an XMLListCollection which is bound to a spark List and the code for that is:
<s:Application name="Spark_List_dataProvider_XML_test"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
initialize="init();">
<fx:Script>
<![CDATA[
private function init():void {
xmlListColl.source = nodes.children();
}
]]>
</fx:Script>
<fx:Declarations>
<fx:XML id="nodes" source="nodesAndStuff.xml" />
</fx:Declarations>
<s:List id="lst"
labelField="#label"
horizontalCenter="0" verticalCenter="0">
<s:dataProvider>
<s:XMLListCollection id="xmlListColl" />
</s:dataProvider>
</s:List>
Now I have added my tree just below the list and I have saved counting from 10 to 19 in one.xml, 20 to 29 in two.xml and so on in different XML file. I have no clue how to connect the XML containing counting from 10 to 19 as the single node in tree at the selection of label one in list.
There are all sorts of ways to do what you want to do. Keeping in the spirit of your example, I have modified it to do what I think you are asking:
<fx:Script>
<![CDATA[
private function init():void {
processXML(one);
}
private function processXML(nodes:XML):void {
xmlListColl.removeAll();
xmlListColl.source = nodes.children();
}
]]>
</fx:Script>
<fx:Declarations>
<fx:XML id="one" source="one.xml" />
<fx:XML id="two" source="two.xml" />
</fx:Declarations>
<s:List id="lst"
labelField="#label"
horizontalCenter="0" verticalCenter="0">
<s:dataProvider>
<s:XMLListCollection id="xmlListColl" />
</s:dataProvider>
</s:List>
<s:Button label="Change" click="processXML(two)" />
<s:List id="lst"
labelField="#label"
change="lst_changeHandler(event)"
horizontalCenter="0" verticalCenter="0">
<s:dataProvider>
<s:XMLListCollection>
<fx:XMLList xmlns="">
<node label="One" />
<node label="Two" />
<node label="Three" />
<node label="Four" />
<node label="Five" />
<node label="Six" />
<node label="Seven" />
<node label="Eight" />
<node label="Nine" />
</fx:XMLList>
</s:XMLListCollection>
</s:dataProvider>
</s:List>
protected function lst_changeHandler(event:IndexChangeEvent):void
{
Alert.show(event.target.selectedItem);
}
I want to extend the list with hyperlinks. For example in every node I should have an href attribute also. Then I need to redirect users to the selected item. I know Flash has the URLRequest class.
The little problem I have now is to get the selected item. It propably is because of the dataprovider is xml and I haven't done the correct casting. Or maybe some more enlightened than me can help me.
<fx:Script>
<![CDATA[
import flash.net.navigateToURL;
import spark.events.IndexChangeEvent;
protected function lst_changeHandler(event:IndexChangeEvent):void
{
navigateToURL(new URLRequest(lst.selectedItem.#url));
}
]]>
</fx:Script>
<s:List id="lst"
labelField="#label"
change="lst_changeHandler(event)"
horizontalCenter="0" verticalCenter="0"
>
<s:dataProvider>
<s:XMLListCollection>
<fx:XMLList xmlns="">
<node label="One" url="www.internet.com" />
<node label="Two" url="www.internet2.com" />
<node label="Three" url="www.internet3.com" />
<node label="Four" url="www.bla.com" />
</fx:XMLList>
</s:XMLListCollection>
</s:dataProvider>
</s:List>
var item:XML = event.target.selectedItem as XML;
var label:String = item.#label;
var url:String = item.#url;
if(url != null) {
var ur:URLRequest = new URLRequest(url);
navigateToURL(ur);
}
It was really real simple!
I am currently developing a dynamic LineChart in FLEX 4. I am implementing a Tree control next to my LineChart, which will filter the LineChart dataprovider and lineseries. The tree control has several branches and ultimately 5 children (leaf nodes) at the bottom of the last branch.
I need the leaf node/children to be displayed as checkboxes inside the tree control. As I understand, this will require overrides in the TreeItemRenderer class. This is where I am a little confused on how to implement that.
Currently I can distinguish between leaf and branches using this code, in my main MXML component. I added this because it may be helpful to some beginning FLEX developers, such as myself, who cannot easily find this functionality documented well:
private function treeClick(e:ListEvent):void {
_selectedItem = Tree(e.currentTarget).selectedItem;
if(mainTree.dataDescriptor.isBranch(_selectedItem)) {
Alert.show('branch click');
}
else {
Alert.show('leaf node click');
}
}
I am looking at the TreeItemRenderer override class from the following example here:
In the example, they override the "createChildden" super function to add checkboxes to the tree control.
My question is, can I override the createChildren function directly in my MXML component, and not have to use an entire class file to override this functionality? Must I re-invent the wheel to do this?
Also, how can I distinguish that my treeItem is a leaf node and not a parent, in the override function? I only want to add checkboxes to the leaf nodes, how can I differentiate? The following example adds checkboxes to all branches and leaf nodes, but I want to add checkboxes only to leaf node/children. How would you approach that?
override protected function createChildren( ): void
{
super.createChildren( );
if( !_checkbox )
{
_checkbox = new CheckBoxExtended( );
_checkbox.allow3StateForUser = false;
_checkbox.addEventListener( MouseEvent.CLICK, onCheckboxClick );
addChild( _checkbox );
}
}
Here is the XML I am working with:
<mx:XMLList id="treeData">
<node label="DAIX">
<node label="Account 1">
<node label="Premise 1">
<node label="Device 1" oid="31" isChecked="false">
</node>
<node label="Device 2" oid="32" isChecked="false">
</node>
</node>
<node label="Premise 2">
<node label="Device 1" oid="41" isChecked="false">
</node>
<node label="Device 2" oid="42" isChecked="false">
</node>
</node>
</node>
<node label="Account 2">
<node label="Premise 1">
<node label="Device 1" oid="31" isChecked="false">
</node>
<node label="Device 2" oid="32" isChecked="false">
</node>
</node>
<node label="Premise 2">
<node label="Device 1" oid="31" isChecked="false">
</node>
<node label="Device 2" oid="32" isChecked="false">
</node>
</node>
</node>
</node>
</mx:XMLList>
Here is my tree tag:
<mx:Tree id="mainTree" dataProvider="{treeData}" itemRenderer="TreeCheckBoxItemRenderer" labelField="#label" showRoot="false" width="100%" height="100%" itemClick="treeClick(event)" />
Here's what I would do: Create your item renderer derived off of TreeItemRender as an MXML component and include your checkbox in the MXML, then override the setter for listData. In your overridden method do something like this:
EDIT: Added surrounding MXML (note that the MXML is pretty much exactly what FB 4 generates by default when creating a new Tree item renderer, and that I haven't tested this in a Tree.)
EDIT2: Added code for moving checked state back and forth between component and data.
<fx:Script>
<![CDATA[
import mx.controls.treeClasses.TreeListData;
override public function set listData(value:BaseListData):void
{
super.listData = value
this.myCheckbox.visible = !(value as TreeListData).hasChildren;
this.myCheckbox.includeInLayout = !(value as TreeListData).hasChildren;
}
override public function set data(value:Object):void {
super.data = value;
this.myCheckbox.selected = this.data.isChecked;
}
private function onCheckboxChange(e:Event):void {
this.data.isChecked = this.myCheckbox.selected;
}
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<s:HGroup left="0" right="0" top="0" bottom="0" verticalAlign="middle">
<s:Rect id="indentationSpacer" width="{treeListData.indent}" percentHeight="100" alpha="0">
<s:fill>
<s:SolidColor color="0xFFFFFF" />
</s:fill>
</s:Rect>
<s:Group id="disclosureGroup">
<s:BitmapImage source="{treeListData.disclosureIcon}" visible="{treeListData.hasChildren}" />
</s:Group>
<s:CheckBox id="myCheckbox" change="onCheckboxChange(event)"/>
<s:Label id="labelField" text="{treeListData.label}" paddingTop="2"/>
</s:HGroup>
I'm using the iconField property of the Flex Tree to dynamically set the icon that a node should use. This works fine for leaf nodes but for branch nodes it doesn't seem to respect my iconField and instead just shows the default folder node.
Here's a simple repro:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Embed("assets/icon1.png")]
public var icon1:Class;
[Embed("assets/icon2.png")]
public var icon2:Class;
]]>
</mx:Script>
<mx:XML id="dp">
<node label="Sales" icon="icon1">
<node label="East" icon="icon2"/>
<node label="West" icon="icon2"/>
</node>
</mx:XML>
<mx:Tree dataProvider="{dp}" labelField="#label" iconField="#icon"
width="100%" height="100%" />
</mx:Application>
What happens is that icon2 shows for the East and West nodes but icon1 doesn't show for the Sales node. How can I get this to work?
I think it can be done with an iconFunction... This looks like it does what you want:
http://blog.flexexamples.com/2007/11/15/creating-a-custom-icon-function-on-a-flex-tree-control/
I see. susichan was right with iconFunction:
<mx:Script>
<![CDATA[
[Embed("icon1.png")]
public var icon1:Class;
[Embed("icon2.png")]
public var icon2:Class;
[Embed("icon3.png")]
public var icon3:Class;
private function setIcons(item:Object):Class {
var iconClass:Class;
var classType:String = XML(item).attribute("icon");
if(classType!="")
return this[classType];
else
return null;
}
]]>
</mx:Script>
<mx:XML id="dp">
<root>
<node label="Sales" icon="icon1">
<node label="East" icon="icon3"/>
<node label="West" icon="icon3"/>
</node>
<node label="Non-Sales" icon="icon2">
<node label="East" icon="icon3"/>
<node label="West" icon="icon3"/>
</node>
</root>
</mx:XML>
<mx:Tree dataProvider="{dp.node}" labelField="#label" iconField="#icon"
iconFunction="setIcons" showRoot="true"
width="100%" height="100%" />
Almost!
You need to set the folderOpenIcon and folderClosedIcon like so:
<mx:Tree dataProvider="{dp}" labelField="#label" iconField="#icon"
folderOpenIcon="{icon3}"
folderClosedIcon="{icon4}"
width="100%" height="100%" />