Flex 4 component on top of TitleWindow - actionscript-3

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.

Related

AS3 Shortcut window and pop up

I have an AIR application with several windows.
I have set the shortcut key ESC to close window. It's works well.
On creationComplete, I have this code :
this.addEventListener(KeyboardEvent.KEY_DOWN, exit_keyDownHandler);
and
protected function exit_keyDownHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.ESCAPE){
//
this.removeEventListener(KeyboardEvent.KEY_UP, exit_keyDownHandler);
stage.nativeWindow.close();
}
}
But on this window, I could open a popup window where I have set same shortcut (ESC) to remove popup.
After opening and closing popup window shortcut on main window (first), has no effect !
My code to open popup is as follows:
wpTL = new wAddEditTL();
PopUpManager.addPopUp(wpTL, this,true);
PopUpManager.centerPopUp(wpTL);
On popup window extend TitleWindows, I add this event :
this.addEventListener(KeyboardEvent.KEY_DOWN, exit_keyDownHandler);
I hope a programming expert can help me, thank you very much!
I had some time to test this.
Here is a simple solution that works on my side with both MX and Spak Window components.
First, we create a simple application (Main.mxml) with only two buttons (to open MX or Spark Window) :
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
name="Key Events Test"
horizontalAlign="center"
verticalAlign="middle"
creationComplete="creationCompleteHandler(event)"
paddingLeft="0"
paddingTop="0"
paddingBottom="0"
paddingRight="0"
frameRate="60"
width="320"
height="200">
<mx:Button id="sparkWindowButton"
label="New Spark Window"
click="sparkWindowButton_clickHandler(event)"/>
<mx:Button id="mxWindowButton"
label="New MX Window"
click="mxWindowButton_clickHandler(event)"/>
<mx:Script>
<![CDATA[
import mx.core.Window;
import mx.events.FlexEvent;
import spark.components.Window;
private function creationCompleteHandler(event:FlexEvent):void {
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, systemManager_keyDownHandler);
}
private function systemManager_keyDownHandler(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.ESCAPE) {
var currentWindow:NativeWindow = NativeApplication.nativeApplication.activeWindow;
currentWindow.stage.nativeWindow.dispatchEvent(new Event(Event.CLOSING));
}
}
private function sparkWindowButton_clickHandler(event:MouseEvent):void {
var nativeWindow:spark.components.Window = new MySparkWindow();
nativeWindow.open();
}
private function mxWindowButton_clickHandler(event:MouseEvent):void {
var nativeWindow:mx.core.Window = new MyMXWindow();
nativeWindow.open();
}
]]>
</mx:Script>
</mx:Application>
Then we create a Popup Component (PopupPanel.mxml) :
<?xml version="1.0"?>
<mx:Panel xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
title="POPUP"
verticalAlign="middle"
width="280"
height="120">
<mx:Label text="HEY"
textAlign="center"
width="100%"/>
</mx:Panel>
And finaly, we create 2 components :
The MX Window (MyMXWindow.mxml) :
<?xml version="1.0"?>
<mx:Window xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
horizontalAlign="center"
verticalAlign="middle"
width="320"
height="200"
creationComplete="creationCompleteHandler(event)"
showStatusBar="false">
<mx:Button id="popupButton"
label="Add a popup"
click="popupButton_clickHandler(event)"/>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
public var popup:PopupPanel;
private function creationCompleteHandler(event:FlexEvent):void {
this.title = "MX Window #" + NativeApplication.nativeApplication.openedWindows.length;
this.stage.nativeWindow.addEventListener(Event.CLOSING, closingHandler, false, 0, true);
}
private function popupButton_clickHandler(event:MouseEvent):void {
popup = new PopupPanel();
PopUpManager.addPopUp(popup, this, true);
PopUpManager.centerPopUp(popup);
}
private function closingHandler(event:Event):void {
if (popup != null && popup.isPopUp) {
event.preventDefault();
trace("CLOSING POPUP");
PopUpManager.removePopUp(popup);
} else {
trace("CLOSING WINDOW");
stage.nativeWindow.close();
}
}
]]>
</fx:Script>
</mx:Window>
And finally, the Spark Window (MySparkWindow.mxml) :
<?xml version="1.0"?>
<s:Window xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="320"
height="200"
creationComplete="creationCompleteHandler(event)"
showStatusBar="false">
<s:layout>
<s:VerticalLayout horizontalAlign="center"
verticalAlign="middle"/>
</s:layout>
<s:Button id="popupButton"
label="Add a popup"
click="popupButton_clickHandler(event)"/>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
public var popup:PopupPanel;
private function creationCompleteHandler(event:FlexEvent):void {
this.title = "Spark Window #" + NativeApplication.nativeApplication.openedWindows.length;
this.stage.nativeWindow.addEventListener(Event.CLOSING, closingHandler, false, 0, true);
}
private function popupButton_clickHandler(event:MouseEvent):void {
popup = new PopupPanel();
PopUpManager.addPopUp(popup, this, true);
PopUpManager.centerPopUp(popup);
}
private function closingHandler(event:Event):void {
if (popup != null && popup.isPopUp) {
event.preventDefault();
trace("CLOSING POPUP");
PopUpManager.removePopUp(popup);
} else {
trace("CLOSING WINDOW");
stage.nativeWindow.close();
}
}
]]>
</fx:Script>
</s:Window>
Now, the explaination of what we are doing :
In Main.mxml, we are listening to the keyboard events for the whole application (so there's no problem with focus on a particular component or window).
When we catch the ESCAPE keycode, we retrieve the instance of the active application window and send it an Event.CLOSING event to indicate that we are closing the window.
In the window (MyMXWindow.mxml or MySparkWindow.mxml), we retrieve this event and check if the PopUp is open. If so, it is closed and the window continues to work, otherwise we close the window.
I do not know if this is what you want to do, but I hope at least it will point you to the right solution for your project.
Happy coding with Flex and AS3 ;-)

