Select to view content in your preferred language

Closing Multiple Widgets

1216
2
03-03-2011 07:59 AM
CraigPlacek
New Contributor
I am developing a set of themes for a project that the user can choose within the Flex viewer.  Each theme will have a certain set of widgets available in the header.  When the user moves from one theme to the next I loop through the widgets that are currently loaded from the header and determine which should be closed because the next selected theme does not include them.  I am dispatching the MouseEvent.Click on the closeButton of the widget template for each of the widgets that I close.  This works when there is only one that needs to be closed, but when there is more than one only one closes properly and the remaining widgets that were dispatched to close, everything accept the background of the widget appears to unload (looks like a widgettemplate but there are no close or minimize buttons... nothing remains).  I attached 2 images that show a before and after look at what happens to the widgets affected.

I have developed a work around for this by creating a timer for each of the widgets that need to be closed and running the function on them at least a second apart from one another, and they all close using that as a solution.  But it slows down the process.

Has anyone seen the behavior I described when closing multiple widgets within a function?
0 Kudos
2 Replies
ReneRubalcava
Esri Frequent Contributor
Not too familiar with the innards of the Flexviewer framework, but looking at the WidgetTemplate and BaseWidget, I don't think calling the MouseEvent is the best way to go about it.

After some tinkering I was able to close a widget programatically this way.
ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_CHANGE_STATE, {id: this.widgetId, state:WidgetStates.WIDGET_CLOSED}));


So if you can iterate through the widget ids, you should be able to dispatch that event for each widget you want to close.

Looking at the event chain on the close_clickHandler for the WidgetTemplate, you may want to set the widget.widgetState before dispatching the ViewContainer event.


Just tested on multiple widgets, nevermind, that doesn't work either.
0 Kudos
by Anonymous User
Not applicable
Original User: mehu11111

TO CLOSE MULTIPLE WIDGETS:

In your widget :
--------------
var widgetIdxUnLoadArray:Array = [6,7,8];
private var closeMultiple:Boolean = false; 

          protected function button2_clickHandler(event:MouseEvent):void
              
           {
               closeMultiple = true;
               preUnloadNextWidget();
           }
           
           private function preUnloadNextWidget():void
          {
               if (widgetIdxUnLoadArray.length > 0)
               {
                   var id:Number = widgetIdxUnLoadArray[0];
                   widgetIdxUnLoadArray.splice(0, 1);
                   ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_STOP, id));
               }
           }
           private function myWidgetRemovedHandler(event:AppEvent):void
          {
               if (closeMultiple)
               { 
                   closeMultiple=false;
                   preUnloadNextWidget();
               }
           }



In WidgetContainer.MXML,
-------------
add elementRemove as shown below
 
<s:Group id="widgetContainer"
            width="100%" height="100%"
            left="{_left}" left.collapsedRight="{containerWidth}" left.resized="{_left}" right="{_right}" right.normal="{_right}" right.resized="{_right}" top="{_top}" top.collapsedDown="{containerHeight}" top.resized="{_top}" bottom="{_bottom}" bottom.resized="{_bottom}"
            clipAndEnableScrolling="true"
            elementAdd="widgetAddedHandler(event)"
            elementRemove="widgetRemoveHandler(event)" />



And

protected function widgetRemoveHandler(event:ElementExistenceEvent):void
{
var wObj:IVisualElement = event.element;
ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_REMOVED, wObj));
}



In AppEvent.as
---------
public static const WIDGET_REMOVED:String = "widgetRemoved";
public static const WIDGET_STOP:String = "widgetStopRequested";


In WidgetManager.mxml
----------------
add following line in Init() Method:
 ViewerContainer.addEventListener(AppEvent.WIDGET_STOP, onStopWidget);


Add following method:
private function onStopWidget(event:AppEvent):void
          {
               var id:Number = event.data as Number;
               var idx:Object = configData.widgetIndex[id];
               
               var wgtContainer:IWidgetContainer = configData.widgetContainers[idx.container].container.obj;
               var wgt:Object = configData.widgetContainers[idx.container].widgets[idx.widget];
               
               widgetAdded = false;
               
               var widget:IBaseWidget;
               if (widgetTable.containsKey(id))
               {
                   widget = widgetTable.find(id) as IBaseWidget;
                   widget.setState(BaseWidget.WIDGET_CLOSED);
               }
         
}



TO OPEN MULTIPLE WIDGETS

Add following code in widget
<s:Button label="Open Multiple Widget" click="button1_clickHandler(event)" />
 
var widgetIdxArray:Array = [6,7,8]; // 6,7,8 are widget Ids. This can be obtained from configData object
           protected function button1_clickHandler(event:MouseEvent):void
          {
               ViewerContainer.addEventListener(AppEvent.WIDGET_ADDED, myWidgetAddedHandler);
               preloadNextWidget();
           }
           
           private function preloadNextWidget():void
          {
               if (widgetIdxArray.length > 0)
               {
                   var id:Number = widgetIdxArray[0];
                   widgetIdxArray.splice(0, 1);
                   ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_RUN, id));
               }
           }
           private function myWidgetAddedHandler(event:AppEvent):void
          {
               preloadNextWidget();
           }


hope this helps.

0 Kudos