Flex: Call function from included component - apache-flex

This is similar to my previous posting. But this time I want to call a function that exists on the main mxml page.
This is my main mxml page:
main.mxml
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="*">
<mx:Script>
<![CDATA[
public function changeText(currentText:String):void{
switch (currentText){
case "changeText":
lblOne.text = "More Text";
}
}
]]>
</mx:Script>
<mx:HBox x="137.5" y="10" width="100%" height="100%">
<ns1:menu id="buttons"> </ns1:menu>
</mx:HBox>
<mx:Canvas x="137" y="88" width="408.5" height="200">
<mx:HBox x="0" y="10" width="388.5" height="190">
<mx:Panel width="388" height="179" layout="absolute">
<mx:Label x="10" y="10" text="Some Text" visible="{buttons.showLabel}" id="lblOne"/>
</mx:Panel>
</mx:HBox>
</mx:Canvas>
</mx:Application>
Here is my included page:
menu.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">
<mx:Script>
<![CDATA[
[Bindable] public var showLabel:Boolean = true;
]]>
</mx:Script>
<mx:MenuBar width="380" height="58"></mx:MenuBar>
<mx:Button x="10" y="10" width="80" label="Show" id="btnOne" click="this.showLabel=true;" />
<mx:Button x="94" y="10" width="80" label="Hide" id="btnTwo" click="this.showLabel=false;"/>
<mx:Button x="181" y="10" width="80" label="Run Function" id="btnThree" click="{changeText('changeText')}"/>
</mx:Canvas>
How do I call the changeText function from the button on menu.mxml?

Add this to menu:
<mx:Metadata>
[Event(name="buttonClicked", type="flash.events.Event")]
</mx:Metadata>
<mx:Button x="10" y="10" width="80" label="Show" id="btnOne" click="this.showLabel=true;dispatchEvent(new Event("buttonClicked"));"/>
Change main to:
<ns1:menu id="buttons" buttonClicked="changeText("Your Text");">
I couldn't tell where current text is coming from but if it is from menu you may have to build your own custom flex event or create a common variable for the two parts to access. The first is usually preferred.
P.S. The event metadata thing could also be achieved by adding the event listener when the creation of the application completes. You would add to main:
buttons.addEventListener("buttonClicked",changeText("Your Text"));

there is a simpler way, just use parentDocument.
Change this:
<mx:Button x="181" y="10" width="80" label="Run Function" id="btnThree" click="{changeText('changeText')}"/>
to:
<mx:Button x="181" y="10" width="80" label="Run Function" id="btnThree" click="{parentDocument*.changeText('changeText')}"/>**

Related

WindowShade and CollapsibleAccordion problems, migrating from Flex3 to Flex4

