Dynamically added FormItem doesn't show error text - actionscript-3

I am dynamically creating a form on runtime of my application. The content of my form item (lets call it MyFormItemContent) looks like this (simplified):
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%" borderAlpha="0.0">
<fx:Declarations>
<utils:DataItemValidator dataItem="{referenceToDataItem}"
source="{this}"/>
</fx:Declarations>
<s:HGroup width="100%">
<s:TextInput width="100%" text="#{bindingToText}"/>
<s:CheckBox width="14" selected="{refToBoolean}"/>
</s:HGroup>
</s:BorderContainer>
and the the code for the the validator we are using. It works fine other parts of the application and debuging shows that a message exists but is not shown.
/**
* This class effectively does *not* validate the given 'value', but just returns
* his 'dataItem's attached messages.
*/
public class DataItemValidator extends Validator {
private var _dataItem:StatefulDataItem;
public function get dataItem():StatefulDataItem {
return _dataItem;
}
public function set dataItem(dataItem:StatefulDataItem):void {
_dataItem = dataItem;
ChangeWatcher.watch(_dataItem, "messages", function():void {
validate();
}, false);
validate();
}
override protected function doValidation(value:Object):Array {
if (!isInitialized()) return [];
// Clear results Array.
var results:Array = [];
// If dataItem has error indicator append all messages to result array.
if (dataItem && dataItem.messages) {
for each (var message:ResultMessage in dataItem.messages) {
results.push(new ValidationResult(message.isErroneous(), null, "", message.text));
}
}
return results;
}
public function isErroneous():Boolean {
if (!dataItem) return false;
return dataItem.isErroneous();
}
private function isInitialized():Boolean {
return (dataItem != null);
}
}
The code that declares the form looks like this:
<s:Form id="myForm" width="100%" height="100%">
<s:layout>
<s:FormLayout gap="-7" paddingBottom="2" paddingLeft="2" paddingRight="2"
paddingTop="2"/>
</s:layout>
</s:Form>
And finally, the item is added to the form like this:
var formItem:FormItem = new FormItem();
formItem.label = "some text";
formItem.addElement(new MyFormItemContent());
myForm.addElement(formItem);
If the validation of MyValidator has errors a red frame apears around the BorderContainer as intended. But unfortunatly the error text that should apear right to the form item doesn't. I'm thinkin it's a layout problem because I define the validator inside the form item content before adding it to the form. I've already debugged this and read documentations a lot.
I thought it would help to know how a FormItem is added to a Form if you declare it in mxml but I couldn't find information on that either.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="application2_creationCompleteHandler(event)" xmlns:local="*">
<fx:Script>
<![CDATA[
import mx.charts.series.ColumnSeries;
import mx.collections.ArrayCollection;
import mx.containers.FormItem;
import mx.events.FlexEvent;
protected function application2_creationCompleteHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
for(var i:int = 0; i < 4; i++)
{
var formItem:FormItem = new FormItem();
formItem.label = "some text";
formItem.addElement(new MyFormItemContent());
myForm.addElement(formItem);
}
}
]]>
</fx:Script>
<s:Form id="myForm" width="100%" height="100%">
<s:layout>
<s:FormLayout gap="-7" paddingBottom="2" paddingLeft="2" paddingRight="2"
paddingTop="2"/>
</s:layout>
</s:Form>
</s:Application>
form item mxml file
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%" borderAlpha="0.0" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="bordercontainer1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.events.ValidationResultEvent;
[Bindable]
private var bindingToText:String;
[Bindable]
private var refToBoolean:Boolean;
protected function bordercontainer1_creationCompleteHandler(event:FlexEvent):void
{
// TODO Auto-generated method stub
}
protected function txt_focusOutHandler(event:FocusEvent):void
{
var obj:ValidationResultEvent = validator.validate(txt.text);
error.visible = !(obj.type == "valid");
}
]]>
</fx:Script>
<fx:Declarations>
<mx:PhoneNumberValidator id="validator"/>
</fx:Declarations>
<s:HGroup width="100%">
<s:TextInput id="txt" width="100%" text="#{bindingToText}" focusOut="txt_focusOutHandler(event)"/>
<s:CheckBox width="14" selected="{refToBoolean}"/>
<s:Label id="error" visible="false" backgroundColor="red" text="This Field Required"/>
</s:HGroup>
</s:BorderContainer>
I am posting this code for your interest.

