Like many of you out there that use Google Maps, when v3.0 of it came out you jumped at the chance to use it! But I couldn’t get the multiple markers, multiple info windows to work, no matter what I found on Google’s site.
Searching got me to this blog:
http://www.svennerberg.com/2009/09/google-maps-api-3-infowindows
And it states this guy is writing a book on this very subject. So this should have the answer. Well bollocks it did! Stop writing your book now matey!
The Problem
When in a loop adding new markers many of you have probably done something similar:
for (var i = 0; i < markers.length; i++) {
var marker = markers[i];
var infowindow = new google.maps.InfoWindow({
content: "holding..."
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, maker);
});
}
This always showed the last marker that was bound to map so the info window always appeared on the last marker. Bit of a problem really.
After reading http://www.svennerberg.com/2010/04/the-state-of-this-blog/ it showed me my mistake and the actual solution…
The Solution
var infowindow = null;
.
.
.
/* now inside your initialise function */
infowindow = new google.maps.InfoWindow({
content: "holding..."
});
for (var i = 0; i < markers.length; i++) {
var marker = markers[i];
google.maps.event.addListener(marker, 'click', function () {
// where I have added .html to the marker object.
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
Notice the change from marker to this. As you have all seen the event fires for each marker, but as you were calling infowindow.open(map, marker) javascript engine’s memory location thingymabob (not good with names) held the last reference to marker. But you had passed in the marker to the event, so by calling this in place of marker, you get what you are looking for.
Hope this helps someone out.
[Edit]
And to auto center your map once all your points are in:
function AutoCenter() {
//Â Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds();
//Â Go through each...
$.each(markers, function (index, marker) {
bounds.extend(marker.position);
});
//Â Fit these bounds to the map
map.fitBounds(bounds);
}
assuming you have saved each marker in a markers array, and map is a global variable on your page.
[Edit 2]
To help someone below in the comments, I created this map to help solve someone’s issue. Hopefully it did. I really should have had a full working example at the start but I can be quite lazy sometimes :S It’s done now, so you can stop complaining
[Edit 3]
Updated the code so that the infowindow was on the outside of the loop. It doesn’t need to be inside the loop.


Great example! Very useful and well explained! I was wondering how to attach to the click listener a way to center the map on every marker click. I got throught a lot of forums and seems map.panTo() is difficult to set up properly. Thanks!
I have spent 2 days trying to make this work. If I run my code like “The Problem”, I always open Window 3 as described.
But when I change to “The Solution” I do not get any windows at all. What does where I have added .html to the marker object” mean?
I have searched Google for hours. There is absolutely no complete code sample anywhere on the web to create multiple markers with multiple windows. Please, please, please post your code where you created the markets.
Hi Lynn,
The “.html” is actually a dynamic property I have added to the marker object. With Javascript you can add any property at any point to an object even if it is not defined before.
example:
var marker = new google.maps.Marker({ position: myLatlng, map: map, title: teacher.Firstname + " " + teacher.Surname, html: BuildTeacher(teacher, location) });So here I am building the marker object. The last line in the constructor of it has “html” as a property, which isn’t defined in the marker object from Google. I added it as, to me, it makes more sense to have the html that will be displayed in the info window, in a property conviently named html. But I could have called it bananas as javascript allows any property to be dynamically created at any point as it is a scripting language.
Once you have created your marker object with this html property, when calling :
this should work (fingers crossed
) for you. Let me know if it doesn’t.
Genius!
Really Genius!
I was heading up to it for few hours while using ExtJs with this.
You solved my problem.
Thank You
Thanks for this, this should be part of the V3 code samples
Thank you!!!!!
Thanks for this post! It solved the exact problem I was having!!!!
Thank you, thank you, thank you. Fantastic info and solved a big headache. I agree with zMastaa. This needs to be on the main Google code page for the API examples.
Great, thanx for this
was just what I needed!
[...] seemed like a common enough scenario yet the answer could not be found. Eventually I found this post which helped point me in the right [...]
[...] loop and then passing the marker to the infowindow via a closure. After some searching, I found a solution which worked. But it still didn’t explain why this wasn’t working. Surely the Google [...]
So I’m almost there. I had this exact problem. Changing “marker” to “this” for infowindow.open worked like a charm for making the info window pop up in the right place, but I’m still not able to get the content for that marker to show up.
I’ve got my data in an array, and I want the content of the info window to show the text held in position 4 for the location for which that marker was created. Adding infowindow.setContent(this.html) just disables all infowindows.
Here’s a sample of my code:
var sites = [
['Mount Evans', 39.58108, -105.63535, 4, 'This is Mount Evans.'],
['Irving Homestead', 40.315939, -105.440630, 2, 'This is the Irving Homestead.'],
['Badlands National Park', 43.785890, -101.90175, 1, 'This is Badlands National Park'],
['Flatirons in the Spring', 39.99948, -105.28370, 3, 'These are the Flatirons in the spring.']
];
function setMarkers(map, markers) {
var redMarker = new google.maps.MarkerImage(‘redmarker.png’,
new google.maps.Size(22,22),
new google.maps.Point(0,0),
new google.maps.Point(12,12))
for (var i = 0; i < markers.length; i++) {
var sites = markers[i];
var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
icon: redMarker,
title: sites[0],
zIndex: sites[3]
});
var infowindow = new google.maps.InfoWindow({
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(this.html);
infowindow.open(map,this);
});
}
}
Hey Billy,
What you have forgotten to do is add the html to the marker:
for (var i = 0; i < markers.length; i++) {
var sites = markers[i];
var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
icon: redMarker,
title: sites[0],
zIndex: sites[3],
html: sites[4]
});
The “html” property is not part of the standard Marker object. I added it myself, which anyone can do with javascript, to make it easier to understand.
With the above change to your code, then infowindow.setContent(this.html) should now work.
Let me know if this helps,
Colin
AH! That makes perfect sense. NOW I get it.
However it’s still not working. I must have something in the wrong place in my code. If I assign content in the infowindow rather than setContent in the event listener, it works, but of course that’s not the text I need. Below is the full script using content: but not setContent:
function initialize() {
var centerMap = new google.maps.LatLng(39.828175, -98.5795);
var myOptions = {
zoom: 4,
center: centerMap,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById(“map_canvas”), myOptions);
setMarkers(map, sites);
}
var sites = [
['Mount Evans', 39.58108, -105.63535, 4, 'This is Mount Evans.'],
['Irving Homestead', 40.315939, -105.440630, 2, 'This is the Irving Homestead.'],
['Badlands National Park', 43.785890, -101.90175, 1, 'This is Badlands National Park'],
['Flatirons in the Spring', 39.99948, -105.28370, 3, 'These are the Flatirons in the spring.']
];
function setMarkers(map, markers) {
var redMarker = new google.maps.MarkerImage(‘redmarker.png’,
new google.maps.Size(22,22),
new google.maps.Point(0,0),
new google.maps.Point(12,12))
for (var i = 0; i < markers.length; i++) {
var sites = markers[i];
var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
icon: redMarker,
title: sites[0],
zIndex: sites[3],
html: sites[4]
});
var contentString = '’+
”+
”+
‘Uluru’+
”+
‘Uluru, also referred to as Ayers Rock, is a large ‘ +
‘sandstone rock formation in the southern part of the ‘+
‘Northern Territory, central Australia. It lies 335 km (208 mi) ‘+
‘south west of the nearest large town, Alice Springs; 450 km ‘+
‘(280 mi) by road. Kata Tjuta and Uluru are the two major ‘+
‘features of the Uluru – Kata Tjuta National Park. Uluru is ‘+
‘sacred to the Pitjantjatjara and Yankunytjatjara, the ‘+
‘Aboriginal people of the area. It has many springs, waterholes, ‘+
‘rock caves and ancient paintings. Uluru is listed as a World ‘+
‘Heritage Site.’+
‘Attribution: Uluru, ‘+
‘http://en.wikipedia.org/w/index.php?title=Uluru (last visited June 22, 2009).’+
”+
”;
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(marker, ‘click’, function() {
//infowindow.setContent(this.html);
infowindow.open(map,this);
});
}
}
Two things…you know the line to set the content is commented out? If you do, could you add this to that same method “alert(this.html);” and see what the alert window has in it.
Let me know how you get on.
Colin
Yes, I know it’s commented out in that bit I copied for you.
When I put an alert outside of the addListener it works. Inside, it doesn’t.
Ok not sure what you are doing wrong your side. I copied your code above, not exactly as I didn’t have the image, and I reduced the amount of text on the contentString variable.
Other than that it was the same, and worked perfectly fine. Could I ask you to double check things, flush browser cache – if the js is in an extra file things can go a bit off – and remove the comments.
You are doing it right.
Man I really don’t know what the heck is wrong if it works for you. I emptied the cache, tried Firebug and opened in a brand new browser. It will not work.
I found an interesting blog post by someone who seems to have figured out the problem, however his JS skills are beyond mine and his explanations aren’t detailed enough to help me apply this to my own code. Check this out:
http://www.aaronkjackson.com/2010/06/how-to-show-an-infowindow-for-multiple-markers-using-google-maps-v3/
Here, I have thrown a full example up on a url using your code above to show it is working properly. Not sure what you are doing wrong though as everything looks great.
http://ratemyyogateacher.co.uk/map.html
Let me know how you get on with that,
Colin
Hi, Colin, and many thanks for your post. I’ve tried a lot of ways, but yours seems the easiest and most intelligible. It helped me a lot…
Now, I am working on an implementation at http://cud.dvartora.ro and can’t seem to make it work as it should. The script is at http://cud.dvartora.ro/gmap.js . Basically, I am loading the markers from a mySQL database dynamically via XML (depending on the area of the map being shown). If the map bounds change, the script is supposed to clear the markers and load the new markers for that particular area from the database. So, the sites array needs to be dynamically generated each time the bounds of the viewport change.
For some reason, the clearing of previous markers doesn’t work properly. I get multiple markers at the same (or almost the same) location, as shown by the fact that the shadow seems to darken, and gets bigger. Just enter “Bucharest, Romania” in the search field, click “Cautare” (Search), zoom out a few times and you’ll see what I mean.
Also, in your example, the infoWindow “moved” when you clicked on another marker. In my implementation, a new infoWindow is open and the ones that are already open for other markers stay open, which is not what I want.
I am sure I am missing something. Any and all help will be greatly appreciated, as I have done all I know and I’ve been pulling my hair with this for 3 days in a row already…
Many thanks.
Give me until the weekend to look into if that’s ok. Bit tied down with work currently – well they pay my wages! But one thing I’d say just from the quick scan of your js…get yourself jQuery in there. Will help no end even with just reduceing document.getElementById(x) to $(“#x”). Speak soon.
Just quickly noticed you are doing this:
var infoWindow = new google.maps.InfoWindow({
content: infoWindowContent[number]
});
/* other code */
infowindows.clear();
infowindows.push(infoWindow);
Then you are essentially adding a new info window each time. You will notice my code uses only 1 info window, and applies the marker to it, when the marker is clicked:
for (var i = 0; i < markers.length; i++) {
var marker = markers[i];
// I really should move this outside the loop as it would be cleaner, but i got lazy!
var infowindow = new google.maps.InfoWindow({
content: “holding…”
});
google.maps.event.addListener(marker, ‘click’, function () {
// where I have added .html to the marker object.
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
The Google api then closes the current info window, applies the html, and reopens it at the new marker point.
So that’s possibly why the info windows don’t close, you are creating a new one each time, and a close event isn’t sent to the other infowindows.
Ok, good point. I was hoping that by closing all the infowindows and by emptying the infowindows array before I open a new one on marker click, that would be solved. In any case, I have the close() method in a for
for (var i=0; i < markers.length; i++) {
infowindows[i].close();
} // end for loop
infowindows.clear();
so it should work, no? Only then I do:
infowindows.push(infoWindow);
Also, in the other implementation, based on your solution (http://cud.dvartora.ro/youarenotme), where only one infowindow should be opened and "moved" from marker to marker, there are ALSO multiple infowindows open at one time. Also, there, the script generates multiple markers too, at the same location.
I'm really baffled with both implementations, each in its own way…
I think you are baffling yourself.
Here are the steps:
1. Create your map
2. Get your data for your markers
3. For each bit of data, create a marker, add it to your map
4. For each marker add the click event
5. Create a global info window variable
6. When the click happens, set the content in the infowindow, and then call the open method with the map and the marker.
That’s it. Stray from that, and you will get into bother.
What you seem to be doing is creating a bunch of markers, and then an infowindow for EACH marker and storing the infowindow in an array. You then open the associated infowindow when you click a marker. Thus the previous infowindow stays open as it doesn’t know (or really care) another info window has opened.
If you use 1 info window only, it will react properly when you call the open method again with a different marker.
So follow the steps above, and see. Any bother you can hire me to rewrite your code (am cheap, a pint and bit of dinner generally enough).
Thanks. Did you have a chance to take a look at http://cud.dvartora.ro/youarenotme yet? That is, as far as I was trying to make it, based entirely on your solution/implementation. Can you give me a hint why THAT isn’t working?
In any case, I will try to start again from scratch, following your 6 steps. Hopefully, I will be successful. If not, I’ll bother you again.
Many thanks again,
Sorin
I think it is working. I searched for “număr” and the mapped zoomed into a blank spot. But I zoomed out and there were couple of hundred points across Africa.
I click one or two and the windows open and closed as expected…on some of them. But others not.
Are you somehow adding the points more than once?
Well I have your code, and data, I might try something tonight as you now have my attention.
Finally got it to work properly. Hurray!
I rewrote the whole thing from scratch using your ideas (for which, your name will go in the comments in the JS file
).
Only thing I added was an clearOverlay() function to delete all the markers from the map on every ‘idle’ event, right before new markers are added to the map. I’m not 100% sure it’s really necessary, though. In any case, it seems the ‘idle’ event, as well as the ‘bounds_changed’ event, are firing way too quickly (because of tile loading) and sometimes markers are “doubled” on the map. Can’t do much about that, it seems…
I have the brand new implementation at http://cud.dvartora.ro/inprogress, and I’ll keep it there for a few hours (then I’ll put the working script in the root folder and continue working, cause I have some other stuff to do for this website). If you want to copy and scripts, you can do that. Or if you want me to email them to you, just let me know.
Many many thanks again. You’ve saved my sanity today…
Take care.
Glad you are happy
and I have been there with the sanity thing…hence why I wrote this post!
No thanks on the scripts side of things, and don’t worry about putting my name on things – all this is out for the world to take and play with as they please.
I was having this issue as well. This post solved it. Thanks a lot!
I bow to you, sir. This is so poorly documented in the official API info. I knew there had to be a solution somewhere, so I kept working on the rest of my app, while trying to figure out why this didn’t work at all. I’m so glad it’s solved—my live demo deadline is quickly approaching and my live demo was more on the dead side until I found your site!
Stand up young padawan. More practice and soon you shall be a master…sorry erm I mean, cheers for that
Ok man, thankyou very much: you helped me solving a two annoying days unsolvable problem! My code version was similare to yours but i wanted to only have one infowindow and populate and attach it to clicked marker only at click event. Really, can’t understand why google API reference, doesn’t talk about this and emphasize the problem.
Thank you again!
Hi Colin, just wondering, have you any idea how I change the message in the info window for each individual marker. I’m using the API sample Ularu info window …
I’ll be honest and say I’m a real novice at this stuff so your posting here has helped me LOTS so thanks a million,
Tanya.
Hi Tanya,
The code above gives the answer to that, but here it is again anyways. When you are building your markers, you add the html you require at this point:
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: teacher.Firstname + ” ” + teacher.Surname,
html: BuildTeacher(teacher, location)
});
The property “html” will contain the html you want, and you add it however you want – above I am calling a method. Please remember that the “html” property was added dynamically and doesn’t exist in the marker object, something which is nice above javascript.
Then for each marker you built you call this bit of code:
google.maps.event.addListener(marker, ‘click’, function () {
// where I have added .html to the marker object.
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
and the property we added “html”, will then be set as the content for the info window.
Does any of that make sense?
Cheers Colin. After a couple of hours reading Google code and not getting anywhere I found you! Works a treat matey, superb.
Hi Colin, thanks again for the help with this. Managed to get my map rolling using your Yoga sample so you’ve saved me much heartache!
Quick [unrelated] question – has the way you link to a map also changed in V3? I’ve been searching for solutions to this and it looks like parameters were used to link directly to a location in earlier versions but nothing on that for V3…
Tanya.
Hi all,
I reckon this solution is fine provided you’ve a set of markers with LatLng alrealdy defined, what if you have to geocode a bunch of physical addresses prior to creating the markers ? I’m facing this exact issue and all I’m getting is cloned infoWindow details for all my markers, the cloned being the last marker.
Wondering if anyone has faced a similar issue or is my assumption plain wrong ?
Cheers,
Shotemba
Am not really sure I understand you. Before you can place a marker, you need a lat/lng. So not sure what you are doing. I’d do this – with each of your addresses, geocode them in one method, store that data in an array, then place markers on your map. Not really rocket science now?
Hi Colin,
Thanks for the reply. I’m aware that a lat/lng is required for every marker. In my case, I need to geocode physical address first using this function (geocoder.geocode({‘addresss’:address,function(results,status)){……}) and use results[0].geometry.location as the lat/lng value for the marker. I have to resort to this method as I am not provided with lat/lng but just physical addresses from which lat/lng is derived.
Will follow as you’ve suggested as in geocode the addresses and store the lat/lng in some array and loop over them to create the markers & infoWindows….
Thks,
Colin
Yeah, works that way
A little confused about how/where to implement your AutoCenter function since I don’t see that in your example or appended to your other code.
Also, I’m using ColdFusion to query my db. My array looks more like this (pulling out lat/long as Y, X):
cfset sites[CurrentRow].Y=Y>
But I can’t just replace my ‘sites’ where you have
function setMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
var sites = markers[i];
CF does seem to like that as-is, even when adding some tags.
The autocenter can be called anywhere you wish, as long as it has access to the correct variables.
As for your other problem, sorry you are on your own there. CF is dirty black magic to me
Hey,
ty mate! That was really helpfull in a bad situation at my internship. U really helped me out, thx dude!
Hi Colin, your solution was realy helpfull!
Thanks alot
Excellent article, I was looking for some code that allowed me to realise multiple infowindows. If you had an example with mysql send the code for see.
thanks
Thanks for the compliment. But the idea of using MySQL and then doing all the work for you is disgusting to me. Why not use a grown’d up database server like MS SQL Server
Am kidding am kidding, but not about doing all the work for you. Why do readers of the internet expect writers of the internet to do all the work for them? Should you not buy a book and do it yourself? Or even read one of the multitude of MySQL tutorials! ARGH!!!
Hi, just what I’ve been looking for.
Is there anyway to hide the markers on load and then make them appear when calling a function?
I have four different groups of markers which I would like to hide/show when selected.
I have tried removing line 40 “setMarkers(map, sites);” and have created a link with a onMouseOver event to call a function which contains the code from line 40.
This does nothing, please any help you be great.
Make you map variable global. It’s not available in setMarkers, so when you call setMarkers(map, sites) the map parameter is null…it’s that simple
Also get Firebug for your browser if running FireFox, as it will tell you the errors, maybe not in this case though as the markers you were building just had a null passed to the map property. But yeah as simple as making the map variable global. That’s £40 please. You can send it via PayPal…
You seem to be creating infowindow objects for each marker, but then only using one at a time?
Surely you’d be better off putting:
var infowindow = new google.maps.InfoWindow({content: “holding…”});
OUTSIDE your for loop.
Seeing as you’re not opening more than one info window at a time, all you’re doing is changing the content of 1 info window and associating it to a different marker with the event listener. So why create 200 info windows for 200 markers? It seems kinda pointless. Just create one outside the for loop.
Interesting post though, even it didn’t fix my problem (which is to use the new functionality in v3 to have multiple info windows open at a time).
Hey Tom, Thanks for pointing that out. The example I used has been updated in live code, but I never got round to (read as couldn’t be bothered to) fix it. But I will do that now.
Thanks
Nice Work. I have it working although I have a lot of html content.
I’m currently accessing my html in the stores array such:
html: store[4]
The in my stores array I have the very long html content string:
[‘{title}’, {locations_latitude}, {locations_longitude}, {count}, ‘INSERT LONG HTML’}
Is there a cleaner way of doing this?
If I access any dynamic data that has line break, the array doesn’t work.
thanks for the good work
Nice Work. I have it working although I have a lot of html content.
I’m currently accessing my html in the stores array such:
html: store[4],
The in my stores array I have the very long html content string:
[‘{title}’, {locations_latitude}, {locations_longitude}, {count}, ‘INSERT LONG HTML’}
Is there a cleaner way of doing this?
If I access any dynamic data that has line break, the array doesn’t work.
thanks for the good work
On the marker’s onclick event:
google.maps.event.addListener(marker, "click", function () { alert(this.html); infowindow.setContent(this.html); infowindow.open(map, this); });instead of using the this.html you could use jQuery and the
$.get(url, function(data) { //do something });with the URL calling something on your website that can spit back the html for your popup. That way you can keep the data being downloaded to your visitor small – 200 markers won’t have 200 markers worth of HTML and the visitor would only view 50 markers anyways, so download that on the fly.
That help?
Oh remember to make it synchronous otherwise things might go a bit tits!
This is nice, but I see it is not working if instead of markers I have polygons google.maps.Polygon. Any Idea how to acomplish this with polygons?
I have never used Polygons on a Google map before so I would be out my depth with an answer to that. Best probably read up on what events you can apply to a polygon. I suspect from your question, not many.
Thanks for that write up, it was really irritating me until I read your post!
I have been banging my head over this for hours. I appreciate your tutorial. Thanks! Jay
You could use this :
marker.infowindow = ...
google.maps.event.addListener(marker, 'click', function() { this.infowindow.open(map,this) });
You could do that, and create a seperate info window for each market, but that’s the point in the post, to have 1 info window only. What happens when you have an info window per marker, is you have to manually close each info window prior to opening the next window, something most people don’t want to do. So by dynamically associating a marker to a single global info window, the info window will close and reposition itself.
Can someone please tell me what I am doing wrong here, I have been working on this for two weeks now. I get my information to show on screen, but I can’t get the array data to show at all. I know the array information is there, because I have it echo’d on the screen for confirmation.
Can someone please help me?
NOTE:I am using my city and state names instead of latlng.
var me = ;
var geocoder;
var map;
var address = me['location']['name'];
var name = me['first_name'] + ” ” + me['last_name'];
var pic = ‘<img src="$pic" height="60px"';
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(33.12950, -117.09105);
var myOptions = {
zoom: 6,
center: latlng,
mapTypeControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
if (geocoder) {
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
map.setCenter(results[0].geometry.location);
var infowindow = new google.maps.InfoWindow(
{ content: '’+pic+”,
size: new google.maps.Size(150,50)
});
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title:name
});
google.maps.event.addListener(marker, ‘click’, function() {
infowindow.open(map,marker);
});
} else {
alert(“No results found”);
}
} else {
alert(“Geocode was not successful for the following reason: ” + status);
}
});
}
}
var markers = new Array();
function addMarkers()
{
var friend = ;
var address =”";
var name =” “;
var pic =”<?php echo "”; ?>”;
for (var i = 0; i < markers.length; i++)
{
var marker = markers[i];
google.maps.event.addListener(marker, 'click', function () {
// where I have added .html to the marker object.
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
function AutoCenter() {
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds();
// Go through each…
$.each(markers, function (index, marker) {
bounds.extend(marker.position);
});
// Fit these bounds to the map
map.fitBounds(bounds);
}
}
The reason it is not working is the reason I wrote this article.
you have:
google.maps.event.addListener(marker, ‘click’, function() {
infowindow.open(map,marker);
});
you need:
google.maps.event.addListener(marker, ‘click’, function() {
infowindow.open(map,this);
});
You also need to tidy up your code. Get rid of extra methods at the end, as they aren’t need for your example.
thanks Colin,
I changed that section, the map now won’t even display. Any suggestions? I appreciate your help, thank you.
I noticed I didn’t add the var infowindow, but still the additional markers don’t show:
var markers = new Array();
var infowindow = null;
infowindow = new google.maps.InfoWindow({content: “holding…”});
function addMarkers()
{
var friend = ;
var address =”";
var name =” “;
var pic =”<?php echo "”; ?>”;
for (var i = 0; i < markers.length; i++)
{
var marker = markers[i];
google.maps.event.addListener(marker, 'click', function () {
// where I have added .html to the marker object.
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
Thanks so much for posting this!
I’ve been struggling with this for hours!
thanks,
chandresh
Thanks this was a lot of help.
Ryan
Colin,
Your code is great but I have a slightly differenty problem.
I need 3 maps on the same page with one infowindow on each.
Can you give me a clue about haow to structure the code for this
Thanks
Paul
How much is it worth to you?
It is possible. Instead of making the map a global property for the script, you need to create a function that passes the map in as a property. That way you can have 3 map variables kicking around. You may get away with 1 info window, but the best is to do the same as the map, and have 3 info window variables floating around – in an array or just as 3 separate properties e.g. var map1, map2, map3; var info1, info2, info3.
It starts to get tricky at this point managing them and the events, but keep you code clean and simple and you should be ok. Let me know how you get on.
Colin
I have spent tons of time and have not managed to find a site example php code which basically connect to a db pulls regular addresses from a column (not geocode, lat, long whatsoever) and puts them on a regular goole map.
Nada nowhere… anyone can assist?
So you don’t have the lat n lng, just the regular address? Look up google geocode address. The v3 api has irks you can call which will send back XML or json for you to parse to get the lat n lng. Other than that what you is ask is a full article in it’s own right and am not well versed on php…I let WordPress do that hard work.
hey really thanks to you …
your this article has been very useful to mee
Just wanted to say thanks, this cleared up the last issue I was having with my map! Cheers.
Thanks! I have been trying to work this problem out for hours! This really helped. Thanks again!
Mate…I do not normally leave comments(for fear of SPAM) but on seeing this solution and after trying it. I have to raise my hat for this.
Many thanks.
Thanks!!
any chance you could post complete code? rather than bits and pieces? i’m trying to mashup what you have against what I have but i’m getting lost somewhere…
very usefull.
How do you attach external click events to those info windows?
I mean, I can click link outside the map and the correct info window opens?
In jQuery, please.
Do you want me to do your job? I can come round and do your job, and you can drink coffee all day?
Think on this cleanly and logically and you should be able to come up with it yourself!
simply great!
thanks a lot (and more)
Thank you Colin, this got me back on track. When I use syntax without knowing what it means I get out of my depth. I had no idea one could just add random extra fields like .html to an object and go back later to collect them. A bit of an Aladdin’s Cave, that, if it’s what’s happening.
I think that’s a great way to look at it John…Javascript – the Aladdin’s Cave of coding! Nice one!
As other map’ers, I stay hours in google to find sample code as yours. Thanks a lot!
Illes
HUNGARY
Genius, thanks so much. Saved hours of frustrating punching the screen
I’m very new to all this. I sure wish I knew enough to follow this solution. Is there any where it can be explained in terms for someone without much programing knowledge ? Yours very frustratedly Andy
I want to have you children. I am a bit novice but have spent 2 days looking for this exact solution.
Thank you
If you are female, we could come to some arrangement
Thank you. Really useful.
Thanks for this Colin, sorted my problem right out!
Thank you!! Finally a working solution. You really helped me out with this article.
After 4 days of despair you’ve dug me out of a hole. Thanks loads
Thank you! VERY helpful.
Hi
Anyway to use your code with tabbed windows? I have a site with windows coded similarly to yours, using a sites array
http://footprint.stanford.edu/compare.html
I want to be able to now add tabs to the infowindows, but how to do that in this approach that you & I are using? Can you think of a way?
thanks for any help!
Thank you !!!
Nice. My thanks.
Mike
thank you sooooo much!
Brilliant! Thank you very much.
Thanks much.. and thanks for choosing the perfect title, ‘multiple markers, multiple info windows’ to get us to this result first up on google
Thank you, nice colin.
I DID have to read the example map you did for about 15 minutes before I finally understood it.
Flipping info windows only “being formed” when they’re activated… ta
Thanks , it helped me.!!!
thank you very much .. this is really helpful…
my site is creating using c#. i want to put a link button into infopanel which is redirecting to page in same site.
and i want to know how i can get data from MS sql database to marker…
I can reply and give you a very good answer. Please email £1000 via PayPal to [email protected] and I will send you the answer.
Thank you for this. It definitely saved me a lot of hours and headscratching.
On a sidenote, for us with little coding experience, it might be an idea to add a remark about adding the “html:” to the marker options, as I didn’t get any windows up before reading through the comments. Ofcourse, the map example would have showed me the answer eventually also.
THANKS AGAIN!
See comment number 3.
Thanks, that was really helpful
Just want to say Thanks. I’ve spent 2 days working on this and other bits and pieces. Your solution took me 15 minutes to fix my code.
Thanks again
Stephen
One word “GREAT!”
Many thanks!
Thanks! It worked.
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(this.content);
infowindow.open(map, this);
});
I was using ‘marker’ instead of ‘this’ and that was a problem (I’m adding content to marker when creating istead of ‘html’, but that’s just name). Thanks again!
Many thanks, I had the same problem and this was really helpful!
[code removed because there are plenty of websites out there that will help you with that] - Colin
any one who can answer me
Code removed, sorry mate but it was more than a days worth of code in that post. From what I did see you were trying to use the “maxContent” property. If I remember rightly, that has been removed from the Google Maps API! Bit annoying as I used it on another project (not upgraded to v3 yet).
Thank you for the clean piece of code. Very helpful and cured many headaches.
Great Job! Thanks for sharing! Your right, it would have been nice for Google to do something like this, especially because this is how their maps work….
Ive almost got it. I may be having the same problem — Billy on August 28th, 2010 4:59 pm — was having.
It works if I take the “infowindow.setContent(this.html);” out
function initialize() {
var bounds = new google.maps.LatLngBounds();
bounds.extend(new google.maps.LatLng(-25.363882,131.044922));
bounds.extend(new google.maps.LatLng(-26.363882,132.044922));
bounds.extend(new google.maps.LatLng(-27.363882,133.044922));
var map = new google.maps.Map(document.getElementById(“map_canvas”),{
zoom: 5,
center: bounds.getCenter(),
mapTypeId: google.maps.MapTypeId.TERRAIN
});
map.fitBounds(bounds);
var flightPlanCoordinates = [
new google.maps.LatLng(-25.363882,131.044922),
new google.maps.LatLng(-26.363882,132.044922),
new google.maps.LatLng(-27.363882,133.044922)
];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
strokeColor: “#000000″,
strokeOpacity: .5,
strokeWeight: 3,
geodesic: true
});
flightPath.setMap(map);
var airports = [
['airport1', -25.363882, 131.044922],
['airport2', -26.363882, 132.044922],
['airport3', -27.363882, 133.044922]
];
setMarkers(map, airports);
}
function setMarkers(map, locations) {
for (var i = 0; i < locations.length; i++) {
var airport = locations[i];
var myLatLng = new google.maps.LatLng(airport[1], airport[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
html: airport[3],
});
var contentString = '’+
”+
”+
‘Airport‘+
‘Test’ +
”+
”;
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(marker, ‘click’, function() {
//infowindow.setContent(this.html);
infowindow.open(map,this);
});
}
}
Never delete this post. You just explained something I’ve been banging my head on the desk about for hours.
Thank you!
Thanks a bunch. I also bashed my head on the desk for a couple of hours trying to work this out yesterday afternoon. With this post I had it licked in just a couple of minutes. Just wish I had have googled for a solution earlier!
Great job.
This has been so helpful.
It took me a minute to figure it out but it was a life saver.
In hind sight the solution seems so simple but I would never have figured this out.
Thx
You are great!!
Yes, yes I am! (and modest too!)
My infowindows don’t resize to fit the content
Example:
And with this code, adding p- or br-tags don’t do the trick either. I guess the windows are loaded before the content. I’m new to Google Maps and coding in general, so any help is appreciated.
Andrew.
Here’s the example-link: i53.tinypic.com/1zl9b0k.jpg
Your post is so helpful that I wanna hug you. Thank you sooo much
THANK YOU SO MUCH!!! You don’t know how many lives you’ve saved!!
u rock dude!
I had hoped to follow the example at http://ratemyyogateacher.co.uk/map.html but it won’t load… could you possibly repost this? Many thanks.
Oops!! Fixed.
Hi,
I have a similar problem as Shotemba. I geocode an array of addresses in one method, and try to add markers per coordinate in another. The odd thing is that all the addresses are geocoded, but for some reason they are not available when I call them in the addMarkers-method (alert length gives 0). Could you have a quick look at it? Many thanks!
My code: http://pastebin.com/pVTTjQWf
If you donate a couple of quid (see the top right hand corner) I’ll do your job for you.
done
Basically your issue is with timing. You are calling your geocode function, which is going off to do an ajax call to Google in a loop. So if you have 5 places, then your code will loop 5 times and call Google, but it doesn’t wait for the return. As the loop takes place in milli seconds, it get’s to your second function BEFORE the Google Geocode call has returned with the answer.
So what you need to do is create the marker, and add it to your map INSIDE the return of the Google Geocode call. See this paste bin I created: http://pastebin.com/3dHpM7U8
You will also notice you then don’t need the array for the coordinates.
Let me know if that works for you.
Now I don’t see any markers anymore. The problem is that even when I put the creation of the markers inside the return of the geocode call (As I had previously), I can’t make use of the variable i in the for loop, which I need for setting the descriptions in the info windows.
Here (http://pastebin.com/8ffFcrwe) you can see my previous code, which does show all the markers and the infowindows. I print the value of i in the infowindow, with this code they all show 32 (the length of the array I loop through).
The reason I changed the code is because I tried to first geocode everything, store it in an array, and then use the methods described by you to place the markers. This is also what you suggested to Shotemba. The pastebin I paste here is the older version of the code, with everything inside the geocode return. Can you advise me which option is best and how to make it work? Thanks a lot!
Like comedy, it’s all about timing, and your timings are well off.
http://pastebin.com/2Sj5d6TY
That’s fully working code – I tested it myself. Now that’s the best £1 you have ever spent (might even be the first…).
Let me know how you get on.
I love you! (in the platonic way that is..) I was only able to donate 1 pound at a time, but I will give you another one !
No seriously, thanks. Since i’m still learning, could you tell me which part was the culprit? My guess would be that it had something to do with the indices in the loop.
Don’t send more money
That £1 will do nicely. It will get me…erm…a bottle of water.
Basically it was all about timing. You were trying to do it all at once, but when working with ajax calls you need to somehow store things. That’s where I use the Google Marker object. JavaScript allows you to create properties on the fly. Store the index (or id or whatever you want) in the marker, and retrieve it’s index when it is clicked.
Job done.
Thanks a lot mate. Unfortunately I have already send you the second bottle of water, sorry!
And am heading to Amsterdam in December. Come, we’ll spend that £1
Nice! We’ll meet up and have a ball
You don’t happen to have a solution for the constant OVER_QUERY_LIMIT messages? What I do now is just a timeout if I get such a response, and then try later. It takes quite a while for all places to be geocoded, and I don’t think I should be getting this message at all since i’m doing the request client side
There is only one solution to it…don’t query too much
Or save the lat n lng in a database against each point.
e.g.
geocoder.geocode({ ‘address’: places[i] }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// now I know the addresses and the lat n lng.
$.post(“my/url/?address=x&lat=y&lng&z”);
}
so that when you pull the addresses out the next time you don’t need to call geocoder.geocode – if the points don’t change regular, then keep a hold of the data.
I think the limit is 20 queries / sec with a max of 2500 per day. I never reach 20/s nor 2500 a day. Still im getting the error. I think I read it has something to do with coding on client side or server side where ip is shared. But Ill just keep the timeout and be happy with it
:O
You save me!!!
… 2 days trying to fix it xD
)
Thanks for the detailed explanation (including the html part
Thanks for the explanation, very helpful
Wow I was getting burned on this issue precisely!
Thanks for the help!
Hello.
Can some one provide a working example with multiple markers + multiple infowindows with html please?
Ive been trying very hard to achieve this, ive been using bits of code above but just cant get it to work. Its too complex for the little I know.
Im no professional
All I need is a map with to markes and two infowindows that include html.
Thanks
You saved me lot of of trouble! Great work Colin. Many many thanks!
btw.. I ‘d like to check the code I ‘m already using against the working example you posted in the past. Can you revive the link, please?
[...] [...]
Nice Post and nice discussion as well………Thank u all…..great help
Could someone please upload their full html code in
tags so i could see this working?!@ thanks!!Thank you so much. I was about to get crazy, your post just saved me.
Thank you! Thank you! Thank you! I just stumbled over the same problem and was looking for a fix!
Thanks man, this worked great. That discovery that you can attach arbitrary properties to markers is priceless.
Awesome, great help!!! I was going around in circles trying to figure out what I was doing wrong. Perfect solution.
Oh my god!!! Thank you!!! My problem was fixed. Yeah!!!
Legend…really useful..I think I would have been tearing my hair out without this…much appreciated!
You legend! this is what i needed!
Lee
Thank you for the post. You are so kind in replying to everyone’s query for past 1 year! Your replies toohave been very helpful for me.
Thanks man this realy was alot of help
I am a newbie on Web Development. Kindly help me out.
Currently looking for similar maps.
http://code.google.com/apis/maps/documentation/javascript/examples/marker-animations-iteration.html
Along with Info Windows for Each Marker.
I dont have any idea how to work on it…
You can check this on http://www.the080.com/dev/Details/MapTest.php
Kindly Help me out
Hi Matheen,
This looks to be outside the scope of my post. Check out stack overflow for that type of help.
Thanks
Colin
Saving the world 1 map at a time.
Hi future commenters. Please do not post your code here saying “help me!”. if for some reason your code doesn’t work. delete it. use the code above that does work and alter it to fit your environment.
alternatively head over to http://www.stackoverflow.com and actually use a questions and answers forum to help you solve your problems.
sorry to anyone that feels that’s a bit harsh but i get a lot of people asking for stuff that is outwith this post or out with me caring.
Thanks. This didn’t solve all my problems, but it helped me surpass a frustrating hurdle and I’m very appreciative. I’m glad that this is finally in my rearview mirror. I say this because the this thingy is what I needed. I don’t know how I got it to work but it works. I’m using PHP and a different kind of loop, so I just started putting this in different spots over and over until I finally got it in the right spot. Ugggh! Not fun, but thanks nonetheless.
you saved me 2 or more hours of work with this article.
thank you