I have two problems in my code:
First: is with the WindowShade. I have a WindowShade in my application, and the moment I click to run this everything just hangs up. This was working fine when I was using the Flex3 to compile.
The code looks like:
<mdi_containers:MDIWindow xmlns:mdi_containers="flexlib.mdi.containers.*"
xmlns:flexlib_controls="flexlib.controls.*"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:containers="flexlib.containers.*"
width="800" layout="absolute"
height="500" title="News Articles"
textAlign="center"
verticalGap="0" horizontalGap="0"
minWidth="800"
minHeight="500">
<mx:Canvas width="100%" styleName="roundedBottomCorner">
<containers:WindowShade id="wshade_fox" top="0" width="100%" opened="false" visible="true"
openIcon="{null}" closeIcon="{null}" paddingTop="0"
headerRenderer="{new ClassFactory(c7.views.components.news.header)}">
<mx:VBox horizontalScrollPolicy="off" width="100%" height="225" verticalGap="0" horizontalGap="0">
</mx:VBox>
</containers:WindowShade>
</mx:Canvas>
Second: The CollapsibleAccordion. I have two canvas inside the CollapsibleAccordion, and everything works fine in Flex4 also, but the only problem, that i am unable to see the label on the Canvas.
The code for this problem is below:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:cal="cal.*"
layout="absolute"
addedToStage="stage_init()"
applicationComplete="init()"
xmlns:geometry="com.degrafa.geometry.*"
xmlns:degrafa="com.degrafa.*"
xmlns:paint="com.degrafa.paint.*"
xmlns:containers="flexlib.containers.*"
xmlns:flexlib_controls="flexlib.controls.*"
xmlns:mdi_containers="flexlib.mdi.containers.*"
xmlns:auto="com.hillelcoren.components.*"
xmlns:local="*" backgroundColor="#f7fafe" backgroundGradientColors="[#f7fafe, #6caaeb]"
xmlns:components="CollapsibleAccordion.*"
xmlns:notifications="c7.views.components.notifications.*"
xmlns:dbview="c7.views.apps.dashboard.*"
modalTransparency="0.8" preloader="c7.views.components.Pre"
modalTransparencyColor="0x000000" verticalScrollPolicy="auto"
backgroundSize="100%"
xmlns:components1="c7.views.components.*"
xmlns:notification="c7.views.components.notification.*"
xmlns:news="c7.views.components.news.*">
<mdi_containers:MDICanvas id="mdic" horizontalScrollPolicy="off" verticalScrollPolicy="off"
visible="{!GlobalModel.getInstance().dashboard_mode}"
minWidth="{top_bar.width}"
width="100%" height="100%" top="{top_bar.height}" backgroundAlpha="0">
<mx:Canvas id="cvs_widget_bar" right="0" top="0" height="100%">
<components:CollapsibleAccordion id="collapsibleAccordion1" height="100%" top="0" right="0"
orientation="left" barSize="30" currentWidth="30" openSize="150"
drawerButtonStyle="drawerButton" closeButtonStyle="drawerCloseRight" accordianStyle="drawerAccordion">
<mx:Canvas width="100%" top="0" right="0" height="100%" label="Widget Bar">
</mx:Canvas>
<mx:Canvas width="100%" height="100%" label="Feedback" icon="{IconUtility.getClass(cvs_comment,'assets/cloud_main/images/article-48x48.png')}"
id="cvs_comment" top="0" right="0">
</mx:Canvas>
</components:CollapsibleAccordion>
</mx:Canvas>
I had simliar problems with WindowShade going from Flex 3 to Flex 4. I had to define a button for the headerClass. Since I had a bunch of WindowShades, I added in my style sheet:
flexlib|WindowShade {
headerClass:ClassReference("mx.controls.Button");
}
Or, if you want when you declare a WindowShade, you can add in your MXML:
headerClass="mx.controls.Buttons"
...so that way your "wshade_fox" declaration looks something like:
<containers:WindowShade id="wshade_fox" top="0" width="100%" opened="false" visible="true"
openIcon="{null}" closeIcon="{null}" paddingTop="0"
headerRenderer="{new ClassFactory(c7.views.components.news.header)}"
headerClass="mx.controls.Button">
Hope that helps the first part of your problem.

Flex + custom component + design-time + binding

I'm trying to create simple custom component with two labels with this MXML:
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="250" height="30">
<mx:String id="result" />
<mx:Label x="5" y="7" id="titleLabel" text="{label}" width="120"/>
<mx:Label x="125" y="7" id="resultLabel" text="{result}" width="120" textAlign="right" color="#A41D00"/>
</mx:Canvas>
It is working well at runtime, bud I have troubles making it working at design-time. How can I make databinding work at the design time? If it is impossible, how should I code the label text assignements?
Try with text={data.label} and text={data.result} instead of mere label and result.
You won't see the actual data at design time. I'm not exactly sure what you're going for but here's how you might code the Labels
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%">
<mx:Script>
<![CDATA[
private var str : String = "Hello world";
]]>
</mx:Script>
<mx:Label x="5" y="7" id="titleLabel" text="{str}" width="120"/>
<mx:Label x="125" y="7" id="resultLabel" text="{titleLabel.text}" width="120" textAlign="right" color="#A41D00"/>
</mx:Application>

Flex - Typed ArrayCollection as Horizontallist's dataprovider

