Communication between widgets

6171
48
09-28-2010 08:07 AM
DonCaviness
New Contributor III
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
SarthakDatt
Occasional Contributor III
Hey Don,

Assuming that you are using Flex Viewer 2.x version, every widget extends the BaseWidget class, which has the addSharedData method. This method internally dispatches the AppEvent.DATA_PUBLISH event which is used for inter-widget communication.

e.g:

Widget 1

 
private function widgetCommunication1():void
{
    addSharedData("your key", shared data(ArrayCollection)); 
}


Widget 2

<viewer:BaseWidget xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:viewer="com.esri.viewer.*"
                   initialize="basewidget1_initializeHandler(event)"
                   >
    <fx:Script>
        <![CDATA[
            import com.esri.viewer.AppEvent;
           
            import mx.events.FlexEvent;

            protected function basewidget1_initializeHandler(event:FlexEvent):void
            {
                ViewerContainer.addEventListener(AppEvent.DATA_PUBLISH, sharedDataUpdated);
            }
           
            private function sharedDataUpdated(event:AppEvent):void
            {
                var data:Object = event.data;

                if (data.key == "my key") 
                {
                     // do something..     
                }
            }
        ]]>
    </fx:Script>



Hope that helps.
0 Kudos
DonCaviness
New Contributor III
Thank you! That is what I was looking for.
0 Kudos
BobCarberry
New Contributor
Sarthak,

Do you know of anyway to open a widget from another widget?
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Bob,

   You have to know your widgets Id number. The widgets id is not a string it is a sequential number that is assigned when the widget is created in FlexViewer.

Here is the code:

ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_RUN, yourWidgetsID#));


I added a new function to the ViewerContainer.mxml for the purpose of finding a widgets id #

//Add this new variable at the beginning with the other  private and public vars
public var _configData:ConfigData;

//Add this new function
                        public function getWidgetId(widgetLabel:String):Number
   {
    var id:Number;
    for (var i:Number = 0; i < _configData.widgets.length; i++)
    {
     if (_configData.widgets.label == widgetLabel)
      id = _configData.widgets.id;
    }
    return id;
   }

//Add this to the postConfigHandler function
_configData = event.data as ConfigData;


Then you can do something like this

ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_RUN, ViewerContainer.getWidgetId("Search")));
0 Kudos
DonCaviness
New Contributor III
Robert, do you know how I would go about calling a function in the flex viewer using a javascript function in a html page?  I have found this example on how to communicate between flex and javascript http://www.switchonthecode.com/tutorials/flex-javascript-basics-using-externalinterface but I am having trouble getting this to work with the 2.1 flex viewer.
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Don,

  I am looking into it. Can you give me a use case or workflow that you are considering this for?
0 Kudos
DonCaviness
New Contributor III
Here is what I am trying to do.  I have a custom wrapper that the flex viewer lives in.  On the html page a have a button that fires an JavaScript event that changes some information within the html.  In the flex viewer I have a widget that will display data depending what is selected by the user clicking on the button in the html wrapper.  In other words, I want to change label text, make components visible or hidden, etc. in the widget when the user fires off a JavaScript function.  I was successful in using the code snippet provided in this thread to communicate between wigets, so I was hoping I could communicate with the widget but from outside of flex.
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Don,

   Took a while to find time for this but here it is:
index.template.html  code:
<script type="text/javascript">
            function getFlexApp(appName)
            {
              if (navigator.appName.indexOf ("Microsoft") !=-1)
              {
                return window[appName];
              }
              else
              {
                return document[appName];
              }
            }
            function someFlexFunction()
            {
                getFlexApp('index').flexTalk('Hello World');
            }
        </script>
        <input type="button" id="butFlexTalk" onclick="someFlexFunction()" value="Say Hello" />


index.mxml portion
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:viewer="com.esri.viewer.*"
               xmlns:managers="com.esri.viewer.managers.*"
               pageTitle="ArcGIS Viewer for Flex"
               initialize="initApp()">
               
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            public function initApp():void
            {
                if (ExternalInterface.available)
                    ExternalInterface.addCallback("flexTalk", flexTalk);     
            }
            
            public function flexTalk(sayThis:String):void
            {
                Alert.show(sayThis);
            }
        ]]>
    </fx:Script>

    <fx:Style source="defaults.css"/>


Of course from here you will have to use some appEvent or something to get from the index.mxml into some widget or what ever you are trying to do.
0 Kudos
DonCaviness
New Contributor III
Thank you Robert.
0 Kudos