Tuesday, March 29, 2011

Communication with pop up window (callback & custom event)

Pop up windows are very handy components, especially for showing some important information to user. But this is only communication in one way, what if we want to get data back from user? We can put some controls to retrieve input from user in pop up window (TextArea for instance), but how this data could be transferred to main application? I will describe two methods to achieve that: callback and custom event (well that was quite obvious if you read the post title).

If you would like to just skip to the source code, you can find finished application here: LINK.

The first thing to do is to build your own custom component using TitleWindow. In Flash Builder click RMB on your project, then New -> MXML Component, in Based On choose TitleWindow (from spark.components) type something in Name and click Finish. Now you can invoke your pop up window from main app:

var popUp:PopUpWindow = PopUpWindow(PopUpManager.createPopUp(this, PopUpWindow, true));

Now we want to send some data from main app to the pop up window, but we can't do that through the constructor - you can't write your own constructor in MXML Components, even though they are just AS3 classes. So the best way (at least for me) is to write a public function that can receive data from main app:

public function setPopUpText(newText:String):void
{
  // here you should do something with received data
}

And in the main app we can now call this function with data that we want to send:

popUp.setPopUpText("This text will be send to pop up window.");

OK but what about the communication from pop up window to the main app? The first way is to set a callback variable in pop up window:

public var callbackFunction:Function = new Function();

In the main app we have to set this variable to our callback function:

popUp.callbackFunction = setCallbackText;

protected function setCallbackText(newText:String):void
{
  // here you should do something with received data
}

Now in the pop up window you can invoke that function with some data:

callbackFunction(callbackText.text);

The main drawback of this method is that when you are invoking callback function from your component you should exactly know what parameters this function take. You have to check it for yourself, there wouldn't be any compiler error, so there is some chance that something will go wrong during runtime. But, on the other hand, this method is quite simple and quick to apply.

The next method uses Flex Events to communicate. Probably this is more proper way and more "Flexy" style of coding, but I can only guess. First thing to do is create your own custom event with additional attribute to hold your data. In Flash Builder click RMB on your project, then New -> Actionscript Class, in Superclass choose Event (from flash.events) type something in Name and click Finish. Now add new attribute and name of the event to your new class:

public static var CLOSE_POP_UP:String = "closePopUp";
        
private var _text:String;

public function get text():String
{
  return _text;
}

Don't forget to add a way to set your custom data property, you can do it in many ways, I chose to set it in constructor:

public function ClosePopUpEvent(type:String, text:String, bubbles:Boolean = false, cancelable:Boolean = false)
{
  super(type, bubbles, cancelable);
            
  _text = text;
}

To send custom event from your pop up window you should set Metadata tag - remember that type must match exactly your custom event class name, and name should match exactly the name of event that you want to send:


  [Event("closePopUp", type="ClosePopUpEvent")]


Now you can dispatch your event from pop up window:

var popUpEvent:ClosePopUpEvent = new ClosePopUpEvent(ClosePopUpEvent.CLOSE_POP_UP, eventText.text);
dispatchEvent(popUpEvent);

Of course you nedd to listen for that event in main app:

popUp.addEventListener(ClosePopUpEvent.CLOSE_POP_UP, setEventText);

protected function setEventText(event:ClosePopUpEvent):void
{
  // here you should do something with received data
}

There is third method that you can use, it's also utilize events but in a different way. This method is possible only when you are using Swiz Framework, and I describe it in one of my future posts.

No comments:

Post a Comment