NOTE: I'm using v3 of the Google Maps API
I'm trying to add an info window to each marker I put on the map. Currently I'm doing this with the following code:
for (var i in tracks[racer_id].data.points) {
values = tracks[racer_id].data.points[i];
point = new google.maps.LatLng(values.lat, values.lng);
if (values.qst) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
tracks[racer_id].markers[i] = marker;
var info = new google.maps.InfoWindow({
content: '<b>Speed:</b> ' + values.inst + ' knots'
});
tracks[racer_id].info[i] = info;
google.maps.event.addListener(marker, 'click', function() {
info.open(map, marker);
});
}
track_coordinates.push(point);
bd.extend(point);
}
The problem is when I click on a marker it just displays the info window for the last marker added. Also just to be clear the info window appears next to the last marker not the marker clicked on. I'd imagine my problem is in the addListener portion but am not postitive. Any ideas?
This question is related to
javascript
google-maps
google-maps-api-3
The add_marker still has a closure issue, cause it uses the marker variable outside the google.maps.event.addListener scope.
A better implementation would be:
function add_marker(racer_id, point, note) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
marker.note = note;
google.maps.event.addListener(marker, 'click', function() {
info_window.content = this.note;
info_window.open(this.getMap(), this);
});
return marker;
}
I also used the map from the marker, this way you don't need to pass the google map object, you probably want to use the map where the marker belongs to anyway.
You can use this
in event:
google.maps.event.addListener(marker, 'click', function() {
// this = marker
var marker_map = this.getMap();
this.info.open(marker_map);
// this.info.open(marker_map, this);
// Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
});
Try this:
for (var i in tracks[racer_id].data.points) {
values = tracks[racer_id].data.points[i];
point = new google.maps.LatLng(values.lat, values.lng);
if (values.qst) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
tracks[racer_id].markers[i] = marker;
var info = new google.maps.InfoWindow({
content: '<b>Speed:</b> ' + values.inst + ' knots'
});
tracks[racer_id].info[i] = info;
google.maps.event.addListener(tracks[racer_id].markers[i], 'click', function() {
tracks[racer_id].info[i].open(map, tracks[racer_id].markers[i]);
});
}
track_coordinates.push(point);
bd.extend(point);
}
for Earth plugin APIs, create the balloon outside your loop and pass your counter to the function to get unique contents for each placemark!
function createBalloon(placemark, i, event) {
var p = placemark;
var j = i;
google.earth.addEventListener(p, 'click', function (event) {
// prevent the default balloon from popping up
event.preventDefault();
var balloon = ge.createHtmlStringBalloon('');
balloon.setFeature(event.getTarget());
balloon.setContentString('iframePath#' + j);
ge.setBalloon(balloon);
});
}
The only way I could finally get this to work was by creating an array in JavaScript. The array elements reference the various info-windows (one info-window is created for each marker on the map). Each array element contains the unique text for its appropriate map marker. I defined the JavaScript event for each info-window based on the array element. And when the event fires, I use the "this" keyword to reference the array element to reference the appropriate value to display.
var map = new google.maps.Map(document.getElementById('map-div'), mapOptions);
zipcircle = [];
for (var zip in zipmap) {
var circleoptions = {
strokeOpacity: 0.8,
strokeWeight: 1,
fillOpacity: 0.35,
map: map,
center: zipmap[zip].center,
radius: 100
};
zipcircle[zipmap[zip].zipkey] = new google.maps.Circle(circleoptions);
zipcircle[zipmap[zip].zipkey].infowindowtext = zipmap[zip].popuptext;
zipcircle[zipmap[zip].zipkey].infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(zipcircle[zipmap[zip].zipkey], 'click', function() {
this.infowindow.setContent(this.infowindowtext);
this.infowindow.open(map, this);
});
}
In My case (Using Javascript insidde Razor) This worked perfectly inside an Foreach loop
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, this);
});
I had a similar problem. If all you want is for some info to be displayed when you hover over a marker, instead of clicking it, then I found that a good alternative to using an info Window was to set a title on the marker. That way whenever you hover the mouse over the marker the title displays like an ALT tag. 'marker.setTitle('Marker '+id);' It removes the need to create a listener for the marker too
Hey everyone. I don't know if this is the optimal solution but I figured I'd post it here to hopefully help people out in the future. Please comment if you see anything that should be changed.
My for loops is now:
for (var i in tracks[racer_id].data.points) {
values = tracks[racer_id].data.points[i];
point = new google.maps.LatLng(values.lat, values.lng);
if (values.qst) {
tracks[racer_id].markers[i] = add_marker(racer_id, point, '<b>Speed:</b> ' + values.inst + ' knots<br /><b>Invalid:</b> <input type="button" value="Yes" /> <input type="button" value="No" />');
}
track_coordinates.push(point);
bd.extend(point);
}
And add_marker
is defined as:
var info_window = new google.maps.InfoWindow({content: ''});
function add_marker(racer_id, point, note) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
marker.note = note;
google.maps.event.addListener(marker, 'click', function() {
info_window.content = marker.note;
info_window.open(map, marker);
});
return marker;
}
You can use info_window.close() to turn off the info_window at any time. Hope this helps someone.
Source: Stackoverflow.com