JSAPI 2.0 - InfoWindow shows up in wrong place after zoom

1027
4
08-25-2010 12:54 PM
TimRourke
New Contributor
I have a script to zoom and pan the map to frame two graphics - a vehicle and a destination - and then popup the map's InfoWindow for the destination graphic. The extent change works most of the time, but the InfoWindow always shows up in the wrong place. Here's the relevant code:

// destData is a data row returned from a service, used to create destGraphic.
// destGraphic is the destination graphic created and added to the graphic layer.
// vehGraphic is a vehicle graphic already present in the graphic layer.
var graphics = [];
graphics.push(destGraphic);
graphics.push(vehGraphic);
var extent = esri.graphicsExtent(graphics);
map.setExtent(extent);

map.infoWindow.hide();
map.infoWindow.setTitle(destGraphic.infoTemplate.title);
map.infoWindow.setContent(destGraphic.infoTemplate.content);
map.infoWindow.resize(350, 300);

var destPoint = new esri.geometry.Point(destData.Longitude, 
 destData.Latitude, new esri.SpatialReference({ wkid: 4326 }));
var screenPoint = map.toScreen(destPoint);
map.infoWindow.show(screenPoint, map.getInfoWindowAnchor(screenPoint));


Firebug shows two errors: "exception in animation handler for: onEnd" and "TypeError: pt is null"  which are Dojo errors that I see during the zoom and pan. They may be related to turning off the "Loading" progress animation, but I'm not sure.

I assume the InfoWindow is trying to find a point that isn't valid because the animation is changing the map coordinates or something. I've tried adding a pause of up to 10 seconds before popping it up, but the InfoWindow always pops up before or during the extent change, even though the execution order is clear in the code. I've also played with the settings esri.config.defaults.map.panDuration, esri.config.defaults.map.panRate, esri.config.defaults.map.zoomDuration and esri.config.defaults.map.zoomRate with no joy.

I'm using ArcGIS 9.3.1 and JavaScript API 2.0 (not Flex, Google or Virtual Earth). Results are the same in Internet Explorer 7 and 8 and in FireFox.

Does anyone know a tweak or other work-around to fix this?
0 Kudos
4 Replies
JohnGrayson
Esri Regular Contributor
You should try to only show the InfoWindow AFTER the map has finished changing extent.  Listening to the 'onExtentChange' event would be one way to handle this situation.


function zoomTo(destGraphic, vehGraphic, destData){

  // CONNECT ONEXTENTCHANGE EVENT
  var onExtentChangeHandle = dojo.connect(map, 'onExtentChange', function() {
    // THIS CODE WILL RUN *AFTER* THE EXTENT CHANGES...
    
    // DISCONNECT ONEXTENTCHANGE EVENT
    dojo.disconnect(onExtentChangeHandle);
    
    // SETUP INFOWINDOW
    map.infoWindow.setTitle(destGraphic.getTitle());
    map.infoWindow.setContent(destGraphic.getContent());
    map.infoWindow.resize(350, 300);

    var destPoint = new esri.geometry.Point(destData.Longitude, destData.Latitude, new esri.SpatialReference({ wkid: 4326 }));
    var screenPoint = map.toScreen(destPoint);
    map.infoWindow.show(screenPoint, map.getInfoWindowAnchor(screenPoint));  
  });
  
  // HIDE INFOWINDOW
  map.infoWindow.hide();  

  // GET ZOOM EXTENT
  var graphics = [];
  graphics.push(destGraphic);
  graphics.push(vehGraphic);
  var extent = esri.graphicsExtent(graphics);
  
  // SET EXTENT: THIS HAPPENS FIRST AND WILL TRIGGER THE ONEXTENTCHANGE EVENT ABOVE
  map.setExtent(extent);  
}
0 Kudos
TimRourke
New Contributor
Thanks for the tip, John. I think you're right, although we have multiple tasks in our map application so I'll have to use an inline callback function for every task when it changes the map extent. It's interesting that it only causes this problem when it zooms to two features.

Thanks,

Tim
0 Kudos
JohnGrayson
Esri Regular Contributor
Tim,
  In that case, you could create a slightly more generic version of this function that takes a callback as a parameter and then each call to this function can do something different when the map has finished setting the new extent.  Something kinda like this:


function setMapExtent(newExtent, callback) {
  var onExtentChangeHandle = dojo.connect(map, 'onExtentChange', function() {
    dojo.disconnect(onExtentChangeHandle);    
    if(callback){
      callback();
    }
  });     
  map.setExtent(newExtent);
}

var graphics = [];
graphics.push(destGraphic);
graphics.push(vehGraphic);
var extent = esri.graphicsExtent(graphics);

setMapExtent(extent, function() {

  map.infoWindow.hide();
  map.infoWindow.setTitle(destGraphic.getTitle());
  map.infoWindow.setContent(destGraphic.getContent());
  map.infoWindow.resize(350, 300);

  var destPoint = new esri.geometry.Point(destData.Longitude, 
 destData.Latitude, new esri.SpatialReference({ wkid: 4326 }));
  var screenPoint = map.toScreen(destPoint);
  map.infoWindow.show(screenPoint, map.getInfoWindowAnchor(screenPoint));

});

0 Kudos
TimRourke
New Contributor
Yeah, that's what I thought. I tried it but the onExtentChange handler never runs - whether I put it in line or as a separate callback function.

I also tried to hook handlers to layer onUpdate and onUpdateEnd events. They don't fire the handlers either.

Event handlers don't seem very dependable in this API.

Thanks anyway,

Tim
0 Kudos