I have an ArrayCollection of objects.
I'm passing this array to a horizontallist as a dataprovider and I'm using a custom itemRenderer.
When executing the application, the horizontallist is displaying
[object CustomClass][object CustomClass][object CustomClass][object CustomClass]
I've tried casting each object in the itemrenderer as following:
<mx:Label text="{(data as CustomClass).label1}"/>
But it's not working...
Thanks for any help you can provide.
Regards,
BS_C3
Edit - 09 March 2010
Let's go for some more code =)
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Component id="Item">
<mx:VBox width="180">
<mx:HBox width="100%">
<mx:Spacer width="100%"/>
<mx:Button label="x"/>
</mx:HBox>
<mx:Image id="thumbnail"/>
<mx:Label width="100%" horizontalCenter="0" text="Collection"/>
<mx:HBox width="100%">
<mx:Label width="100" text="GIA"/>
<mx:Label text="{data.charg_st}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label width="100" text="Finger Size"/>
<mx:Label text="xxxxxx"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label width="100" text="Carat"/>
<mx:Label text="{data.carats}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label width="100" text="Color"/>
<mx:Label text="{data.color}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label width="100" text="Clarity"/>
<mx:Label text="{data.clarity}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label width="100" text="Shop"/>
<mx:Label text="{data.lgort_fp}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label width="100" text="Resizing"/>
<mx:Label text="{data.resizing}"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Label width="100" text="Price Excl. VAT"/>
<mx:Label text="{data.net_price_fp}"/>
</mx:HBox>
</mx:VBox>
</mx:Component>
<mx:HorizontalList
dataProvider="{GlobalData.instance.tray}"
columnCount="4"
rowCount="1"
horizontalScrollPolicy="off"
itemRenderer="{Item}"
/>
</mx:Canvas>
FYI, the horizonalList dataprovider is an ArrayCollection of objects.
Now, the horizontallist is displaying empty items... with the correct width...
The arraycollection is not empty (I'm using an alert on the click event on an item, and I do retrieve the expected data).
Hope this will help >_<
Regards,
BS_C3
Have you tried
<mx:Label text="{data.label1}"/>
? (label1 being a property of your objects)
Use the labelField field within your list, see here
<mx:List dataProvider="{myDataProvider}" labelField="label1"/>
Try declaring your custom class as a variable somewhere in your component. Once you declare an instance of the class, Flex might have more success identifying the properties of the class.
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
private var myClass:CustomClass;
]]>
</mx:Script>
<mx:Component id="Item">
<mx:VBox width="180">
...
thelost had it right with his code too. You should be able to use
<mx:Label text="{data.label1}"/>
to access your class's properties in your itemRenderer.
Edit: I'm sure you've done this, but also double check that you've set the dataProvider in your HorizontalList to a [Bindable] declaration of your CustomClass.
I managed to resolve my issue.
When I removed the width property of the itemrenderer's vbox, all data appeared in the horizontalList.
Why? I wouldn't know why but it seems like it was positionning the data somewhere out of the visible scope of the horizontallist (huh??).
The thing is that everything is working now. And for the final code, there you have:
HorizontalList:
<mx:HorizontalList id="hlist"
dataProvider="{TrayData.instance.itemsCollection}"
columnCount="{TrayData.instance.hlistColumns}"
rowCount="1"
itemRenderer="components.TrayItem"
horizontalScrollPolicy="off"
horizontalCenter="0" verticalCenter="0"
borderStyle="none"
horizontalScrollPosition="{TrayData.instance.hsPosition}"
/>
ItemRenderer:
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:HBox width="100%">
<mx:Spacer width="100%"/>
<mx:Button label="x"/>
</mx:HBox>
<mx:HBox width="100%">
<mx:Spacer width="15%"/>
<mx:VBox width="70%">
<mx:Image id="thumbnail" horizontalAlign="center"/>
<mx:Label width="100%" textAlign="center" text="Collection"/>
<mx:HBox width="100%">
<mx:VBox id="labelBox" width="100">
<mx:Label width="100" text="GIA"/>
<mx:Label width="100" text="Finger Size"/>
<mx:Label width="100" text="Carat"/>
<mx:Label width="100" text="Color"/>
<mx:Label width="100" text="Clarity"/>
<mx:Label width="100" text="Shop"/>
<mx:Label width="100" text="Resizing"/>
<mx:Label width="100" text="Price"/>
</mx:VBox>
<mx:VBox id="dataBox" width="100%" horizontalAlign="left">
<mx:Label text="{data.resizingCode + ' ' + data.charg_st}"/>
<mx:Label text="{data.fingerSize}"/>
<mx:Label text="{((new Number(data.carats))/100).toString()}"/>
<mx:Label text="{data.color}"/>
<mx:Label text="{data.clarity}"/>
<mx:Label text="{data.lgort_fp}"/>
<mx:Label text="{data.net_price_fp}"/>
</mx:VBox>
</mx:HBox>
<mx:Button label="Order" enabled="{data.product_type == 'C'}" width="50%"/>
</mx:VBox>
<mx:Spacer width="15%"/>
</mx:HBox>
</mx:VBox>
Regards,
BS_C3

Adding components to CoverFlow in Flex

