I have designed a quiz application in Flex 4. At the end I want to reload my application (that is refresh the page in the browser). At the end I will show score in an alert. After that I want to reload the current application. How can I do this?
To cause the refresh to not happen until after your alert is clicked:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark" xmlns:local="*"
>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.core.FlexGlobals;
import mx.events.CloseEvent;
protected function refreshClicked(event:Event):void
{
Alert.show("Congratulations you won",
"Hooray!",
Alert.NO|Alert.YES, null, refreshFinish);
}
protected function refreshFinish(event:CloseEvent=null):void{
if(event == null){
event = new CloseEvent("refreshFinish");
event.detail = Alert.YES;
}
if(event.detail == Alert.YES){
navigateToURL(new URLRequest(FlexGlobals.topLevelApplication.url), "_self");
}
}
]]>
</fx:Script>
<s:Button label="Alert and Refresh" click="refreshClicked(event)" />
</s:Application>
You can remove the option of "NO" by removing it from the or as the 3rd parameter of Alert.show.
just navigate back to your website :)
navigateToURL(new URLRequest("linktoyourwebsite"));
to get the current page's url, you can use the following code:
import flash.external.ExternalInterface;
var pageURL:String = ExternalInterface.call('window.location.href.toString');
so your code then becomes:
var pageURL:String = ExternalInterface.call('window.location.href.toString');
navigateToURL(new URLRequest(pageURL));
another answer.
we have to call function in AS3
ExternalInterface.call("reload");
in html file within javascript we have to define function reload
function reload()
{
window.location.reload(true);
}
Related
I need to create a component using ActionScript. Can't use mxml in this case.
In my component I need to create PopUpAnchor using new operator and addElement to the stage. Unfortunatelly when I'm doing it, the PopUpAnchor's displayPopUp property does not respond to any values.
Here is my the example:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
initialize="init(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.components.Label;
import spark.components.PopUpAnchor;
protected function init(event:FlexEvent):void
{
var anchor:PopUpAnchor = new PopUpAnchor();
var label:Label = new Label();
label.text = 'ABC';
anchor.addChild(label);
addElement(anchor);
anchor.displayPopUp = true;
}
]]>
</fx:Script>
</s:WindowedApplication>
I'm using Flex SDK 4.5 with AIR SDK 2.6.
What am I doing wrong?
I figured it out. The problem is that i connot use addChild on anchor. I should use popUp property instead.
So, this line is WRONG:
anchor.addChild(label);
and should be corrected to this form:
anchor.popUp = label;
I have prepared a simplified test case for my question. It will run instantly in your Flash Builder if you put the 2 files below into a project.
I'm trying to display a List of strings and a confirmation checkbox in a popup:
In the real application I dispatch a custom event with the string selected in the list, but in the test code below I just call trace(str);
My problem: if I use click event, then the window closes, even if I click at a scrollbar (the !str check below doesn't help, when an item had been selected in previous use). And if I use change event, then the window doesn't close, when I click on the same item as the last time. And the itemClick event seems not to be present in spark.components.List anymore.
Any suggestions please on how to handle this probably frequent problem?
Writing a custom item renderer and having a click event handler for each item seems to be overkill for this case, because I have strings in the list.
Test.mxml: (please click myBtn few times - to see my problems with click and change)
<?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="400" minHeight="300">
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
private var _popup:Popup = new Popup();
private function showPopup(event:MouseEvent):void {
PopUpManager.addPopUp(_popup, this, true);
PopUpManager.centerPopUp(_popup);
}
]]>
</fx:Script>
<s:Button id="myBtn" right="5" bottom="5"
label="Open window" click="showPopup(event)" />
</s:Application>
Popup.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s: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"
width="240" height="240"
creationComplete="init(event)"
close="close()">
<fx:Script>
<![CDATA[
import mx.collections.ArrayList;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.events.CloseEvent;
import mx.events.ItemClickEvent;
import mx.managers.PopUpManager;
private var myData:ArrayList = new ArrayList();
private function init(event:FlexEvent):void {
// XXX in the real app data is updated from server
myData.removeAll();
for (var i:uint = 1; i <= 10; i++)
myData.addItem('Item #' + i);
}
public function close(event:TimerEvent=null):void {
PopUpManager.removePopUp(this);
}
private function handleClick(event:MouseEvent):void {
var str:String = myList.selectedItem as String;
if (!str)
return;
if (myBox.selected) {
Alert.show(
'Select ' + str + '?',
null,
mx.controls.Alert.YES | mx.controls.Alert.NO,
null,
handleConfirm,
null,
mx.controls.Alert.NO
);
} else {
sendEvent();
}
}
private function handleConfirm(event:CloseEvent):void {
if (event.detail == mx.controls.Alert.YES)
sendEvent();
}
private function sendEvent():void {
close();
// XXX in the real app dispatchEvent() is called
trace('selected: ' + (myList.selectedItem as String));
}
]]>
</fx:Script>
<s:VGroup paddingLeft="20" paddingTop="20"
paddingRight="20" paddingBottom="20" gap="20"
width="100%" height="100%">
<s:List id="myList" dataProvider="{myData}"
click="handleClick(event)"
width="100%" height="100%" fontSize="24" />
<s:CheckBox id="myBox" label="Confirm" />
</s:VGroup>
</s:TitleWindow>
Also I wonder, why do I get the warning above:
Data binding will not be able to detect assignments to "myData".
The Spark List dispatches an 'IndexChangeEvent.CHANGE'. You can listen for this event to know when the selection in the List has changed.
<s:List id="myList" dataProvider="{myData}"
change="handleIndexChange()"
width="100%" height="100%" fontSize="24" />
That event is only dispatched whenever the selected index actually changes, which means that when you reopen the window a second time an item might still be selected and when you click on that one, no CHANGE event will be fired. To fix this just deselect the selection before you close the window:
public function close():void {
myList.selectedIndex = -1;
PopUpManager.removePopUp(this);
}
Also make sure to dispatch your event with the selected item before you close the window (and deselect it).
As for your question about the binding warning: you get that message because you didn't mark 'myData' to be bindable. To fix this just use the [Bindable] tag:
[Bindable]
private var myData:ArrayList = new ArrayList();
or skip the binding altogether if you don't need it and just assign the dataprovider to the list in ActionScript:
myList.dataProvider = myData;
I'd recommend two solutions if you absolutely wnat to display what item was selected. Otherwise, the solution provided by RIAStar would do the trick.
Listen to rendererAdd and rendererRemove events within your PopUp
As explained here, you can easily access to your list's renderers without interfering with its virtualLayout business.
Use a custom renderer
I know. But as long as you keep your code clean, itemRenderers won't blow up your application's memory. They're made to render huge amount of items without memory leaks.
In your Test.mxml, modify the codes like:
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
private var _popup:Popup;
private function showPopup(event:MouseEvent):void {
_popup = new Popup();
PopUpManager.addPopUp(_popup, this, true);
PopUpManager.centerPopUp(_popup);
}
]]>
</fx:Script>
And in your Popup.mxml, I am not sure why you have the TimerEvent in the close function.
Also the trace won't be shown, as you are calling the close() function immediately after the alert's YES button has been clicked..
When I test my deployed app in a browser the popup window continues to be displayed even after it should be closed. Everything works as expected when debugged in Flash Builder 4.
Following is currently what's happening: the request is sent to my restful web service, which processes the request, (seemingly) the ResultEvent is called which in turn dispatches the profileEvt dynamic event that changes the view state. However, the popup window does not get closed and the applet gets 'stuck.'
Anyone know what could be the problem? Below are the flex applet web service event listeners/handlers:
webService.addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void
{
var rawData:String = String(event.result);
var profileEvt:DynamicEvent = new DynamicEvent("profileSaved", true);
profileEvt.data = JSON.decode(rawData).profile;
dispatchEvent(profileEvt); // Dispatch profile saved event
_progressPopUp.closePopUp();
dispatchEvent(event); // Dispatch submit profile button clicked
});
webService.addEventListener(FaultEvent.FAULT, function(event:FaultEvent):void
{
Alert.show("Could not create profile; please try again later.\n" + event.message, "Status");
_progressPopUp.closePopUp();
});
var params:Object = {"profile" : profile};
try
{
_progressPopUp = PopUpManager.createPopUp(this, com.profs.ui.components.ProgressPopUp, true);
_progressPopUp.eventSource = webService; // Set source of progress events
webService.send(JSON.encode(params));
}
NOTE:
com.profs.ui.components.ProgressPopUp is a custom component; the code for it is below:
<?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="absolute" width="300" height="200" showCloseButton="false" title="Status" creationComplete="init()">
<fx:Declarations></fx:Declarations>
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
[Bindable] public var eventSource:Object;
private function init():void
{
PopUpManager.centerPopUp(this);
}
public function closePopUp():void
{
PopUpManager.removePopUp(this);
}
public function completionHandler(event:Event):void
{
closePopUp();
}
]]>
</fx:Script>
<mx:ProgressBar id="progressBar" indeterminate="true" mode="event" source="{eventSource}" complete="completionHandler(event)" verticalCenter="0" horizontalCenter="0"/>
</mx:TitleWindow>
I am not familiar with the com.profs.ui.components.progressPopUp component, but it is possible that the closePopUp() method has a bug in it. You could try to remove the ProgressPopUp directly using the PopUpManager method. For example instead of:
_progressPopUp.closePopUp();
try
PopUpManager.removePopUp(_progressPopUp);
I also don't know off the top of my head what the rules for closures are (i.e. at which point is the _progressPopUp variable copied into the ResultEvent.RESULT event handler. You could try moving that particular event handler below the line where you actually created the _progressPopUp instance.
In my Flex application, users need to be able to upload and download content. However, this content is access restricted, and I need to do a permissions check before allowing the upload/download. The user clicks a link, and then selects a file using the FileReference class. The FileReference class doesn't attach cookie information, so I can't use a session.
I want to implement a 2 step process where the client first pings the server to get a one-time-use token, and then does the upload or download with the one-time-use token as a parameter. However, this plan is being foiled by error #2176, which is apparently a security fix to FP10, that only allows uploads/download to be triggered during a MouseEvent propogation. Anyways around this?
I got workarround for this here.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
minWidth="955" minHeight="600"
creationComplete="creationCompleteHandler(event)">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.events.FlexEvent;
protected function creationCompleteHandler(event:FlexEvent):void
{
Alert.show("Now you can save the file!", "Test", Alert.OK|Alert.CANCEL, null, closeHandler);
}
protected function closeHandler( event:CloseEvent ):void
{
var fileReference :FileReference;
if ( event.detail == Alert.OK )
{
fileReference = new FileReference();
fileReference.save("http://www.bogdanmanate.com", "test.txt");
}
}
]]>
</mx:Script>
</mx:Application>
I have a Flex RIA App, and in the application tag there is a button when it's pressed calls upon a TitleWindow from another .mxml file, and sets
application.enable = false
That way the user can't use any of the components in the application, and still can use the components in the TitleWindow.
The problem is when the TitleWindow is closed I want it to restore the application back to
application.enable = true
Which enables the application once again. But I can't call that code from inside the TitleWindow .mxml
How can I do it?
Here is the Source:
Loja.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="585" height="450" xmlns:ns1="com.*">
<mx:Style source="theme/simplicitygray.css" />
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
private var clientid = 0;
public function openWindow() : void
{
if (clientid == 0)
{
PopUpManager.createPopUp(this,Login,false);
application.enabled = false;
} else {
PopUpManager.createPopUp(this,Conta,false);
application.enabled = false;
}
}
]]>
</mx:Script>
<mx:Panel x="10" y="40" width="565" height="400" layout="absolute">
</mx:Panel>
<mx:MenuBar x="10" y="10" width="565" height="22"></mx:MenuBar>
<mx:Button x="508" y="10" label="Aceder" click="openWindow();"/>
</mx:Application>
And one of the title windows. Once they are the same.
Login.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="350" height="200" creationComplete="centerWindow()" showCloseButton="true" close="closeWindow()" title="Login">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
public function centerWindow():void
{
PopUpManager.centerPopUp(this);
}
public function closeWindow():void
{
PopUpManager.removePopUp(this);
}
]]>
</mx:Script>
</mx:TitleWindow>
application is a static property of the Application class and can be called from the TitleWindow
public function closeWindow():void
{
PopUpManager.removePopUp(this);
Application.application.enabled = true;
}
BTW, There is another easier way to achieve the following:
That way the user cant use any of the components in the application, and still can use the components in the TitleWindow.
That is to use a modal popup. Set the third parameter of the createPopUp to true and that's it - you don't have to enable/disable the application manually: flex will take care of it.
PopUpManager.createPopUp(this,Login, true);
application will automatically become functional once you call removePopUp.
You can use custom events to enable this functionality, as described here.
Essentially, you set up a custom event in the class you are calling, then create a function that runs when the event is consumed. That way your 'Loja' will know when the 'Login' is done.