views:

1205

answers:

3

I've got a page that retrieves a bunch of locations and some data about their associated markers and puts them on a Google Maps map. Each one is supposed to pop up its own little message when clicked on. However, clicking on ANY of them makes the most recently added message pop up at the most recently added marker. What gives? Am I not scripting the click event properly? Here's the relevant code:

var xmlDoc;
    if (window.XMLHttpRequest)
    {
    xmlDoc=new window.XMLHttpRequest();
    xmlDoc.open("GET","locs.php",false);
    xmlDoc.send("");
    xmlDoc=xmlDoc.responseXML;
    }
    // IE 5 and IE 6
    else if (ActiveXObject("Microsoft.XMLDOM"))
    {
    xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async=false;
    xmlDoc.load("locs.php");
    }

    var pins = xmlDoc.getElementsByTagName("pin");
    //alert(pins);

    for (i=0;i<pins.length;i++)
    {
       //alert(pins[i].getElementsByTagName("lat")[0].childNodes[0].nodeValue);
       var point = new GLatLng( pins[i].getElementsByTagName("lat")[0].childNodes[0].nodeValue, 
                                pins[i].getElementsByTagName("lon")[0].childNodes[0].nodeValue);
       var colord;
       var curgender = pins[i].getElementsByTagName("gender")[0].childNodes[0].nodeValue;
       if(curgender == "Male")
       {colord = blueOpt;}else if(curgender=="Female"){colord = pinkOpt;}else{colord = purpleOpt;}

       var marker = new GMarker(point, colord);
       var mess =  pins[i].getElementsByTagName("message")[0].childNodes[0].nodeValue;

       GEvent.addListener(marker, "click", function() {
         marker.openInfoWindowHtml(mess);
       });

       map.addOverlay(marker);

    }
  }
A: 

I had this once, too. It is a scoping issue. I had to change my structure a little bit but maybe in your case changing the callback could already help:

GEvent.addListener(marker, "click", function() {
 marker.openInfoWindowHtml(pins[i].getElementsByTagName("message")[0].childNodes[0].nodeValue;);
});
Daff
+3  A: 

Daff is right about the scope. One alternative, however, is to use bindInfoWindowHtml() instead of a listener with openInfoWindowHtml(). Just replace the listener with this code:

marker.bindInfoWindowHtml(mess);


UPDATE: As a sidenote - because of closure, any variable created in a for loop will be remembered. A direct solution to the problem is to make a separate function to create the Listener.

Replace the listener with

createMarker(marker,mess);

and add the function:

function createMarker(marker, mess) {
    GEvent.addListener(marker, "click", function() {
        marker.openInfoWindowHtml(mess);
    });
}
Chris B
Thank you, thank you, thank you. This is exactly what I needed but couldn't find.
John
+1 Great answer ...
Cannonade
A: 

I have the same problem and I couldn't solve it with Daff's or Chris B's suggestions. The thing is that I am writing my code with the Google Maps API V3 not V2. Does anyone have any idea what would be wrong what I have. Below I am posting my script and any help is appreciated.

All markers appear well on the map but clicking on them doesn't bring me anything. There is also am external .xml file that the script is using in the root folder. I will attach the .xml at the end of this post as well.

--------------------------------------------------------------------------
--------------------------------------------------------------------------


<head>
<script type="text/javascript">

var xmlDoc;
    if (window.XMLHttpRequest)
    {
    xmlDoc=new window.XMLHttpRequest();
    xmlDoc.open("GET","markers.xml",false);
    xmlDoc.send("");
    xmlDoc=xmlDoc.responseXML;
    }
    // IE 5 and IE 6
    else if (ActiveXObject("Microsoft.XMLDOM"))
    {
    xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async=false;
    xmlDoc.load("markers.xml");
    }


  x=xmlDoc.getElementsByTagName("marker");

function initialize() {
var myLatlng = new google.maps.LatLng(21.1616, -86.8341);
var myOptions = {
  zoom: 14,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
  }
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);



for (var i = 0; i<x.length; i++) {
  var markerLatLng = new google.maps.LatLng((x[i].childNodes[3].childNodes[0].nodeValue), (x[i].childNodes[4].childNodes[0].nodeValue));
  var marker = new google.maps.Marker({
      position: markerLatLng,
      title: (x[i].childNodes[1].childNodes[0].nodeValue),
      map: map
  });
  attachMessage(marker, i);
}


}

// click markers

function attachMessage(marker, number) {
  var infowindow = new google.maps.InfoWindow(
      { content: number + "whatever content",
        zIndex: number
      });
  google.maps.event.addListener(marker, 'click', function() {
    infowindow.open(map,marker);
  });
}

</script>
</head>

<body onLoad="initialize()">
<div id="map_canvas" style="width:1500; height:1000"></div>
</body>
</html>

------------------------------------------------------------------------

markers.xml:
-----------------------


<markers>

<marker>
<id>1</id>
<name>Mercado 28</name>
<price>20000000</price>
<lat>21.161659</lat>
<lng>-86.834160</lng>
<type>shopping</type>
</marker>

<marker>
<id>2</id>
<name>Costco</name>
<price>58000000</price>
<lat>21.148310</lat>
<lng>-86.835487</lng>
<type>shopping</type>
</marker>

</markers>

------------------------------
haluk