call a function when component visibility changes

Pretty simple thing but I am stuck.
Question: I want to call a function when the visibility of my component changes so I can do some clean up.
I have tried using the FlexEvents FlexEvent.HIDE and FlexEvent.SHOW and specified the function to call in my mxml header
show="onShow(event)"
private function onShow(event:FlexEvent):void
{
trace("********** onShow***********");
}
That didn't work. I then tried adding various eventListeners but that didn't work, Am I using listening for the wrong events?
addEventListener(FlexEvent.SHOW, onShow, false, 0, true);
addEventListener(FlexEvent.STATE_CHANGE_COMPLETE, onHide, false, 0, true);
And finally I tried overriding the setter for visible but that threw errors
override public function set visible(value:Boolean):void
{
super.visible = value;
visible = value;
}
You are right when using FlexEvent.HIDE and FlexEvent.SHOW but I don't know why you didn't get what you want. Take this simple example where a button hide a second one and when this last is hidden it disable the first one. A third button show the second one which when it is visible enable the first button :
<?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" creationComplete="init(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
protected function button_02_hideHandler(event:FlexEvent):void
{
button_01.enabled = false;
}
protected function button_01_clickHandler(event:MouseEvent):void
{
button_02.visible = false;
}
protected function button_03_clickHandler(event:MouseEvent):void
{
button_02.visible = true;
}
protected function init(event:FlexEvent):void
{
button_02.addEventListener(FlexEvent.SHOW, function(e:FlexEvent){
button_01.enabled = true;
})
}
]]>
</fx:Script>
<s:Button id="button_01" x="68" y="93" label="Button 01" click="button_01_clickHandler(event)"/>
<s:Button id="button_02" x="170" y="93" label="Button 02" hide="button_02_hideHandler(event)"/>
<s:Button id="button_03" x="276" y="93" label="Button 03" click="button_03_clickHandler(event)"/>
</s:Application>

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();
}

How to handle a change in a custom GridItemRenderer

I'm using a DataGrid in one of my project, with a custom ItemRenderer for one of the column to represent a boolean value as a CheckBox
<s:DataGrid id="clients" resizableColumns="false">
<s:columns>
<s:ArrayList>
<s:GridColumn dataField="fullName" headerText="Client name" />
<s:GridColumn dataField="active" headerText="Active?" width="90"
itemRenderer="CheckBoxGridItemRenderer"/>
</s:ArrayList>
</s:columns>
</s:DataGrid>
And here is the code of CheckBoxGridItemRenderer:
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
clipAndEnableScrolling="true">
<fx:Script>
<![CDATA[
override public function prepare(hasBeenRecycled:Boolean):void {
checkBox.selected = Boolean(data[column.dataField]);
}
]]>
</fx:Script>
<s:CheckBox id="checkBox" horizontalCenter="0" />
</s:GridItemRenderer>
Now here is my question: What is the best way to handle the change in data from the class I declared the DataGrid ?
I tried to change the data value from within my custom item renderer class:
private function valueChange():void
{
data.active = checkBox.selected;
}
[...]
<s:CheckBox id="checkBox" change="valueChange()" />
and then listen to CollectionEvent.COLLECTION_CHANGE event on the dataProvider of the DataGrid but I never handle any change. Any thoughts or advices?
Where do you change the data. When an element of data collection changed, the DataGrid can detect nothing unless you dispatch CollectionEvent.COLLECTION_CHANGE for the data collection.
In addition, the data collection should be something like ArrayCollection, not Array.
As I found a solution to my problem, I will post it here, but I leave the question open for some time in case someone come up with a better one.
First I created a CustomEvent (I could use the CollectionEvent class but this way I'm sure I don't mess up with the internal logic of the DataGrid)
package
{
import flash.events.Event;
public class CustomEvent extends Event
{
public static const CHANGE:String = "change";
public var column:String;
public var data:Object;
public function CustomEvent(column:String, data:Object)
{
super(CHANGE, true);
this.column = column;
this.data = data;
}
}
}
Notice the call to super() with bubbles set to true. This is actually needed for the event to be handle here.
Then I modified my CheckBoxGridItemRenderer to dispatch this event when the checkbox is selected/deselected:
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" clipAndEnableScrolling="true">
<fx:Script>
<![CDATA[
import CustomEvent;
override public function prepare(hasBeenRecycled:Boolean):void {
if (data)
{
checkBox.selected = Boolean(data[column.dataField]);
}
}
private function valueChange():void
{
data[column.dataField] = checkBox.selected;
dispatchEvent(new CustomEvent(column.dataField, data));
}
]]>
</fx:Script>
<s:CheckBox id="checkBox" horizontalCenter="0" change="valueChange()" />
</s:GridItemRenderer>
Finally I only have to listen to my custom event dispatched by the DataGrid instance:
clients.addEventListener(CustomEvent.CHANGE, handleCustomEvent);

Dynamically added FormItem doesn't show error text

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.