You need to sign in to do that
Don't have an account?
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>
All Answers
This is the issue:
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.
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>
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.