Related

Need 2 way binding between 2 components flex 4

Can anyone tell me how to do 2-way Binding between 2 components?
I have a TabGroup, in which I created 2 tabs.. Each tab has each component...
First tab: Some form is there and submit button
Second Tab: Datagrid
So, when I enter some details and click Submit button, 1 row should be added in Datagrid.. This functionality is working, BUT when i double click the row in Datagrid, the row details from Datagrid should be filled up in Form which iam not getting this..
PLease check below code , run it, and provide me solution:
Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:components="components.*"
creationComplete="init()">
<fx:Script>
<![CDATA[
import components.EmployeeSingleton;
[Bindable]
public var empSingleton: EmployeeSingleton;
public function init(): void
{
empSingleton = EmployeeSingleton.getInstance();
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:VGroup>
<s:TabBar dataProvider="{contact}" />
<mx:ViewStack id="contact"
resizeToContent="true">
<components:ContactInfo id="contactInfo"
label="Employee Info"
empSingleton="{empSingleton}"/>
<components:ContactList label="Employee List"
empSingleton="{empSingleton}"/>
</mx:ViewStack>
</s:VGroup>
</s:Application>
EmployeeSingleton.as
package components
{
import mx.collections.ArrayCollection;
[Bindable]
public final class EmployeeSingleton
{
private static var instance: EmployeeSingleton;
public var empData: ArrayCollection;
public function EmployeeSingleton()
{
}
public static function getInstance(): EmployeeSingleton
{
if(instance == null)
instance = new EmployeeSingleton();
return instance;
}
}
}
EmployeeVO.as
package vo
{
[Bindable]
public class EmployeeVO
{
public function EmployeeVO()
{
}
public var empName: String;
public var address: String;
public var state: String;
public var city: String;
public var zip: String;
}
}
ContactInfo.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import vo.EmployeeVO;
public var empSingleton: EmployeeSingleton;
private var empVO : EmployeeVO;
private var empCollection : ArrayCollection = new ArrayCollection();
protected function submit_clickHandler(event:MouseEvent):void
{
empVO = new EmployeeVO();
empVO.empName = empName.text;
empVO.address = address.text;
empVO.city = city.text;
empVO.state = state.text;
empVO.zip = zip.text;
empCollection.addItem(empVO);
empSingleton.empData = empCollection;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Form>
<s:FormItem label="Name">
<s:TextInput id="empName" />
</s:FormItem>
<s:FormItem label="Address">
<s:TextInput id="address" />
</s:FormItem>
<s:FormItem label="City">
<s:TextInput id="city" />
</s:FormItem>
<s:FormItem label="State">
<s:TextInput id="state" />
</s:FormItem>
<s:FormItem label="Zip">
<s:TextInput id="zip" />
</s:FormItem>
<s:FormItem>
<s:Button id="submit"
label="Submit"
click="submit_clickHandler(event)"/>
</s:FormItem>
</s:Form>
</s:NavigatorContent>
ContactList.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="300"
>
<fx:Script>
<![CDATA[
[Bindable]
public var empSingleton: EmployeeSingleton;
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:DataGrid id="empData"
dataProvider="{empSingleton.empData}"/>
</s:NavigatorContent>
Awaiting for solution, please run above code and provide me solution for 2-way binding
You don't need to bind for 'update for on double click on an item in list'. Bindings are very tightly coupled. What you should do instead is listen for double-click events on list and update form with a item information that was double-clicked on.

Simple flex popup with dispatch event in child and listener in parent not working

Parent.mxml
This file is calling the popup class below when the button is clicked.
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.PopUpManager;
var popup:pop = null ;
protected function clickHandler(event:MouseEvent):void
{
popup = PopUpManager.createPopUp(this,pop,true) as pop;
popup.ok.addEventListener(MouseEvent.CLICK, captureComments);
popup.close();
}
var str:String="";
private function captureComments():void{
Alert.show("Invoked Event Listener", "Alert");
str=popup.comments;
}
]]>
</fx:Script>
<mx:Button id="id1" label="Click" click="clickHandler(event)"/>
<s:Label id="lbl" height="18" width="282" text={str} />
</s:Application>
Child.mxml
This file is the popup reference, creating popup.
I have configured the close action and cancel buttons to work as needed, but unable to propagate the text entered in comment are back to the parent.
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
layout="vertical" width="524" height="322"
showCloseButton="true"
close="close()" chromeColor="#CCCCCC"
horizontalAlign="center" verticalAlign="middle" color="#000000">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.PopUpManager;
import mx.rpc.events.ResultEvent;
[Bindable]public var comments:String;
public function close(): void{
PopUpManager.removePopUp(this);
}
private function save(): void{
if(comments == null){
comments = "";
}
dispatchEvent(new ResultEvent(comments));
}
]]>
</fx:Script>
<mx:HBox width="100%" height="70%">
<mx:VBox width="100%" height="100%">
<mx:TextArea id="comment" text="{comments}" width="100%" height="80%" change="comments = event.target.text">
</mx:TextArea>
<mx:HBox horizontalAlign="center" width="100%" height="20%">
<s:Button id="ok" label="OK" chromeColor="#CCCCCC" click="save()" fontWeight="bold"/>
<s:Button id="cancel" label="Cancel" chromeColor="#CCCCCC" click="close()" fontWeight="bold"/>
</mx:HBox>
</mx:VBox>
</mx:HBox>
</mx:TitleWindow>
You are dispatching a ResultEvent, like this:
dispatchEvent(new ResultEvent(comments));
However, the event type is the user entered input. Check out the ResultEvent constructor. The first argument is the event type. I have no idea how you'll be able to consistently listen for an event type that is unknown at compile time.
I think you are trying to pass your custom data back to your parent class. My preference would be to use a custom event for this; but if you wanted to use a ResultEvent you could pass your comments in the result property:
dispatchEvent(new ResultEvent(ResultEvent.RESULT,false,true,comments));
In your parent file, add an event listener like this:
popup.addEventListener(ResultEvent.RESULT, processResult);
You should be able to get at your comments value as a property on the event:
protected function processResult(event:ResultEvent):void{
str=event.result
}
Another thing I've done as well is in the Child Container Create a public variable to pass the function from the parent ie:
in parent:
protected function captureComments(comments:String):void{
str=comments;
}
in child :
declare a public var and add the function to the save() function
public var parentFunction:Function;
private function save(): void{
if(comments == null){
comments = "";
}
parentFunction(comments);
Then when Creating your popup container in the parent:
protected function clickHandler(event:MouseEvent):void
{
popup = PopUpManager.createPopUp(this,pop,true) as pop;
popup.parentFunction = captureComments;
popup.close();
}

Flex 4 component on top of TitleWindow

I have Flex s:Group with some ui elements and I want it to be always (!) on top of any component inside my app, including s:TitleWindow (dialog).
How can I achieve it with Flex 4?
Thanks in advance!
You should use the mx.managers.PopUpManager class. It provides a simple interface to handle displaying content above any other.
You can write your own interface that encapsulates the PopUpManager interface to give you a chance to bring all your "always-on-top" components on top again, even when you add another popup that should appear behind.
Simple example:
public final class AlwaysOnTopPopUpManager {
private static var alwaysOnTopDisplayObjects:Array;
public static function addAlwaysOnTopObject(displayObject:IFlexDisplayObject):void
{
alwaysOnTopDisplayObjects = alwaysOnTopDisplayObjects || [];
if (alwaysOnTopDisplayObjects.indexOf(displayObject) == -1)
{
alwaysOnTopDisplayObjects.push(displayObject);
arrange();
}
}
public static function removeAlwaysOnTopObject(displayObject:IFlexDisplayObject):void
{
if (alwaysOnTopDisplayObjects)
{
var index:int = alwaysOnTopDisplayObjects.indexOf(displayObject);
if (index != -1)
{
alwaysOnTopDisplayObjects.splice(index, 1);
}
}
}
// uses the same interface as mx.managers.PopUpManager
public static function addPopUp(window:IFlexDisplayObject, parent:DisplayObject, modal:Boolean = false, childList:String = null, moduleFactory:IFlexModuleFactory = null):void
{
mx.managers.PopUpManager.addPopUp(window, parent, modal, childList, moduleFactory);
arrange();
}
private static function arrange():void
{
for each (var popup:IFlexDisplayObject in alwaysOnTopDisplayObjects)
{
mx.managers.PopUpManager.bringToFront(popup);
}
}
The class holds a list of objects to appear above any other content. Each time an object is added to that list or to the popups the arrange() method is called and bring all your registered objects to front again.
Add you top component in systemManager.rawChildren after application creationComplete event. See down:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="application_creationCompleteHandler(event)"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.core.UIComponent;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
protected function application_creationCompleteHandler(event:FlexEvent):void
{
panel.width = width;
panel.height = 300;
systemManager.rawChildren.addChild(panel);
}
protected function addPopup():void
{
PopUpManager.addPopUp(titleWin, this, true);
PopUpManager.centerPopUp(titleWin);
}
protected function button_clickHandler(event:MouseEvent):void
{
addPopup();
}
protected function titleWin_closeHandler(evt:CloseEvent):void
{
PopUpManager.removePopUp(evt.currentTarget as UIComponent);
}
]]>
</fx:Script>
<fx:Declarations>
<s:Panel id="panel" backgroundColor="0x00ff00" alpha="0.9" title="Panel">
<s:layout>
<s:VerticalLayout paddingLeft="50" horizontalAlign="left" verticalAlign="middle" />
</s:layout>
<s:Button id="btn" width="200" height="100" label="create popup"
click="button_clickHandler(event)" />
</s:Panel>
<s:TitleWindow id="titleWin"
title="Spark TitleWindow"
close="titleWin_closeHandler(event);"
width="300">
<s:layout>
<s:VerticalLayout paddingLeft="10" paddingRight="10"
paddingTop="10" paddingBottom="10" />
</s:layout>
<s:Label text="Popup window"
fontSize="24"
width="100%"/>
</s:TitleWindow>
</fx:Declarations>
</s:Application>
If all your elements are in the same MXML file, you simply have to put your s:Group element at the bottom of the file as the last element of it.
If your views are wired more dynamically, then you can force its index with something like this:
var topIndex:int = myParentView.numChildren - 1;
myParentView.setChildIndex(myGroupElement, topIndex);
Where myGroupElement if the reference to your s:Group or its ID.
myGroupElement must already be a child of myParentView when this code is executed.
If your s:Group element is only displayed occasionally, you might be interested in Popups.

Create Custom Dialog Box using dispatch events,states and titlewindow in flex/AS3.0

Since a month Iam working on creating a custom dialog box, having parameters like message,state and modal(true/false)
Eg:
showAlert("Hi, how are you doing","Goodmorning", true);
I have learned how to dispatch event. but unable to dispatch the alertevent/popupManager using States.
Below is the code, I am struggling with.
Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
public function onclick(event:MouseEvent):void
{
this.dispatchEvent("Hi, How are you?", "Morning", true);
}
public function dispatchEvent(arg1:String, arg2:String, arg3:Boolean):void
{
var str:*=null;
str.message = arg1;
str.stateName = arg2;
str.modal = arg3;
this.dispatchEvent(new ShowAlert(ShowAlert.SHOW, true));
}
]]>
</mx:Script>
<mx:Button id="click" click="onclick(event)"/>
</mx:Application>
ShowAlert.as
package
{
import flash.events.*;
public class ShowAlert extends Event
{
public var _stateName:String;
public var _closable:Boolean;
public var _message:String;
public var _isModal:Boolean;
public static const SHOW:String="show";
public function flash.events.(arg1:String, arg2:Boolean=false, arg3:Boolean=false)
{
super(arg1, arg2, arg3);
trace("arg1: "+arg1+"\t arg2: "+arg2+"\t arg3: "+arg3);
}
public function set message(arg1:String):void
{
this._message = arg1;
}
public function get message():String
{
return _message;
}
public function get modal():Boolean
{
return _isModal;
}
public function get stateName():String
{
return _stateName;
}
public function set stateName(arg1:String):void
{
this._stateName = arg1;
}
public function set modal(arg1:Boolean):void
{
this._isModal = arg1;
}
public override function clone():flash.events.Event
{
return new ShowAlert(type);
}
}
}
I was unable to write the custom titlewindow using states, so I dint post that.
Please let me know, how to make this happen.
Below is the Sample code, specifying my problem
main.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public var info:IModuleInfo;
public var loadalert:DisplayObject;
import mx.modules.ModuleManager;
import mx.modules.IModuleInfo;
import mx.events.ModuleEvent;
public function init():void
{
Alert.show("This is forst alert.");
}
public function Loadalerrt():void
{
trace("loadalertmodule");
info = ModuleManager.getModule("../bin-debug/alerrtmod.swf");
info.addEventListener(ModuleEvent.READY, modEventHandler);
info.load();
}
public function modEventHandler(event:ModuleEvent):void
{
trace("modeventHandler");
loadalert=info.factory.create() as DisplayObject;
can1.addChild(loadalert);
}
]]>
</mx:Script>
<mx:Button label="Alert in Application" id="b1" click="init()" x="29" y="21"/>
<mx:Button label="Load Module" id="b2" click="Loadalerrt();" x="10" y="92"/>
<mx:Canvas id="can1" x="409" y="57" backgroundColor="cyan"/>
</mx:Application>
alerttmod.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="300">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function alertshow():void
{
Alert.show("This is second alert, You Can see it covers whole application, What I want is its scope should be limited to this specific module, not to whole application ");
}
]]>
</mx:Script>
<mx:Button label="Alert in Module" id="b1" click="alertshow()" x="163" y="100"/>
</mx:Module>
Now I see your problem. I think it is not possible to restrict the modal area of the Alert. I can suggest you to fake the modal behaviour by desabling the modules elements while your dialog is being shown.
May be it can help you...
Here are two components to demonstrate it:
//your module with another Alert
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="300">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.managers.PopUpManager;
public function alertshow():void
{
Alert.show("This is second alert...");
}
public function alertshow2():void
{
var customAlert:CustomAlert = new CustomAlert();
customAlert.addEventListener("CLOSED", onCustomAlertClosed);
this.enabled = false;
PopUpManager.addPopUp(customAlert, this, false);
PopUpManager.centerPopUp(customAlert);
}
private function onCustomAlertClosed(evt:Event):void
{
this.enabled = true;
}
]]>
</mx:Script>
<mx:Button label="Alert in Module" id="b1" click="alertshow()" x="163" y="100"/>
<mx:Button label="CustomAlert in Module" id="b2" click="alertshow2()" x="163" y="150"/>
<mx:Canvas width="100%" height="100%" backgroundColor="0xbbbbbb" alpha="0.8" visible="{!this.enabled}"/>
</mx:Module>
//simple CustomAlert as a Panel
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="300" height="200">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
protected function button1_clickHandler(event:MouseEvent):void
{
PopUpManager.removePopUp(this);
this.dispatchEvent(new Event("CLOSED"));
}
]]>
</mx:Script>
<mx:Button x="112" y="128" label="Close" click="button1_clickHandler(event)"/>
</mx:Panel>

