Select to view content in your preferred language

infoWindow - zoom button click - Flex API 1.3

992
6
10-29-2010 07:31 AM
TracySchloss
Frequent Contributor
I'm using a queryTask to define tooltips, graphic, listeners etc.  I have an infoWindow that comes up when the user clicks a point.  I'd like to be able to add a button within the infoWindow that zooms to the point when the user clicks that button.

I've added a listener to the graphic:
myGraphic.addEventListener("zoomHere",zoomHandler);


Then wrote the handler function:
 public function zoomHandler(event:MouseEvent): void {
   var newMapPoint:MapPoint = MapPoint(lastGraphic.geometry);
   if (mainMap.scale > 100000)
   {
    mainMap.scale = 100000; 
   } else {
    var zoomScale:Number = mainMap.scale / 4;
    mainMap.scale = zoomScale;
   }
    mainMap.centerAt( newMapPoint);  
 }

I'm not sure exactly how or where to call the click event.  There isn't any error when I compile, but the event handler I created never gets called.  So maybe I don't have the listener added to the right thing?  I was able to add a listener to the whole Infow window using mainMap.infoWindow.addEventListener(MouseEvent.CLICK,zoomHandler), but I really only want the event on the button, not the whole infoWindow.

   <mx:Component className="MyInfoWindowRenderer" > 
      <mx:VBox verticalGap="-5" height="100%">
        <infoClasses:InfoWindowLabel styleName="balloonTitle" text="{data.FACILITY}" width="100%"/>
    <mx:Label text="{data.ADDRESS}" />
    <mx:Label text="{data.CITY}"/>
  

             <mx:Label includeInLayout="{data.PHONE1 != ''? true:false}" 
     visible="{data.PHONE1 != ''? true:false}" text="Phone:  {data.PHONE1}"/> 
     
             <mx:Label includeInLayout="{data.PHONE2 != ''? true:false}" 
     visible="{data.PHONE2 != ''? true:false}" 
     text="Phone:  {data.PHONE2}"/>
    
    <mx:Label includeInLayout="{data.PHONE3_FB != ''? true:false}" 
     visible="{data.PHONE3_FB != ''? true:false}" 
     text="Phone:  {data.PHONE3_FB}"/>
<!--     <mx:Label includeInLayout="{(data.PHONE1 == '' &amp;&amp; data.PHONE2 == '') ? true:false}" 
     visible="{(data.PHONE1 == '' &amp;&amp; data.PHONE2 == '') ? true:false}" 
     text="Phone:  {data.PHONE3_FB}"/>
      -->
    <mx:Label includeInLayout="{data.DAYS != ''? true:false}" 
     visible="{data.DAYS != ''? true:false}" 
     text="---------------------------------------" /> 
        
    <mx:Label includeInLayout="{data.DAYS != ''? true:false}" 
     visible="{data.DAYS != ''? true:false}" 
     text="{data.DAYS}"/>
     
    <mx:Label includeInLayout="{data.HOURS != ''? true:false}" 
     visible="{data.HOURS != ''? true:false}" 
     text="{data.HOURS}"/>
     
     <mx:Label includeInLayout="{data.CERTIFICATION != ''? true:false}" 
     visible="{data.CERTIFICATION != ''? true:false}" text="---------------------------------------" />
     
    <mx:TextArea width="100%" height="60" fontSize="11" includeInLayout="{data.CERTIFICATION != ''? true:false}" 
     visible="{data.CERTIFICATION != ''? true:false}"
     text="{data.CERTIFICATION}"/>
     
    <mx:Label includeInLayout="{data.LOC_CODE != 'CENT'? false:true}" 
     visible = "{data.LOC_CODE != 'CENT'? false:true}" 
     text="** Location Approximate **"/>

    <mx:Button label="Zoom Closer" id="btn_Zoom" >
                                        <mx:click>
                                            <![CDATA[
                                                dispatchEvent(new Event("zoomHere", true));
                                            ]]>
                                        </mx:click>
                                    </mx:Button>

        </mx:VBox>   
    </mx:Component>


The
Tags (2)
0 Kudos
6 Replies
DasaPaddock
Esri Regular Contributor
Try:

