Hi guys i have a list control in a component mxml file. I have created a function in main mxml file, i want to input a text string and add it to this list. How can i do that. Currently using this code
public function add(event:MouseEvent):void
{
var name:String = mytextinputid.text;
currentState = 'ChatScreen';
mylist.____
}
Note that this function is in main and the mylist list control is in component mxml
Best regards
If you have assigned an id to your component, which I assume is mylist, you simply call
myList.dataProvider.addItem(name);
You should always have a dataProvider set to myList. Or else you can set one at run time.
var myCollection:ArrayCollection = new ArrayCollection();
myCollection.addItem(name);
myList.dataProvider = myCollection;
OR you can specify a dataProvider from MXML
<mx:List id="myList" dataProvider="{myCollection}"/>
how can i do binding exists property in actionscript e.g. i want image still in middle aplication..in mxml i do this simple as <mx:Image source="image.jpg" x="{this.width/2}"/> ...i don't know how can i do this simple in actionscript without event handlers... i put this code to application_creationCompleteHandler..
something like var image:Image = new Image(); image.source="image.jpg"; image.x=this.width/2; or have i put this to another function?? i can't do e.g. updateComplete event handler and change it there...
thanks
pavel
Check the BindingUtils class and its bindSetter method. You can bind a setter to the "width" property and adjust the x property of your image in that handler.
Considering that as3 is OO language i always start from something like this:
public class App extends Sprite {
public function App() { //constructor
super(); //extends class constructor
loading(); //your function were you set all elements properties
}
}
Why doesn't autocompletion work for function's local variables in included *.as files? For example:
Main.mxml:
<fx:Script>
<![CDATA[
include "code.as"; // or <fx:Script source="code.as"/>, doesn't matter
]]>
</fx:Script>
code.as:
import mx.controls.Button;
var foo:Button = new Button();
foo. <---- autocompletion is working here
function myFunc() {
var bar:Button = new Button();
bar. <----- doesn't work
}
Autocompletion will only work if a code class was imported, or if a class extended an .as class. Has to be a Class. When you use 'include code.as', code.as is not a class, its basically just a collection of variables, imports and functions, so autocomplete cannot access it like a class.
The code-behind pattern is similar to what your doing (seperating logic from the mxml), and allows for atuocompletion. To use it:
Create an Actionscript class that
extends an MXML control that you
want to use e.g. HBox or UIComponent
Put all of you logic within this
Actionscript class.
Then create an MXML class that
extends the Actionscript class.
Code completion will work in your new custom MXML class for accessing public/protected variables and functions.
I have several mxml components in an app, all of which need the same variable called genericX. I've included that variable in the main mxml and made it public
[Bindable] public var genericX:Number = 102;
but I still can't access it from other mxml components. If I try to do this for example, it doesn't recognize the variable.
<s:Button x="{genericX}" label="Click" />
There's also a filthy solution that works but isn't nice. You can create a static variable against the application class. For example:
[Bindable] public static var genericX : Object
You can access that from anywhere like this:
MyApplicationName.genericX
It ain't pretty, but it does work :)
simon
You cannot access in this way. There is something called Events in Flex and you need to pass this variable in a MXML file to another using eventDispatcher.
For example
[Bindable] public var genericX:Number = 102;
private function init():void {
var evt:NewCustomEvent = new CustomEvent(CustomEvent.SENDDATA);
evt.genericaValue = genericX
dispatchEvent(evt);
}
Now you need to get into the MXML component where you want to recieve this Event and using addEventListner() to recieve this event and the corresponding variable.
Then finally Inject it into your button.
You should be able to access any global variables with:
Flex 3:
var app:Application = mx.core.Application.application as Application;
Flex 4(looks like what you're using):
var app:Object = FlexGlobals.topLevelApplication;
And then:
<s:Button x="{app.genericX}" label="Click" />
x="{parentApplication.genericX}"
Here is an example for sharing variables between MXML components by declaring them public in the main application.
What I am trying to accomplish to to get financial data in my Flex Datagrid to be color-coded--green if it's positive; red if it's negative. This would be fairly straightforward if the column I want colored was part of the dataProvider. Instead, I am calculating it based on two other columns that are part of the dataProvider. That would still be fairly straightforward because I could just calculate it again in the ItemRenderer, but another part of the calculation is based on the value of a textBox. So, what I think I need to be able to do is send the value of the textBox to the custom ItemRenderer, but since that value is stored in the main MXML Application, I don't know how to access it. Sending it as a parameter seems like the best way, but perhaps there's another.
Here is the current code for my ItemRenderer:
package {
import mx.controls.Label;
import mx.controls.listClasses.*;
public class PriceLabel extends Label {
private const POSITIVE_COLOR:uint = 0x458B00 // Green
private const NEGATIVE_COLOR:uint = 0xFF0000; // Red
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
/* Set the font color based on the item price. */
setStyle("color", (data.AvailableFunding >= 0) ? NEGATIVE_COLOR : POSITIVE_COLOR);
}
}
(data.AvailableFunding doesn't exist)
So does anyone know how I would go about accomplishing this?
You may want to look into ClassFactory from the Flex APIs:
This allows you to set a prototype Object with arbitrary types / values each of which will be passed to the item renderer. From the sample:
var productRenderer:ClassFactory = new ClassFactory(ProductRenderer);
productRenderer.properties = { showProductImage: true };
myList.itemRenderer = productRenderer;
The above code assumed that "ProductRenderer" has a public property called "showProductImage" which will be set with a value of "true."
Ah, so I knew about outerDocument but not parentDocument. I was able to just use parentDocument.*whatever I want from the main App and I can access it as long as it's public.
Example:
setStyle("color", (parentDocument.availableFunding >= 0) ? POSITIVE_COLOR : NEGATIVE_COLOR);
Sweet! :)
You can access the value of the TextBox directly, if you need to, by using the static Application.application object, which is accessible from anywhere in your application.
For example, if you wanted the renderers to be notified when the value of the TextInput control changes, you could do something like this (from within your ItemRenderer, and where myTextInput is the ID of the control defined in your main MXML class):
<mx:Script>
<![CDATA[
import mx.core.Application;
private function creationCompleteHandler(event:Event):void
{
Application.application.myTextInput.addEventListener(TextEvent.TEXT_INPUT, handleTextInput, false, 0, true);
}
private function handleTextInput(event:TextEvent):void
{
if (event.currentTarget.text == "some special value")
{
// Take some action...
}
}
]]>
</mx:Script>
With this approach, each item-renderer object will be notified when the TextInput's text property changes, and you can take appropriate action based on the value of the control at that time. Notice as well that I've set the useWeakReference argument to true in this case, to make sure the listener assignments don't interfere unintentionally with garbage collection. Hope it helps!
There's another technique, which, while it initially feels a little hacky is perhaps less cumbersome and cleaner in actual use.
It involves the little-observed fact that an event dispatch is, of course, synchronous and the event object can be treated as a value object populated by any event handler.
i.e. the ItemRenderer can do something like:
...
var questionEvt:DynamicEvent = new DynamicEvent('answerMeThis', true, true);
if (dispatchEvent(questionEvt))
{
if (questionEvent.answer == "some value")
....
With a corresponding handler somewhere up the view hierarchy above the renderer that has a listener on the event and does something like:
function handleAnswerMeThis(event:DynamicEvent):void
{
event.answer = "another value";
event.dataHelper = new DataHelperThingy();
}
etc.
It need not be a DynamicEvent - I'm just using that for lazy illustrative purposes.
I vote up for cliff.meyers' answer.
Here's another example on setting the properties of an itemRenderer from MXML by building a function that wraps a ClassFactory around the itemRenderer class and that injects the necessary properties.
The static function:
public static function createRendererWithProperties(renderer:Class,
properties:Object ):IFactory {
var factory:ClassFactory = new ClassFactory(renderer);
factory.properties = properties;
return factory;
}
A simple example that adds a Tooltip to each item in a list:
<mx:List dataProvider="{['Foo', 'Bar']}" itemRenderer="{createRendererWithProperties(Label, {toolTip: 'Hello'})}"/>
Reference:
http://cookbooks.adobe.com/post_Setting_the_properties_of_an_itemRenderer_from_MXM-5762.html
You use outerDocument property. Please see the fx:Component reference.
You could create an 'AvailableFunding' static variable in the ItemRenderer and then set it in the parent document.
public class PriceLabel extends Label {
public static var availableFunding:int;
...
...
SetStyle("color", (PriceLabel.availableFunding >= 0) ? NEGATIVE_COLOR : POSITIVE_COLOR);
}
In your parent document, set it when your text box gets updated
PriceLabel.availableFunding = textBox.text;
Obviously it'll be the same value for every ItemRenderer but it looks like that might be what you're doing anyway.
I like to override the set data function of the item renderer to change the renderer when the data provider changes as shown here
When you override the function you could cast the object to your object to make the availableFunding property available.
To access the text box you could try creating a public property and binding the property to the text box in the mxml file:
public var textVar:String;
<mx:itemRenderer>
<mx:Component>
<customrenderer textVar="{txtBox.text}" />
</mx:Component>
</mx:itemRenderer>
Nice ClassFactory Example here
See this example:
itemRenderer="{UIUtils.createRenderer(TextBox,{iconSrc:IconRepository.linechart,headerColor:0xB7D034,subHeaderColor:0xE3007F,textColor:0x75757D})}"