ItemRollOver with a custom ToolTip

I have this custom toolTip:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
implements="mx.core.IToolTip"
creationPolicy="all"
cornerRadius="4" borderStyle="solid" backgroundColor="#FFFFFF"
creationComplete="init()" width="100" height="100">
<fx:Script>
<![CDATA[
import mx.core.IToolTip;
public var arrItemsKits:Array=[];
public var _text:String;
public function get text():String {
return _text;
}
public function set text(value:String):void {
}
protected function init():void
{
grid.dataProvider=arrItemsKits;
}
]]>
</fx:Script>
<mx:DataGrid id="grid" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn headerText="Code" dataField="itemPartNumber"/>
<mx:DataGridColumn headerText="Description" dataField="kitItemsNotes"/>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
and i want it to fire it when i roll the mouse over a row from a datagrid, so i need to add an event listener(toolTipCreate) to the row of that grid.
Any ideas how can i solve this?
Thanks
Check out this
<!-- myDataGridTest.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.events.ListEvent;
import mx.core.IToolTip;
import mx.events.ToolTipEvent;
// holds the currently highlighted item
private var highlightedItem:Object;
// event listener to get our hands on the currently highlighted item.
private function getHighlightedItem(e:ListEvent):void {
highlightedItem = e.itemRenderer.data;
// Quick n dirty way to force the ToolTipManager to refresh our tooltip.
// We need to dispatch this by hand because the pointer never leaves myDataGrid
// between successive highlights.
myDataGrid.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OUT));
}
private function createTooltip(e:ToolTipEvent):void {
var tt:MyCustomTooltip = new MyCustomTooltip();
tt.firstName = highlightedItem.name;
tt.lastName = highlightedItem.surname;
// Contract with the tooltip manager: if it finds an IToolTip instance attached to
// the event, it uses that instance instead of creating the standard one.
e.toolTip = tt;
}
]]>
</mx:Script>
<mx:DataGrid id="myDataGrid" toolTip=" " toolTipCreate="createTooltip(event)" itemRollOver="getHighlightedItem(event)">
<mx:dataProvider>
<mx:Object name="john" surname="doe"/>
<mx:Object name="mike" surname="smith"/>
</mx:dataProvider>
</mx:DataGrid>
</mx:Application>
<!-- MyCustomTooltip.mxml -->
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" implements="mx.core.IToolTip"
backgroundColor="yellow" backgroundAlpha="0.6">
<mx:Script>
<![CDATA[
private var _firstName:String;
private var _lastName:String;
// Dummy implementations to comply with mx.core.IToolTip
public function get text():String {return null;}
public function set text(value:String):void {}
// properties and functions
public function set firstName(value:String):void {
_firstName = value;
invalidateProperties();
}
public function set lastName(value:String):void {
_lastName = value;
invalidateProperties();
}
override protected function commitProperties():void {
fName.text = _firstName;
lName.text = _lastName;
}
]]>
</mx:Script>
<mx:Label x="0" y="0" id="fName"/>
<mx:Label x="0" y="20" id="lName"/>
</mx:Canvas>
.
.
Or try something like this
.
.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="doInit();">
<mx:Script>
<!![CDATA[import mx.collections.ArrayCollection; // this holds the grid data
[Bindable]
private var myData:ArrayCollection = new ArrayCollection();private function doInit():void{
myData.addItem({fname:"Joe",lname:"Bloggs"});
myData.addItem({fname:"Joe1",lname:"Bloggs"});
}
private function buildToolTip(item:Object):String{
var myString:String = "";
if(item != null)
{
myString = myString + "Firstname : " + item.fname + "\n";
myString = myString + "Lastname : " + item.lname + "\n"
}
return myString;
}
]]>
</mx:Script>
<mx:DataGrid id="dGrid" dataProvider="{myData}" visible="true" dataTipFunction="buildToolTip">
<mx:columns>
<mx:DataGridColumn dataField="fname" headerText="FirstName" showDataTips="true" />
<mx:DataGridColumn dataField="lname" headerText="LastName" showDataTips="true" />
</mx:columns>
</mx:DataGrid>
</mx:Application>
I figured it out: On itemRollOver handler you add event.itemRenderer.addEventListener(ToolTipEvent.TOOL_TIP_CREATE, createTT);