mainMap.infoWindow.addEventListener("zoomHere", zoomHandler);
0 Kudos
TracySchloss
Frequent Contributor
At least it is now getting to my zoomHandler event.  However, the click graphic (which it doesn't look like I copied my code right last time) returns as null.  I'm getting confused on whether I should dispatch an Event or MouseEvent.

public function zoomHandler(event:MouseEvent): void {
  
  var clickGraphic:Graphic = event.currentTarget as Graphic;
   var newMapPoint:MapPoint = MapPoint(clickGraphic.geometry); 
  if (mainMap.scale > 100000)
  {
   mainMap.scale = 100000; 
  } else {
  var zoomScale:Number = mainMap.scale / 4;
  mainMap.scale = zoomScale;
  }
  mainMap.centerAt( newMapPoint);  
 }
0 Kudos
DasaPaddock
Esri Regular Contributor
There's not an easy way to get to the Graphic from the InfoWindow.

It sounds like you're using Graphic.infoWindowRenderer. If you also listen for click on the Graphic, you can save the clicked Graphic to a var and then refer back to it in the zoomHandler.

The zoomHandler should take an Event, since that's what is being dispatched. You should be getting an error otherwise when you debug the app or use the Flash Debug player.
0 Kudos
TracySchloss
Frequent Contributor
Yes, I have a listener on the graphic for MouseClick which was added through the results function for a query task.  The onMouseClick function does a mainMap.infoWindow.show.  I did as you suggested and added a variable, lastGraphic, to store the graphic and then added the listener for the InfoWindow during that onMouseClick function as well.

     private function onMouseClick(event:MouseEvent):void {
      //adds a info tip window when you click on a map feature     
   var g:Graphic = Graphic(event.currentTarget);
   lastGraphic = g;
   mainMap.infoWindow.data = g.attributes;
   mainMap.infoWindow.styleName = "myInfoWindow";
                                      mainMap.infoWindow.show( MapPoint(g.geometry) );
   
   mainMap.infoWindow.addEventListener("zoomHere",zoomHandler);
  }


Then when I got to the zoomHandler, I had the graphic stored and could then zoom to it.

 public function zoomHandler(event:Event): void {
  var newMapPoint:MapPoint = MapPoint(lastGraphic.geometry);
   if (mainMap.scale > 100000)
     {
      mainMap.scale = 100000; 
     } else {
      var zoomScale:Number = mainMap.scale / 4;
      mainMap.scale = zoomScale;
     }
     mainMap.centerAt( newMapPoint);   
 }


Works well!  Thanks Dasa!
0 Kudos
DavidBoiano
Occasional Contributor
I am trying to add a "Zoom to" button to an InfoWindow, also.  I am having a hard time following this thread in terms of how it applies to my code.  I have a feature layer of points that displays an info window when the user clicks on a point.  I am unsure of how to isolate the selected point and include it in a zoom event to have it zoomed in relative to the currently selected point at the center.

I am very new to ActionScript so any suggestions/tips in the right direction would be greatly appreciated!

My thought was to add a button to the info window with a click property calling a function "zoomToPoint()" but I am not sure how to get it going.

My code is:
(I have bolded areas of uncertainty surrounding this zoom event)

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
      xmlns:mx="library://ns.adobe.com/flex/mx"
      xmlns:esri="http://www.esri.com/2008/ags"
      xmlns:s="library://ns.adobe.com/flex/spark">
  <s:layout>
  <s:VerticalLayout/>
</s:layout>

<fx:Script>
  <![CDATA[
   import com.esri.ags.geometry.MapPoint;
  
   import mx.collections.ArrayCollection;
  
   import spark.events.IndexChangeEvent;
  

  
   [Bindable]
   public var myDP:ArrayCollection = new ArrayCollection(
    [ {timeframe:"Last 2 Weeks"},
     {timeframe:"Last Year"},
     {timeframe:"Last 2 Years"},
     {timeframe:"Year to Date (2013)"},
     {timeframe:"Last Year (2012)"} ]);
  
   [Bindable]
   public var updateDefExp:String = "Days_Ago > 49";
   public var lastG:Graphic = new Graphic;
 
  
  
   private function doQuery0():void
   {
    var defExp0:String = "Days_Ago = 49";
    updateDefExp = defExp0;
   }
   private function doQuery1():void
   {
    var defExp1:String = "Days_Ago = 63";
    updateDefExp = defExp1;
   }
   private function doQuery2():void
   {
    var defExp2:String = "Days_Ago = 74";
    updateDefExp = defExp2;
   }
   private function doQuery3():void
   {
    var defExp3:String = "Days_Ago > 95";
    updateDefExp = defExp3;
   }
   private function doQuery4():void
   {
    var defExp4:String = "Days_Ago < 60";
    updateDefExp = defExp4;
   }
  
   private function updateSelection(e:IndexChangeEvent):void
   {
    //currentSel.text = "You are viewing SSOs from: " + myDDL.selectedItem.timeframe;
   
    if(myDDL.selectedItem.timeframe == "Last 2 Weeks")
    {
     doQuery0();
    }
    else if (myDDL.selectedItem.timeframe == "Last Year")
    {
     doQuery1();
    }
    else if (myDDL.selectedItem.timeframe == "Last 2 Years")
    {
     doQuery2();
    }
    else if (myDDL.selectedItem.timeframe == "Year to Date (2013)")
    {
     doQuery3();
    }
    else if (myDDL.selectedItem.timeframe == "Last Year (2012)")
    {
     doQuery4();
    }
   }
   private function zoomToPoint(event:MouseEvent):void
   {
    var g:Graphic = Graphic(event.currentTarget);
    currentPoint = layer1.selectedFeatures as MapPoint;
   }

  ]]>
</fx:Script>
<s:controlBarLayout>
  <s:HorizontalLayout horizontalAlign="center"
       paddingBottom="10"
       paddingTop="15"/>
</s:controlBarLayout>
<s:controlBarContent>
  <s:Label fontSize="12"
     fontWeight="bold"
     text="Select a timeframe from the drop down list:  "/>
  <s:DropDownList id="myDDL" width="150" prompt="Select..."
      dataProvider="{myDP}" labelField="timeframe"
      change="updateSelection(event);"/>
</s:controlBarContent>
<fx:Declarations>
  <esri:SimpleLineSymbol id="smsOutline"
          width="1.5"
          alpha="0.75"
          color="white"/>
  <esri:SimpleMarkerSymbol id="querySymbol"
         color="green"
         outline="{smsOutline}"
         size="28"
         style="circle"/>

</fx:Declarations>



<esri:Map id="myMap">
  <esri:ArcGISDynamicMapServiceLayer url="http://ntsv58/ArcGIS/rest/services/Maps/sso_basemap/MapServer"/>
  <esri:FeatureLayer id="layer1" outFields="[ADDRESS,NEIGHBORHO,Spill_Start_Date,Spill_End_Date,Start_Time,End_Time,Spill_Volume__gal_]"
         definitionExpression="{updateDefExp}"
         url="http://ntsv58/ArcGIS/rest/services/Maps/sso_map_fulltable/MapServer/0">
   <esri:infoWindowRenderer>
    <fx:Component>
     <esri:LabelDataRenderer label="{data.ADDRESS}" fontWeight="bold">
      <s:BorderContainer backgroundColor="white"
             borderColor="black"
             color="0x353930"
             cornerRadius="5"
             minHeight="0"
             minWidth="0">
       <s:layout>
        <s:VerticalLayout paddingBottom="5"
              paddingLeft="5"
              paddingRight="5"
              paddingTop="5"/>
       </s:layout>
       <s:Label text="Spill started on {data.Spill_Start_Date} at {data.Start_Time}"/>
       <s:Label text="Spill ended on {data.Spill_End_Date} at {data.End_Time}"/>
       <s:Label text="The volume of the overflow spill was {data.Spill_Volume__gal_} gallons"/>
       <s:Button label="Zoom to SSO"/>
      </s:BorderContainer>
     </esri:LabelDataRenderer>
    </fx:Component>
   </esri:infoWindowRenderer>
   <esri:renderer>
    <esri:SimpleRenderer>
     <esri:SimpleMarkerSymbol color="0x6D0010"
            outline="{smsOutline}"
            size="22"
            style="diamond"/>
    </esri:SimpleRenderer>
   </esri:renderer>
  </esri:FeatureLayer>
</esri:Map>

</s:Application>
0 Kudos
DasaPaddock
Esri Regular Contributor
I'd try making your infoWindowRenderer into a separate MXML component that implements the IGraphicRenderer interface. This way you can get to the map and the geometry of the graphic.

e.g.,
var map:Map = graphic.graphicsLayer.map;

Also see the zoomToButton_clickHandler code inside PopUpRendererSkin.mxml. This file is inside the skins folder when you download the API zip file.

Another option is to use the PopUpRenderer as your infoWindowRenderer, like in this sample:
http://resources.arcgis.com/en/help/flex-api/samples/index.html#/Display_popups_programmatically/01n...
but don't set "showZoomToButton" to false.
0 Kudos