One of the things that I don’t like about the Flex Popup’s is that despite it being a “view”, I can not declare it within mxml. I have to create a separate class for the popup component and then use the PopUpManager API to display it and remove it. Wouldn’t be so nice if I could just declare the component to opened up, within my mxml  and I could easily pass/get data from the component using bindings etc.


It is especially useful when creating Skinnable components as I can declare some component as a SkinPart and in the skin declare it to be opened up in a popup.


As I was looking to do something like that, I came across another Flex component – PopUpAnchor.


This is a very useful component which can be used to position a popup control. What this control doesn’t do, is to open the popup in modal and centered manner. So I decided to create my own PopUpUIComponent component by stripping this PopUpAnchor of all the positioning code and use it only to open centered/ modal popups.


I quickly hatched a sample application which allows user to input text and then the text is passed onto the popup using bindings. The application can be seen below.





The PopUpUIComponent looks like this:



 

package

{

    import flash.display.DisplayObject;

    import flash.events.Event;

    import mx.core.FlexGlobals;

    import mx.core.IFlexDisplayObject;

    import mx.core.IUIComponent;

    import mx.core.UIComponent;

    import mx.managers.PopUpManager;

    import mx.styles.ISimpleStyleClient;


    [DefaultProperty( “popUp” )]

    public class PopUpUIComponent extends UIComponent

    {


        public function PopUpUIComponent()

        {

            addEventListener( Event.ADDED_TO_STAGE, addedToStageHandler );

            addEventListener( Event.REMOVED_FROM_STAGE, removedFromStageHandler );

        }


        [Bindable]

        public var isCentered : Boolean = true;


        [Bindable]

        public var isModal : Boolean = true;


        [Bindable]

        public var parentOfPopup : DisplayObject = FlexGlobals.topLevelApplication as DisplayObject;


        private var _displayPopUp : Boolean = false;


        private var _popUp : IFlexDisplayObject;


        public function get displayPopUp() : Boolean

        {

            return _displayPopUp;

        }


        /**

         *  If <code>true</code>, adds the <code>popUp</code> control to the PopUpManager.

         *  If <code>false</code>, it removes the control.

         *

         *  @default false

         */

        public function set displayPopUp( value : Boolean ) : void

        {

            if (_displayPopUp == value)

            {

                return;

            }


            _displayPopUp = value;

            addOrRemovePopUp();

        }


        public function get popUp() : IFlexDisplayObject

        {

            return _popUp

        }


        [Bindable( “popUpChanged” )]


        /**

         *  The IFlexDisplayObject to add to the PopUpManager when the PopupUIComponent is opened.

         *  If the <code>popUp</code> control implements IFocusManagerContainer, the

         *  <code>popUp</code> control will have its

         *  own FocusManager. If the user uses the Tab key to navigate between

         *  controls, only the controls in the <code>popUp</code> control are accessed.

         */

        public function set popUp( value : IFlexDisplayObject ) : void

        {

            if (_popUp == value)

            {

                return;

            }


            _popUp = value;


            if (_popUp is ISimpleStyleClient)

            {

                ISimpleStyleClient( _popUp ).styleName = this;

            }


            dispatchEvent( new Event( “popUpChanged” ));

        }


        private function addOrRemovePopUp() : void

        {

            if (popUp == null)

            {

                return;

            }


            if (DisplayObject( popUp ).parent == null && displayPopUp)

            {

                PopUpManager.addPopUp( popUp, parentOfPopup, isModal );

                if (isCentered)

                {

                    PopUpManager.centerPopUp( popUp );

                }

                if (popUp is IUIComponent)

                {

                    IUIComponent( popUp ).owner = this;

                }

            }

            else if (DisplayObject( popUp ).parent != null && displayPopUp == false)

            {

                removeAndResetPopUp();

            }

        }


        private function addedToStageHandler( event : Event ) : void

        {

            addOrRemovePopUp();

        }


        private function removeAndResetPopUp() : void

        {

            PopUpManager.removePopUp( popUp );

        }


        private function removedFromStageHandler( event : Event ) : void

        {

            if (popUp != null && DisplayObject( popUp ).parent != null)

            {

                removeAndResetPopUp();

            }

        }

    }

}

 

 

The opening and the closing of the popup is controlled by displayPopup var (same as in PopUpAnchor).


It is not the most perfect component but it does make things easier for me to use popups in mxml skins.

Of course, there are some good alternatives out there if you are using frameworks like Cairngorm which has a nice popup library.


Hope it helps!


Download the source code




Originally published at : http://code-debugged.blogspot.in/2013/08/flex-popup-as-uicomponent.html