I'm working with the CoverFlow library by Doug McCune.
In the example included, he has created some panels inside a CoverFlowContainer. There are other examples of him populating the coverflow from an RSS feed on the page linked above but he doesn't include the source for these :(
I will eventually be retrieving data from a web service to add to the coverflow however I'm starting with this simple example:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="center" verticalAlign="middle" xmlns:containers="com.dougmccune.containers.*" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.controls.TextArea;
public var articlePanel:Panel = new Panel();
public var articleTextArea:TextArea = new TextArea();
private function init() : void
{
articlePanel.addChild(articleTextArea);
articlePanel.title = "test tile"
articleTextArea.text = "article1" + "\n" + "www.article.com" + "\n" + "hello this is article 1";
coverflow2.addChild(articlePanel);
}
]]>
</mx:Script>
<mx:VBox id="box" verticalGap="0" height="306" width="100%" maxWidth="600" maxHeight="300" >
<containers:CoverFlowContainer id="coverflow2" width="100%" height="244"
horizontalGap="40" borderStyle="inset" backgroundColor="0x000000"
segments="6" reflectionEnabled="true">
<mx:Panel id="testpanel" width="200" height="200" title="Mxml title">
<mx:DataGrid width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="Column 1" dataField="col1"/>
<mx:DataGridColumn headerText="Column 2" dataField="col2"/>
<mx:DataGridColumn headerText="Column 3" dataField="col3"/>
</mx:columns>
</mx:DataGrid>
</mx:Panel>
<mx:Panel id="buttonpanel" width="200" height="200" title="Mxml title">
<mx:Button id="myButton" label="Change title" click="buttonpanel.title = ('hello') "/>
</mx:Panel>
</containers:CoverFlowContainer>
</mx:VBox>
</mx:Application>
I've defined some panels in the mxml and set creationComplete=init() so that the new panel I've created in ActionScript will be added to the CoverFlow container.
When I launch the application it displays the two predefined panels but not the one I have created in ActionScript.
Any ideas? Is there a better way of doing this?
you can try mx:Repeater component
<mx:HTTPService id="srv" url="pics.xml"/>
<ns2:CarouselContainer id="cf" width="100%" height="303" horizontalGap="40"
segments="6" reflectionEnabled="true" angle="10" >
<mx:Repeater id="r" dataProvider="{srv.lastResult.images.image}">
<mx:Canvas width="200" height="200">
<mx:Image source="{r.currentItem.src}"/>
</mx:Canvas>
</mx:Repeater>
</ns2:CarouselContainer>
Fixed this by first defining the coverflow container with nothing in it:
<containers:CoverFlowContainer id="coverflow" width="100%" height="244"
horizontalGap="40" borderStyle="inset" backgroundColor="0x000000"
reflectionEnabled="true"/>
In the actionscript section I retrieve an array from a web service and for each item in the array I create a panel. It is important to give each panel a width and height otherwise it will only show one element in the coverflow or no elements at all:
articlePanel.width = 200;
articlePanel.height = 200;

Flex Question: Can I use a ComboBox in Flex to change a view stack?

I am trying to use a combobox in flex with an array to change to a canvas in a view stack.
Can I do this with some custom action script? The UI I am designing could really benefit form this.
Here's a little demo app that demonstrates what you are trying to do:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:Script>
<![CDATA[
import mx.core.Container;
private function onComboBoxChange():void
{
stackNav.selectedChild = this[comboNav.selectedItem];
}
]]>
</mx:Script>
<mx:ComboBox id="comboNav" dataProvider="{['canvas1','canvas2']}" change="onComboBoxChange()"/>
<mx:ViewStack id="stackNav" width="400" height="300">
<mx:Canvas id="canvas1" width="100%" height="100%">
<mx:Label text="Hello" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
<mx:Canvas id="canvas2" width="100%" height="100%">
<mx:Label text="World!" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
</mx:ViewStack>
</mx:Application>
You can change the logic in onComboBoxChange() to use selectedIndex as well:
stackNav.selectedIndex = comboNav.selectedIndex;
Or you can bind the selectedIndex of the viewStack to the selectedIndex property of the combo:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:ComboBox id="comboNav" dataProvider="{['canvas1','canvas2']}"/>
<mx:ViewStack id="stackNav" width="400" height="300"
selectedIndex="{comboNav.selectedIndex}">
<mx:Canvas id="canvas1" width="100%" height="100%">
<mx:Label text="Hello" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
<mx:Canvas id="canvas2" width="100%" height="100%">
<mx:Label text="World!" horizontalCenter="0" verticalCenter="0"/>
</mx:Canvas>
</mx:ViewStack>
</mx:Application>
You can use this solution, but be warned that you can not pike a word with space
(try to change "canvas1" to "canvas 1") and you will see:
[Bindable] private var models:Array = ["tasks","users","bugs"];
public function changeViewStackModel():void {
//this.modelViewStack.selectedChild=users; //works
//this.modelViewStack.selectedChild="users"; //does not work
//this.modelViewStack.selectedChild=this.modelsCombo.selectedItem; //does not work
switch(modelsCombo.selectedItem) {
case "tasks": modelViewStack.selectedChild=tasks; break;
case "users": modelViewStack.selectedChild=users; break;
case "bugs": modelViewStack.selectedChild=bugs; break;
}
}
MXML code:
<mx:ComboBox id="modelsCombo" dataProvider="{models}" selectedIndex="0"
change="changeViewStackModel()"/>
<mx:ViewStack x="29.25" y="55" id="modelViewStack" width="90%" height="200">
<mx:Canvas id="tasks" label="Tasks"><mx:Label text="Tasks stack view!!"/>
</mx:Canvas>
<mx:Canvas id="users" label="Users"><mx:Label text="Users stack view!!"/>
</mx:Canvas>
<mx:Canvas id="bugs" label="Bugs"><mx:Label text="Bugs stack view!!"/>
</mx:Canvas>
</mx:ViewStack>

Resources