MENU - RightNavigation
<fx:Metadata>
[Event(name="interval", type="flash.events.Event")]
<fx:Metadata>
[Bindable]
public var sInterval:String;
[Bindable]
public var sIntervalId:String;
protected function intervalSelected(event:MouseEvent):void
{
sInterval = intervalMenu.selectedItem.intervals_miles;
sIntervalId = intervalMenu.selectedItem.interval_id;
dispatchEvent(new Event("interval"));
}
MENU - RightNavigation = This are the buttons in the menu
<s:VGroup includeIn="iMenu" width="100%" height="100%" horizontalAlign="center" paddingTop="10">
<s:List id="intervalMenu" styleName="leftNavContent" creationComplete="miles_handler(event)"
itemRenderer="renderers.MilesItemRenderer" click="intervalSelected(event)" >
<s:AsyncListView list="{intervalsResult.lastResult}"/>
</s:List>
</s:VGroup>
MODULE - mcIntervals
initialize="init()"
import containers.RightNavigation;
import mx.binding.utils.ChangeWatcher;
import flash.events.*;
[Bindable]
public var interval:RightNavigation;
public function init():void
{
//addEventListener("interval", intervalServices);
ChangeWatcher.watch(interval, "sIntervalId", intervalServices);
}
protected function intervalServices(e:Event):void
{
Alert.show("test");
}
Application Setup
MainApp has two containers RightNavigation and MainContent
MainContent has a module called mcIntervals
So I'm trying to send value from RightNavigation to mcIntervals
This is a desktop application if this make any difference
This is not working I can see that is sending the value in debug mode but ChangeWatcher or evenListener are not detecting anything
Thanks, Robert
Related
I am using a component to display the popup and using an event listener to get popover properties and remove the popup in the Parent. The poup var, however, in the listeners popup var is nul so it throws an error.
Any suggestions would be greatly appreciated.
John
Here is my EditStudentLogInForm.mxml component..
<?xml version="1.0"?>
<!-- containers\layouts\myComponents\MyLoginForm.mxml -->
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="handleCreationComplete();">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
[Bindable] public var studentLoginEmail:String;
]]>
</mx:Script>
<mx:Form width="333">
<mx:FormItem label="Email">
<mx:TextInput id="username" width="207"/>
</mx:FormItem>
<mx:FormItem label="Password">
<mx:TextInput id="password"
width="205"/>
</mx:FormItem>
</mx:Form>
<mx:HBox>
<mx:Button id="okButton" label="OK"/>
<mx:Button id="cancelButton" label="Cancel" />
</mx:HBox>
</mx:TitleWindow>
Here is the Parent...
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:s="library://ns.adobe.com/flex/spark">
<mx:Script>
<![CDATA[
import flash.events.Event;
import mx.managers.PopUpManager;
import mx.core.IFlexDisplayObject;
import EditStudentLogInForm;
import mx.containers.TitleWindow;
public var helpWindow:EditStudentLogInForm;
public function showLogin():void {
// Create the TitleWindow container.
var helpWindow:EditStudentLogInForm = EditStudentLogInForm(
PopUpManager.createPopUp(this, EditStudentLogInForm, true));
helpWindow.username.text = "johnbdh#myserver.com";
helpWindow["cancelButton"].addEventListener("click", removeMe);
helpWindow["okButton"].addEventListener("click", submitData);
}
// OK button click event listener.
private function submitData(event:Event):void {
testText.text = helpWindow.username.text;
//*********helpWindow is nul*******
removeMe(event);
}
// Cancel button click event listener.
private function removeMe(event:Event):void {
PopUpManager.removePopUp(helpWindow);
}
]]>
</mx:Script>
</mx:Application>
When you do
public function showLogin():void {
var helpWindow:EditStudentLogInForm = ...
}
you're declaring and instantiating a new variable helpWindow inside the scope of the showLogin method. This means that the instance you assigned to this locally scoped variable can not be accessed outside the showLogin method.
You did declare another variable helpWindow on the class scope (your class being the main application in this case), but you're never assigning any instance to it (since you're assigning this popup instance to the helpWindow variable that lives only in showLogin.
Hence when you try to access this variable in another method, it's value is null.
The solution is simple enough: just assign the popup instance to the class-scoped variable:
public function showLogin():void {
helpWindow = EditStudentLogInForm(
PopUpManager.createPopUp(this, EditStudentLogInForm, true)
);
...
}
On a side note: if you have a variable of the same name on the class and inside a method, the most locally scoped one always takes precedence:
public var s:String = 'class';
public function myMethod():void {
var s:String = 'method';
trace(s); // prints method
trace(this.s); // prints class
}
public function myOtherMethod():void {
trace(s); // prints class
trace(this.s); // prints class
}
I have a Flex application which sends a query to a database when an user clicks a button. Since the query might be heavy, and can take up to a minute, I want to display an alert, which will close only after an event comes back from the database (user won't be able to close it himself). Is it possible in Flex? How do I do that?
I have functions sendQuery() and dataEventHandler(). I think I need to put code in sendQuery() to display the alert and in dataEventHandler() to close it after data comes from the DB, but how do I make the alert "unclosable" by the user?
The built in Flex Alert class will always have some type of close button.
However, there is no reason you can't create your own component; and then open and close it using the PopUpManager.
Following code may help you… (One of the solution...)
You can find I have made Solution 1 and Solution 2… You can use any one of it and third solution is to create your own Custom Component.
Please find below code…. You can use below logic to solve your problem..
Use Timer to check if data received or you can dispatch custom event and call updateAlertPosition function.
Hope it may help: -
<?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:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
private var minuteTimer:Timer;
private var alert:Alert;
private var displayInitialText:String = "Data Not Received, Please wait....";
private var displayDataReveivedText:String = "Data Received...";
private function timerInit():void
{
//Logic to check if data Received.
minuteTimer = new Timer(3000);
minuteTimer.addEventListener(TimerEvent.TIMER, updateAlertPosition);
minuteTimer.start();
}
private function updateAlertPosition(event:Event = null):void {
minuteTimer.stop();
//Solution 1
//add your flag here if y you want to check if data is received or not
//if(Data Received)
alert.mx_internal::alertForm.mx_internal::buttons[0].enabled = true;
alert.mx_internal::alertForm.mx_internal::buttons[1].enabled = true;
alert.mx_internal::alertForm.mx_internal::textField.text = displayDataReveivedText;
//Solution 2
//alert.enabled = true;
//If you want to remove it automatically
//closeAutomatically();
}
private function closeAutomatically():void
{
PopUpManager.removePopUp(alert);
}
private function clickHandler():void
{
//Start Timer
timerInit();
//Solution 1
alert = Alert.show(displayInitialText, "Alert", Alert.OK|Alert.CANCEL,this,alertCloseHandler);
alert.mx_internal::alertForm.mx_internal::buttons[0].enabled = false;
alert.mx_internal::alertForm.mx_internal::buttons[1].enabled = false;
//Solution 2
//alert.enabled = false;
}
private function alertCloseHandler(event:CloseEvent):void
{
if(event.detail == Alert.CANCEL)
{
//Some Code on close
}
else
{
//Some Code on OK
}
}
]]>
</fx:Script>
<s:Button label="Show Alert" x="100" y="100" click="clickHandler()"/>
</s:Application>
make a 0-0.2 alpha shape what covers the whole application (probably you'll want to listen for resizeevents), and add a custom panel to the middle of it, with the message.
As an idea you can create a custom alert then:
Show Alert
Disable Application.
Hide Alert.
Enable Application.
An alert example:
<?xml version="1.0" encoding="utf-8"?>
<s:Group 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"
creationComplete="onCreationComplete(event)">
<s:Rect>
<s:fill>
<s:SolidColor color="0xFFFFFF"/>
</s:fill>
<s:stroke>
<s:SolidColorStroke />
</s:stroke>
</s:Rect>
<s:Label text="Please Wait..."/>
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
public static function show():void
{
PopUpManager.createPopUp(FlexGlobals.topLevelApplication);
}
public static function hide():void
{
PopUpManager.removePopUp(this);
FlexGlobals.topLevelApplication.enabled = true;
}
protected function onCreationComplete(event:FlexEvent):void
{
PopUpManager.centerPopUp(this);
FlexGlobals.topLevelApplication.enabled = false;
}
]]>
</fx:Script>
</s:Group>
Usage:
YourAlert.show();
YourAlert.hide();
#Alex, I used your code but modify it a bit, because there was some errors:
<?xml version="1.0" encoding="utf-8"?>
<s:Group 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="creationCompleteHandler()" width="100%" height="100%">
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.managers.PopUpManager;
///////////////////////////////////////
//// public functions - my group is ImageViewer.mxml component
public static function show():ImageViewer {
return PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, ImageViewer) as ImageViewer;
}
public function hide():void {
PopUpManager.removePopUp(this);
FlexGlobals.topLevelApplication.enabled = true;
}
////////////////////////////
//// component events
private function creationCompleteHandler():void {
PopUpManager.centerPopUp(this);
FlexGlobals.topLevelApplication.enabled = false;
}
]]>
</fx:Script>
</s:Group>
And call it like:
var imageviewer:ImageViewer = ImageViewer.show();
//imageviewer.imageURL = _value_dto.value;
I can't get my TextArea to take the focus skin which I did in the mxml skin file below. Can anyone help me with this. Note that in my application css file I have specified the focus skin as such : focus-skin: ClassReference("skins.focusSkin");
Skin File Code:
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.components.supportClasses.SkinnableComponent;
private var _target:SkinnableComponent;
public function get target():SkinnableComponent
{
return _target;
}
public function set target(value:SkinnableComponent):void
{
_target = value;
if (_target.skin)
_target.skin.addEventListener(FlexEvent.UPDATE_COMPLETE,
skin_updateCompleteHandler, false, 0, true);
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
this.setActualSize(target.width, target.height);
super.updateDisplayList(target.width, target.height);
}
private function skin_updateCompleteHandler(event:Event):void
{
invalidateDisplayList();
}
]]>
</fx:Script>
<s:BitmapImage id="focusGroup" source="#Embed(source='mySkinFile.swf', symbol='mySymbol')" />
</s:Group>
Take a look at the examples in this blog post that demonstrates how to create custom focus skins in spark:
http://flexponential.com/2010/01/24/custom-focusskin-for-spark-components-in-flex-4/
I defined a simple event class:
public class NewMoveEvent extends Event
{
public function NewMoveEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=true)
{
super(type, bubbles, cancelable);
}
}
}
Then in custom mxml component, I defined a button which triggers it:
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:ns1="ui.*" layout="absolute" width="682" height="412" title="Board">
<mx:Metadata>
[Event(name="newformevent", type="events.NewMoveEvent")]
</mx:Metadata>
<mx:Script>
<![CDATA[
import events.NewMoveEvent;
import config.Config;
private function addNewUIComponent(event:Event):void
{
var e:NewMoveEvent = new NewMoveEvent("newformevent");
dispatchEvent(e);
}
]]>
</mx:Script>
<ns1:ChessBoard x="8" y="9" width="350" height="350" backgroundColor="0x99CCCC" moveId="0" name="chessboard" themeColor="#FFFFFF"/>
<mx:Button id="next" x="507" y="127" label="Next" click="addNewUIComponent(event)"/>
<ns1:PieceContainer x="363" y="10" width="292" height="51" items="{Config.piecesWhite}" id="white"/>
<ns1:PieceContainer x="362" y="69" width="292" height="51" items="{Config.piecesBlack}" id = "black"/>
<ns1:PasteBin x="363" y="306" width="292" height="53" backgroundColor="0x99CCCC" id="paste"/>
<mx:Button x="445" y="127" label="Save" name="save" enabled="false"/>
No from the main application file I want to set the event handler, to this event.
I can easily do it from mxml
e.g.
But cant do it in actionscript (e.g. this code don't work):
private function addNewUIContainer(event:Event):void
{
var newBoard:UIContainer = new UIContainer();
newBoard.addEventListener(NewMoveEvent.NEWFORMEVENT, addNewUIContainer);
}
Compiler gives me an error. Don't understand why.
ERROR
Access of possibly undefined property NEWFORMEVENT through a reference with static type Class.
And yes, UIContainer is mxml class
The function addNewUiContainer is defined in main file (project.mxml)
It doesn't look like you have defined the public static const NEWFORMEVENT:String = "newformevent";
public class NewMoveEvent extends Event
{
public static const NEWFORMEVENT:String = "newformevent";
public function NewMoveEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=true)
{
super(type, bubbles, cancelable);
}
}
Was that it?
I am trying my first flex application. And have a problems adding data from xml http service to datagid.
My xml file looks like this:
<players>
<player>
<name>test</name>
<status>F</status>
<claimed>1</claimed>
</player>
<player>
<name>meta</name>
<status>F</status>
<claimed>1</claimed>
</player>
</players>
First I tried to fill the data in a raw way, so created mxml tag for HTTP service, and added handlers.
But very soon I realized that main application file became unreadable (because of huge amount of code), so I decided to organize it some way.
So decided to replace services with a separate as classes.
My new code looks like this:
MXML:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="main()" height="756" borderColor="#FFFFFF" width="950" top="10" left="10" horizontalAlign="left" verticalAlign="top" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#FCFCFC, #FCFCFC]">
<mx:Panel width="900" height="727" layout="absolute" title="Игра ГО" horizontalAlign="center" horizontalCenter="0" top="10">
<mx:Script>
<![CDATA[
import goclient.ListOfPlayers;
import goclient.usersList;
import goclient.Tester;
import mx.controls.Alert;
// And makes periodical requests to the server
[Bindable]
public var users:ListOfPlayers;
[Bindable]
public var test:Tester;
public function main():void{
test = new Tester();
users = new ListOfPlayers();
}
]]>
</mx:Script>
<mx:DataGrid doubleClickEnabled="true" dataProvider="{users.getPlayersList()}"
x="10" y="157" width="860" height="520" id="userList">
<mx:columns>
<mx:DataGridColumn dataField="claimed" headerText="Was claimed" width="25"/>
<mx:DataGridColumn dataField="name" headerText="Name of the player" />
<mx:DataGridColumn dataField="status" headerText="Status (Free or Busy)" />
</mx:columns>
</mx:DataGrid>
And the service class:
ListOfPlayers.as
package goclient
{
import flash.utils.Timer;
import mx.controls.Alert;
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.mxml.HTTPService;
public class ListOfPlayers
{
public var usersListService:HTTPService;
private var minTimer:Timer = new Timer(100000, 0);
private var playersData:ArrayCollection;
private var person:currentPerson;
public function ListOfPlayers()
{
usersListService = new HTTPService();
usersListService.url = "http://127.0.0.1:8000/go/active/";
usersListService.addEventListener(ResultEvent.RESULT, resultHandler);
//Alert.show("Here");
sendData();
//minTimer.addEventListener(TimerEvent.TIMER, sendData);
//minTimer.start();
}
public function getResp():String
{
return "Resr";
}
public function resultHandler(event:ResultEvent):void
{
//person = new currentPerson(event.result.current.username, event.result.current.img, event.result.current.rank);
playersData = event.result.players.player;
Alert.show("resh");
}
public function sendData():void
{
usersListService.send();
}
public function getPlayersList():ArrayCollection
{
Alert.show(playersData.toString());
return playersData;
}
}
}
The problem is that nothing is shown in the datagrid
I am just a beginner, so please advice what did I wrong with the class
The result function (in ListOfPlayers class) should give the list of players and not the function that is calling the webservice.
What you could do is add this in server class:
[Bindable]
public var playersData:ArrayCollection;
and in your view add also this variable with the bindable tag and set the value add this line in main():
playersData = users.playersData;
then the datagrid dataprovider is "{playersData}"
this should work. But with XML list it is always a bit difficult to know how deep you are in the tree ;)