Select to view content in your preferred language

Communication between widgets

7250
48
09-28-2010 08:07 AM
DonCaviness
Occasional Contributor
Does anyone know how I would go about communicating between widgets?  I would like to use a button in one widget to call a function in another or change components (label text, visible property, etc) in another widget.  Any help will be appreciated.
Tags (2)
0 Kudos
48 Replies
LeiZhou
Deactivated User
I changed that to :

var viewerCon:ViewerContainer = ViewerContainer.getInstance();

Then it works. Thank you all!

Anthony,

All you have to do is call
ViewerContainer.getInstance()
0 Kudos
FrankRoberts
Frequent Contributor
Robert et al, Regarding launching widget1 from widget2.  I made the ViewerContainer.mxml changes as mentioned above.  I then added the code per step two above.  It was working just great. I've been busy writing more code for the same widget,  now the other widget won't launch....  So assume I broke something.  I then created a new widget, so I can just figure out what I did wrong, and it won't work either....  The below is my stripped down widget2 code.  Do you guys see any reason why this wouldn't work?  Thanks for the extra set of eyes..

Frank
<?xml version="1.0" encoding="utf-8"?>
<viewer:BaseWidget xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   xmlns:esri="http://www.esri.com/2008/ags"                   
       xmlns:Search="widgets.Response.*"
       xmlns:viewer="com.esri.viewer.*"
                   widgetConfigLoaded="init()">
    <fx:Script>
        <![CDATA[
   
   import com.esri.viewer.ViewerContainer;
   import com.esri.viewer.AppEvent;      
   import mx.controls.Alert;
      
   private var viewerCon:ViewerContainer;
         
   //this function called when the widget's configuration is loaded
                        private function init():void
                        {             
    
   }
   
   protected function editButton_clickHandler(event:MouseEvent):void
   {
    ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_RUN, viewerCon.getWidgetId("Edit")));    
   }         
  ]]>
    </fx:Script>
 <fx:Declarations>
  
  <!-- Place non-visual elements (e.g., services, value objects) here -->
 </fx:Declarations> 
    <viewer:WidgetTemplate id="Removal" width="450" height="180">  
  <mx:Button id="editButton" label="Edit" click="editButton_clickHandler(event)"/>       
    </viewer:WidgetTemplate>
</viewer:BaseWidget>
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Frank,

   The ViewerContainer is a singleton so you need to get the instance. Try:

protected function editButton_clickHandler(event:MouseEvent):void
            {
                ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_RUN, ViewerContainer.getInstance().getWidgetId("Edit")));                
            }
0 Kudos
FrankRoberts
Frequent Contributor
Thanks that fixed it.  Strange that it was working and then it stopped.... 

Have a great Forth of July!
0 Kudos
grahamcooke
Regular Contributor
hi,

Hope somone can assist as i am struggling a bit with this. the use case is that a user clicks a button on a widget, a second widget should then be opened with data from the first widget copied across to the newly opened widget.

I can get the second widget open fine, but the data is not copied across unless i click the button a second time. Only on that second click is the sharedData routine in the second widget called.

Relevant code snippets are as follows (flex viewer version = 2.3.1):

1st widget (button click routine)

//call the range detail widget.
ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_RUN, ViewerContainer.getInstance().getWidgetId("Range Detail")));

//add the ArrayCollection data to the sharedData object on the BaseWidget class.
addSharedData("ArtyDetail", rangeDetailArray);


2nd widget
<viewer:BaseWidget xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   xmlns:esri="http://www.esri.com/2008/ags"
                   xmlns:viewer="com.esri.viewer.*"
                   xmlns:customValidators="Landmarc.customValidators.*"
                   initialize="myBaseWidgetInitHandler(event)"
                   widgetConfigLoaded="init()"  
                   xmlns:supportClasses="com.esri.ags.skins.supportClasses.*">

protected function myBaseWidgetInitHandler(event:FlexEvent):void
{
     ViewerContainer.addEventListener(AppEvent.DATA_PUBLISH, sharedDataUpdated);
}

public function sharedDataUpdated(event:AppEvent):void
{
    var data:Object = event.data;
    switch (data.key)
    {
         //if arty detail there is a maximum of 2 items in the ArrayCollection. First is the grids, second (if present) is the direct fire firing point
         case "ArtyDetail":
         {
              txtSta.text = data.collection[0].toString();
              //if the artillery selection was a direct fire, then there will be a firing position in the second item in the collection
              if (data.collection[1])
              {
                 txtWeaponPosition.text = data.collection[1].toString();
              }
              break;
        }
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Graham,

   Try adding this to widget 2 along with your other event listener.

ViewerContainer.addEventListener(AppEvent.DATA_SENT, sharedDataUpdated);
0 Kudos
grahamcooke
Regular Contributor
Hi Robert.

Still not working I'm afraid. Have tried various combinations of appevents without any success.

The event that is raised by addsharedata is firing before the listener is declared. But I don't understand why it has worked for others. Have I got something in the wrong order or put the events in the wrong routines or something?
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Graham,

  Now that I look at your code closer you should be adding the listeners in the init function.
0 Kudos
grahamcooke
Regular Contributor
Hi robert,

Still no joy with that i'm afraid. i got it working by creating a new AppEvent called RANGE_DETAIL_OPEN and then firing that from the init of the Range detail widget (widget 2). in widget 1 i have a listener for that and the listener routine then fires the addshareddata routine which is listened for in widget 2 init.

This works great.....BUT, it means that the second time I click the button for a different set of data, nothing works as a widgets init routine is only fired the first time it is ever loaded. I think maybe I have to fire the RANGE_DETAIL_OPEN event from somewhere in the widgetcontainer code.

I will have a play around, I'm sure there is a way to get this working. The other issue I foresee is emptying the data ArrayCollection that is passed every time addshareddata is called. It seems to always be added to every time the addshareddata is called successfully.
0 Kudos
GabrielSuárez
New Contributor
this may sound stupid, but i need to send just 1 variable from one widget as the imput of another, appereantly this methods and DATA_SENT all that stuff pops an error that "1 is not an array collection" 1 being the input of the second widget, any ideas? or help?


problem solve... now, how to i repopulate or rebuild a widget content?
0 Kudos