I am developing a static flex application which does not have a database connection, all the values are hardcoded(its just a prototype for the original app). Now when i click the save button, i need to get a message like saving in progress... please wait, I need to display this message for 3 seconds.
Please let me know how could this be done.
Thanks!
Cheers,
Deena
I am putting in the complete code of how i did it for easy reference to other users.
First Create a savingProgressBar.mxml file with the progress bar with the required format.
Then in the parent page where you want the progress bar enter the following scrip code
[In my parent page i click a button called save and on click of it i am calling the save() function]
private var pBar:IFlexDisplayObject;
private function save()
{
pBar=PopUpManager.createPopUp( this, savingProgressBar, true);
PopUpManager.centerPopUp(pBar);
var myTimer:Timer = new Timer(1500,1)
myTimer.addEventListener(TimerEvent.TIMER, timerHandler);
myTimer.start();
}
public function timerHandler(event:TimerEvent):void
{
PopUpManager.removePopUp(pBar);
}
]]>
Hope this helps,
cheers,
Deena
Fist create a timer with:
private var t:Timer = new Timer(3000,1);
Then add an event lister to resond when the timer will be finished:
t.addEventListener(TimerEvent.TIMER_COMPLETE, removeMSG);
//start timer
t.start();
Add, removeMSG function that will remove your progress bar or notifier:
private function removeMSG(e:TimerEvent):void{
//code to remove the notification
}
Also if you plan to use ProgressBar control in Flex use indeterminate="true" that will make progress bar move without any feedback data from your webservice
Use a timer that triggers every 200ms or something, and each time it triggers have it add 3s/200ms to the progress bar.
Related
I have a GridView in which the last Column has a Button which loads data. Doing that takes like 2 Minutes. So, I need the user to know that some functions are going on in backend not that the screen is frozen So, I need to show ProgressBar in a click of that button inside the GridView How to do that??
please advice on this
Thanks in Advance.
if You have some functions which do this operation You can set global boolean, which show when this function ended and then check if function is ended set progress bar value higher.
private bool functionLoaded = false;
private void first()
{
//some code
functionLoaded = true;
}
private void NumberOfScenariosChanged(Object sender, EventArgs e)
{
if (functionLoaded)
return;
UpdateScenarioDataGrid();
}
Or if always it takes 2 minutes You can do a little trick and create second thread which rising progress bar value moment by moment. It will be only for show for user that program is not stopped.
I have two layouts in JavaFX app. The first one contains table view whereas the second one is a simple dialog to input data. The problem is that I want to refresh data after closing the dialog. Now I have a button on the first layout which refreshes data:
data.removeAll(data);
loadDataToTable();
But I don't want to invoke methods shown above with the button but automatically right after closing the dialog. I don't know how to make this, let's say, connection between those controllers.
thanks in advance
The new Dialog, if I am not wrong must be a new Stage ! Let us consider the new Stage to be modifyStage. We can call the onSetCloseRequest of the new Stage and put your code in it.
modifyStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent paramT) {
data.removeAll(data);
loadDataToTable();
}
});
I have DataGrid control in Flash Builder, it shows a long list of data.
I want to set a timer, so every time the timer ticks, the timer will call a function which makes the DataGrid control do a pagedown action, just like you click the scroll bar every 3 seconds. What is the easiest way?
Thanks.
Even-though it's not very clear you can try something like this
private var gridTimer:Timer;
public function onSomeFunction():void
{
gridTimer = new Timer(5000); //the timer is set for 5 seconds
gridTimer.addEventListener("timer", dataGridTimer);
gridTimer.start();
}
private function dataGridTimer(event:TimerEvent):void
{
grid.verticalScrollPosition = value;
}
I am using view stack...so when view change like when we move from one page to another hide event is dispatched.So i am saving the information of last page in hide event before i go to next page.but thing is that if i change nothing still change on view hide event is invoked nd call go to backend...i just want do call only if sumthing change in the view..like sum text value...So i have two options
use event listener on each component if sumthing change its make the flag true...nd hide event check, if flag is true send call to backend.
event listener at container level ..if sumthing change in child componenet through bubbling container knows if sum event is dispatched.nd makes the flag true.
I have doubt with container...
Can i use container, and how?
Reason why I can't use container?
What are the pros and cons either way?
I would recommend using a dataProvider with the ability to compare them. For instance, if you are changing things with textinputs, you could basically do something like this:
[Bindable]
private var myDataProvider:Object = new Object();
private function creationCompleteHandler():void {
myDataProvider.updated = false;
myDataProvider.defaultValue = 'default';
myDataProvider.defaultValueTwo = 'default';
}
etc.
Then, in your mxml, you can have something like this:
<mx:TextInput id="myText" text="{myDataProvider.defaultValue}" change="myDataProvider.defaultValue=myText.text; myDataProvider.updated=true;" />
Lastly, in your hide event, you can do the following:
private function hideEventHandler( event:Event ):void {
if( myDataProvider.updated ){
// Call your RemoteServices (or w/e) to update the information
}
}
This way, when anything changes, you can update your dataProvider and have access to the new information each time.
Hope this helps!
I've used an approach similar to your first option in a couple of my past projects. In the change event for each of my form's controls I make a call to a small function that just sets a changesMade flag to true in my model. When the user tries to navigate away from my form, I check the changesMade flag to see if I need to save the info.
Data models are your friend!
If you get in the habit of creating strongly typed data models out of your loaded data, questions like this become very basic.
I always have a key binding set to generate a code snipit similar to this...
private var _foo:String;
public function get foo():String
{
return _foo;
}
public function set foo(value:String):void
{
if(_foo == value)
return;
var oldVal:String = _foo;
_foo = value;
this.invalidateProperty("foo", oldVal, value);
}
If your data used getters/setters like this, it would be very easy to validate a change on the model level, cutting the view out of the process entirely.
How can I open a synchronous dialog in Flex? I need to call a function from an External Interface (JavaScript) that will open a simple dialog in the Flex application and returns an value according to the button the user has clicked (OK/Cancel).
So it should by a synchronous call to a dialog, i.e. the call waits until the user has closed the dialog like this.
//This function is called by JavaScript
function onApplicationUnload():Boolean
{
var result:Boolean;
result = showDialogAndWaitForResult();
return result
}
Does anybody know how I can do this? I could write a loop that waits until the dialog has set a flag and then reads the result to return it, but there must be something that is way more elegant and reusable for waiting of the completion of other asynchronous calls.
EDIT:
Unfortunately a callback does not work as the JavaScript function that calls onApplicationUnload() itself has to return a value (similar to the onApplicationUnload() function in Flex). This JavaScript function has a fixed signature as it is called by a framework and I cannot change it. Or in other words: The call from JavaScript to Flex must also be synchronous.
Flex doesn't work in a synchronous fashion, as it is a single thread application and so needs your code to hand execution back to the "core" in order to handle user input etc.
The way to do it is to make your dialogue's behaviour asynchronous:
function onApplicationUnload():void
{
showDialog(resultMethod);
}
function resultMethod(result:Boolean):void
{
ExternalInterface.call("javaScriptCallback", [result]);
}
You can't do that in Flex. As David mentioned, Flex is single-threaded, so you can't have your function block while the dialog is being processed.
Your best bet might be to use a Javascript popup. You'll have a lot less control over the window, but it should behave the way you want (blocking the function until it's been closed).
Have your Flex code use an event to wait for the dialog. In the main thread, register an event handler that waits for the dialog to close. On OK in the dialog, dispatch the dialog complete event.
With Cairngorm, this is something like:
In the main thread:
CairngormEventDispatcher.getInstance().addEventListener(ClosingDialogCompleteEvent.DIALOG_COMPLETE, onClosingDialogComplete);
(if you want to avoid returning until complete, loop on a timer and global variable.)
In the dialog closing handler:
CairngormEventDispatcher.dispatchEvent(new ClosingDialogCompleteEvent(<parameters>));
The event handler:
public function onClosingDialogComplete (e: ClosingDialogCompleteEvent):void
{
param1 = e.param1;
param2 = e.param2;
// etc.
// Continue processing or set the global variable that signals the main thread to continue.
}
For this to work, the class ClosingDialogCompleteEvent has to be defined. Partial code for the class is:
package com. ... .event // You define where the event lives.
{
import com.adobe.cairngorm.control.CairngormEvent;
public class ClosingDialogCompleteEvent extends CairngormEvent
{
// Event type.
public static const DIALOG_COMPLETE:String = "dialogComplete";
public var param1:String;
public var param2:String;
public function ClosingDialogCompleteEvent(param1:String, param2:String)
{
super(DIALOG_COMPLETE);
this.param1 = param1;
this.param2 = param2;
}
}
}
Waiting on an event is the best way to synchronize in Flex. It works well for startup dialogs too. In a flex-only application it works especially well.
I have explained a workaround to create synchronous alert in flex
http://reallypseudorandom.blogspot.com/2010/05/flash-asynchronous-alert-and-pause.html
OK... after all I found a possible solution. But I guess hardly everybody is going to do that seriously :-(
The solution focuses around using a while loop to check for a result and then return the function that is being called by JavaScript. However we need a way to sleep in the while loop, while we are waiting for the result. However calls to JavaScript are synchronous. Now the trick is to make a sleep in JavaScript, which is also not directly available here, but can be done using a synchronous XML Http Request like described on this blog.
As I said - I won't recommend this only as last resort. For my problem I have resorted to ugly JavaScript popups.
Have your dialog call another function in flex to process the result of the user selection:
private function deleteFileCheck():void
{
Alert.show("Are you sure you want to delete this file?",
"Confirm Delete",
Alert.YES| Alert.NO,
this, deleteFileHandler, null, Alert.NO);
}
private function deleteFileHandler(event:CloseEvent):void
{
if (event.detail == Alert.YES)
{
...do your processing here
}
}
You can fake a synchronous dialog in flex by popping up a dialog then disabling everything in the background. You can see this in action if you do Alert.show("Hello World"); in an application. The background will grey out and the user won't be able to click on any UI in the background. The app will "wait" until the user clicks the OK button.