+ Start a Discussion
robertcw777robertcw777 

Same infowindow opens for all markers in google map

My VF page opens a google map and adds multiple locations based on an list returned from the controller. The markers display fine with the correct names displayed on the mouseover. However, whenever I click to view the infoWindow, it always opens the infowindow for the last location added. Can anyone see what I'm doing wrong?

 

Thanks.

 

 

<apex:page Controller="LocationMapController2">

<head>

<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function() {

var myOptions = {
   zoom: 2,
   mapTypeId: google.maps.MapTypeId.ROADMAP,
   center: new google.maps.LatLng(40,-95),
   mapTypeControl: false
}

var map;
var marker;

//create map
map = new google.maps.Map(document.getElementById("map"), myOptions);

var geocoder = new google.maps.Geocoder();


<apex:repeat var="l" value="{!LocationInfo}">

   var address = "{!l.Street__c}, " + "{!l.City__r.Name}, " + "{!l.City__r.Name}, " + "{!l.Country__r.Name}";

   var infowindow = new google.maps.InfoWindow({
content: "<b>{!l.Name}</b><br>{!l.Street__c}<br>{!l.City__r.Name}, {!l.City__r.Name}<br>{!l.Country__c}"
   });

   geocoder.geocode( { address: address}, function(results, status) {
   if (status == google.maps.GeocoderStatus.OK && results.length) {
      if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
         //create marker
         marker = new google.maps.Marker({
         position: results[0].geometry.location,
map: map,
         title: "{!l.Name}"
         });

         //add listeners
         google.maps.event.addListener(marker, 'click', function() {
         infowindow.open(map,marker);
         });
         google.maps.event.addListener(infowindow, 'closeclick', function() {
map.setCenter(marker.getPosition());
         });
   }
} else {
   $('#map').css({'height' : '15px'});
   $('#map').html("Oops! {!l.Name}'s address could not be found, please make sure the address is correct.");
   resizeIframe();
}
});

</apex:repeat>

function resizeIframe() {
   var me = window.name;
      if (me) {
        var iframes = parent.document.getElementsByName(me);
         if (iframes && iframes.length == 1) {
             height = document.body.offsetHeight;
            iframes[0].style.height = height + "px";
        }
 }
}

});
</script>

<style>
#map {
font-family: Arial;
font-size:12px;
line-height:normal !important;
height:500px;
background:transparent;
}
</style>

</head>

<body>
<div id="map"></div>
</body>
</apex:page>

Best Answer chosen by Admin (Salesforce Developers) 
robertcw777robertcw777
That was it. Thanks!

All Answers

SarfarajSarfaraj

This is the issue:

google.maps.event.addListener(marker, 'click', function() {
         infowindow.open(map,marker);
         });

 infowindow is local variable that is getting overwritten on each iteration. So when the anonymous function executes it gets only the last value. Use one hash array to keep all infowindow objects (or better create one infowindow object and set its anchor and content at runtime. Performance in this approach will be better). Use some information from the current marker being clicked to open the correct infowindow. Below is one sample code. I haven't tested it. But this is the approach I use. I am using l.name as key to the hash array. Please modify it as per your need.

var infoWindowArray = new Array();
<apex:repeat var="l" value="{!LocationInfo}">

   var address = "{!l.Street__c}, " + "{!l.City__r.Name}, " + "{!l.City__r.Name}, " + "{!l.Country__r.Name}";

   infowindow = new google.maps.InfoWindow({
content: "<b>{!l.Name}</b><br>{!l.Street__c}<br>{!l.City__r.Name}, {!l.City__r.Name}<br>{!l.Country__c}"
   });
   infoWindowArray["{!l.Name}"] = infowindow;
   geocoder.geocode( { address: address}, function(results, status) {
   if (status == google.maps.GeocoderStatus.OK && results.length) {
      if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
         //create marker
         marker = new google.maps.Marker({
         position: results[0].geometry.location,
map: map,
         title: "{!l.Name}"
         });

         //add listeners
         google.maps.event.addListener(marker, 'click', function() {
         infoWindowArray[this.getTitle()].open(map,this);
         });
         google.maps.event.addListener(infowindow, 'closeclick', function() {
map.setCenter(marker.getPosition());
         });
   }
} else {
   $('#map').css({'height' : '15px'});
   $('#map').html("Oops! {!l.Name}'s address could not be found, please make sure the address is correct.");
   resizeIframe();
}
});
</apex:repeat>

 

robertcw777robertcw777

Thanks. I made your recommended changes. Now infoWindow only appears for the last location. Nothing happens when I click the other locations. I used to get an infoWindow to open on the others when clicked, but it was the wrong infoWindow (always that of last location).

 

Any ideas? Did I implement incorrectly?

 

<apex:repeat var="l" value="{!LocationInfo}">
   var infoWindowArray = new Array();
   var address = "{!l.Street__c}, " + "{!l.City__r.Name}, " + "{!l.City__r.Name}, " + "{!l.Country__r.Name}";

   var infowindow = new google.maps.InfoWindow({content: "<b>{!l.Name}</b><br>{!l.Street__c}<br>{!l.City__r.Name}, {!l.City__r.Name}<br>{!l.Country__c}"
});
   infoWindowArray["{!l.Name}"] = infowindow;
   geocoder.geocode( { address: address}, function(results, status) {
   if (status == google.maps.GeocoderStatus.OK && results.length) {
      if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
         //create marker
         marker = new google.maps.Marker({
          position: results[0].geometry.location,
         map: map,
         title: "{!l.Name}"
      });

      //add listeners
      google.maps.event.addListener(marker, 'click', function() {
      infoWindowArray[this.getTitle()].open(map,this);
      });
      google.maps.event.addListener(infowindow, 'closeclick', function() {
      map.setCenter(marker.getPosition());
      });
   }
} else {
   $('#map').css({'height' : '15px'});
   $('#map').html("Oops! {!l.Name}'s address could not be found, please make sure the address is correct.");
   resizeIframe();
}
});

</apex:repeat>

 

SarfarajSarfaraj

var infoWindowArray = new Array();
<apex:repeat var="l" value="{!LocationInfo}">
var address = "{!l.Street__c}, " + "{!l.City__r.Name}, " + "{!l.City__r.Name}, " + "{!l.Country__r.Name}";

var infowindow = new google.maps.InfoWindow({content: "<b>{!l.Name}</b><br>{!l.Street__c}<br>{!l.City__r.Name}, {!l.City__r.Name}<br>{!l.Country__c}"
});
infoWindowArray["{!l.Name}"] = infowindow;
geocoder.geocode( { address: address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results.length) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
//create marker
marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title: "{!l.Name}"
});

//add listeners
google.maps.event.addListener(marker, 'click', function() {
infoWindowArray[this.getTitle()].open(map,this);
});
google.maps.event.addListener(infowindow, 'closeclick', function() {
map.setCenter(marker.getPosition());
});
}
} else {
$('#map').css({'height' : '15px'});
$('#map').html("Oops! {!l.Name}'s address could not be found, please make sure the address is correct.");
resizeIframe();
}
});
</apex:repeat>

 

Please keep the declaration of the array outside of the loop. The above code will fail if you have duplicate l.name. In that case please use the following code.

	var infoWindowArray = new Array();
	var iCtr = 0;
<apex:repeat var="l" value="{!LocationInfo}">
   var address = "{!l.Street__c}, " + "{!l.City__r.Name}, " + "{!l.City__r.Name}, " + "{!l.Country__r.Name}";

   var infowindow = new google.maps.InfoWindow({content: "<b>{!l.Name}</b><br>{!l.Street__c}<br>{!l.City__r.Name}, {!l.City__r.Name}<br>{!l.Country__c}"
});
   infoWindowArray[iCtr] = infowindow;
   geocoder.geocode( { address: address}, function(results, status) {
   if (status == google.maps.GeocoderStatus.OK && results.length) {
      if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
         //create marker
         marker = new google.maps.Marker({
          position: results[0].geometry.location,
         map: map,
         title: iCtr + " {!l.Name}"
      });

      //add listeners
      google.maps.event.addListener(marker, 'click', function() {
      infoWindowArray[this.getTitle().split(" ")[0]].open(map,this);
      });
      google.maps.event.addListener(infowindow, 'closeclick', function() {
      map.setCenter(marker.getPosition());
      });
   }
} else {
   $('#map').css({'height' : '15px'});
   $('#map').html("Oops! {!l.Name}'s address could not be found, please make sure the address is correct.");
   resizeIframe();
}
});
iCtr++;
</apex:repeat>

 

robertcw777robertcw777
That was it. Thanks!
This was selected as the best answer