you.arenot.me


Google Maps API v3 – Multiple Markers, Multiple Infowindows

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.

[Edit 4]
Demo of map working with v3 of Google Maps

228 Responses to this post

  • Fernando on July 1st, 2010 3:01 am

    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!

  • Lynn on July 11th, 2010 12:34 am

    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.

  • Colin on July 11th, 2010 6:24 am

    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 :

    infowindow.setContent(this.html);
    

    this should work (fingers crossed ;) ) for you. Let me know if it doesn’t.

  • Max on August 5th, 2010 3:09 pm

    Genius!

  • Arif on August 7th, 2010 1:42 pm

    Really Genius!

    I was heading up to it for few hours while using ExtJs with this.

    You solved my problem.

    Thank You

  • zMastaa on August 13th, 2010 12:34 pm

    Thanks for this, this should be part of the V3 code samples

  • Alex on August 17th, 2010 8:45 pm

    Thank you!!!!!

  • Scott on August 21st, 2010 6:32 am

    Thanks for this post! It solved the exact problem I was having!!!!

  • Matt McCallon on August 23rd, 2010 4:12 pm

    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.

  • Anne on August 25th, 2010 7:57 am

    Great, thanx for this :) was just what I needed!

  • Google Marker Events on August 26th, 2010 7:53 pm

    [...] 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 [...]

  • RobertBolton.com » Google Maps v3 Multiple Markers and Infowindows in a Loop on August 27th, 2010 8:13 pm

    [...] 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 [...]

  • Billy on August 28th, 2010 1:23 pm

    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);
    });
    }
    }

  • Colin on August 28th, 2010 1:32 pm

    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

  • Billy on August 28th, 2010 4:59 pm

    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);
    });
    }
    }

  • Colin on August 28th, 2010 5:13 pm

    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

  • Billy on August 28th, 2010 5:54 pm

    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.

  • Colin on August 28th, 2010 6:56 pm

    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.

  • Billy on August 28th, 2010 7:02 pm

    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/

  • Colin on August 29th, 2010 4:49 am

    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

  • Sorin on September 2nd, 2010 12:18 pm

    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.

  • Colin on September 2nd, 2010 12:58 pm

    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.

  • Colin on September 2nd, 2010 1:44 pm

    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.

  • Sorin on September 2nd, 2010 1:59 pm

    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…

  • Colin on September 2nd, 2010 2:19 pm

    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).

  • Sorin on September 2nd, 2010 2:35 pm

    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

  • Colin on September 2nd, 2010 3:03 pm

    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.

  • Sorin on September 2nd, 2010 3:31 pm

    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.

  • Colin on September 2nd, 2010 3:39 pm

    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.

  • Craig on September 14th, 2010 11:12 pm

    I was having this issue as well. This post solved it. Thanks a lot!

  • manwich on September 16th, 2010 6:07 am

    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!

  • Colin on September 16th, 2010 6:22 am

    Stand up young padawan. More practice and soon you shall be a master…sorry erm I mean, cheers for that :D

  • Alberto on September 17th, 2010 3:46 pm

    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!

  • Tanya on September 19th, 2010 4:14 pm

    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.

  • Colin on September 19th, 2010 4:37 pm

    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?

  • Paul on September 24th, 2010 5:43 pm

    Cheers Colin. After a couple of hours reading Google code and not getting anywhere I found you! Works a treat matey, superb.

  • Tanya on September 26th, 2010 8:52 am

    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.

  • Shotemba on September 29th, 2010 9:40 am

    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

  • Colin on September 29th, 2010 10:01 am

    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?

  • Shotemba on September 30th, 2010 1:26 am

    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

  • Shotemba on October 4th, 2010 7:56 am

    Yeah, works that way ;-)

  • Matt on October 6th, 2010 8:20 pm

    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.

  • Colin on October 13th, 2010 8:21 am

    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 :)

  • Sven on October 19th, 2010 8:34 am

    Hey,
    ty mate! That was really helpfull in a bad situation at my internship. U really helped me out, thx dude! ;)

  • Frank on November 1st, 2010 12:24 pm

    Hi Colin, your solution was realy helpfull!

    Thanks alot

  • byzard on November 2nd, 2010 4:05 am

    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

  • Colin on November 2nd, 2010 6:23 am

    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 :D 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!!!

  • VonHat on November 5th, 2010 4:16 pm

    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.

  • Colin on November 5th, 2010 4:55 pm

    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…

  • Tom on November 8th, 2010 8:45 pm

    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).

    :)

  • Colin on November 9th, 2010 1:09 pm

    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

  • Stephen on November 11th, 2010 5:20 pm

    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

  • Stephen J. on November 11th, 2010 5:21 pm

    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

  • Colin on November 11th, 2010 5:32 pm

    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?

  • Colin on November 11th, 2010 5:34 pm

    Oh remember to make it synchronous otherwise things might go a bit tits!

  • Iulian on November 15th, 2010 4:53 pm

    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?

  • Colin on November 15th, 2010 5:05 pm

    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.

  • Swifty on November 25th, 2010 2:09 pm

    Thanks for that write up, it was really irritating me until I read your post!

  • jay on November 27th, 2010 5:28 pm

    I have been banging my head over this for hours. I appreciate your tutorial. Thanks! Jay

  • Bozhidar on November 27th, 2010 9:13 pm

    You could use this :

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

  • Colin on November 27th, 2010 9:22 pm

    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.

  • kevin on November 30th, 2010 9:03 pm

    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);
    }
    }

  • Colin on November 30th, 2010 9:13 pm

    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.

  • kevin on November 30th, 2010 9:33 pm

    thanks Colin,
    I changed that section, the map now won’t even display. Any suggestions? I appreciate your help, thank you.

  • kevin on November 30th, 2010 9:38 pm

    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);
    });
    }

  • Chandresh on December 9th, 2010 5:08 am

    Thanks so much for posting this!

    I’ve been struggling with this for hours!

    thanks,
    chandresh

  • Ryan on December 20th, 2010 5:18 am

    Thanks this was a lot of help.

    Ryan

  • Paul Cobb on December 20th, 2010 12:00 pm

    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

  • Colin on December 20th, 2010 12:08 pm

    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

  • Jack on December 24th, 2010 8:02 am

    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?

  • Colin on December 24th, 2010 10:22 am

    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.

  • jaimin on January 17th, 2011 8:07 am

    hey really thanks to you …
    your this article has been very useful to mee

  • SuperAlly on January 19th, 2011 3:23 pm

    Just wanted to say thanks, this cleared up the last issue I was having with my map! Cheers.

  • Morey on January 23rd, 2011 8:16 am

    Thanks! I have been trying to work this problem out for hours! This really helped. Thanks again!

  • ken... on January 25th, 2011 10:26 am

    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.

  • yo on January 25th, 2011 4:55 pm

    Thanks!!

  • andy on February 9th, 2011 10:31 pm

    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…

  • panchicore on February 17th, 2011 8:57 pm

    very usefull.

  • asker on March 3rd, 2011 10:05 pm

    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.

  • Colin on March 3rd, 2011 10:36 pm

    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!

  • FredBx on March 4th, 2011 1:32 pm

    simply great!
    thanks a lot (and more)

  • John Harris on March 7th, 2011 7:19 am

    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.

  • Colin on March 7th, 2011 8:53 am

    I think that’s a great way to look at it John…Javascript – the Aladdin’s Cave of coding! Nice one!

  • Illes on March 18th, 2011 10:53 pm

    As other map’ers, I stay hours in google to find sample code as yours. Thanks a lot!

    Illes
    HUNGARY

  • Mark Kenny on March 25th, 2011 11:53 pm

    Genius, thanks so much. Saved hours of frustrating punching the screen :D

  • Andy on April 1st, 2011 1:33 pm

    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

  • Chase on April 5th, 2011 11:07 pm

    I want to have you children. I am a bit novice but have spent 2 days looking for this exact solution.

    Thank you

  • Colin on April 7th, 2011 7:56 am

    If you are female, we could come to some arrangement :D

  • tunnik on April 12th, 2011 1:34 pm

    Thank you. Really useful.

  • Gareth Griffiths on April 13th, 2011 11:37 am

    Thanks for this Colin, sorted my problem right out!

  • Serial on April 20th, 2011 11:30 am

    Thank you!! Finally a working solution. You really helped me out with this article. :)

  • Dale on April 20th, 2011 12:25 pm

    After 4 days of despair you’ve dug me out of a hole. Thanks loads :-)

  • Matt on April 23rd, 2011 6:49 pm

    Thank you! VERY helpful.

  • bugjah on April 28th, 2011 7:14 am

    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!

  • Fred on April 28th, 2011 9:22 pm

    Thank you !!!

  • Mike on May 10th, 2011 1:11 pm

    Nice. My thanks.

    Mike

  • Luann Ebert on May 11th, 2011 3:09 am

    thank you sooooo much!

  • Dave on June 3rd, 2011 3:37 pm

    Brilliant! Thank you very much.

  • Vipul on June 3rd, 2011 4:00 pm

    Thanks much.. and thanks for choosing the perfect title, ‘multiple markers, multiple info windows’ to get us to this result first up on google

  • inteblio on June 8th, 2011 2:47 pm

    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

  • arturo on June 12th, 2011 6:46 pm

    Thanks , it helped me.!!! :)

  • repz on June 21st, 2011 7:06 am

    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…

  • Colin on June 21st, 2011 10:38 am

    I can reply and give you a very good answer. Please email £1000 via PayPal to you@arenot.me and I will send you the answer.

  • Andrew on June 22nd, 2011 11:12 am

    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!

  • Colin on June 22nd, 2011 11:14 am

    See comment number 3.

  • tarekadel89 on June 26th, 2011 7:22 pm

    Thanks, that was really helpful

  • Stephen on June 28th, 2011 4:30 pm

    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

  • Mrodrigues on July 6th, 2011 4:03 pm

    One word “GREAT!”

  • Everton on July 10th, 2011 12:17 am

    Many thanks!

  • Wojtas on July 10th, 2011 11:03 am

    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! :)

  • Nassia on July 16th, 2011 6:55 pm

    Many thanks, I had the same problem and this was really helpful!

  • niraj on July 18th, 2011 4:02 pm

    [code removed because there are plenty of websites out there that will help you with that] - Colin

    any one who can answer me

  • Colin on July 18th, 2011 4:27 pm

    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).

  • Aaron West on July 19th, 2011 4:50 pm

    Thank you for the clean piece of code. Very helpful and cured many headaches.

  • Greg Sipes on July 21st, 2011 2:46 pm

    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….

  • fpmuser on July 30th, 2011 7:39 pm

    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);
    });
    }
    }

  • Danny on August 3rd, 2011 11:42 pm

    Never delete this post. You just explained something I’ve been banging my head on the desk about for hours.

    Thank you!

  • Richard on August 12th, 2011 2:01 pm

    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.

  • Bonadventure on August 19th, 2011 8:18 pm

    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.

  • Daniele on September 2nd, 2011 2:24 pm

    Thx ;) You are great!!

  • Colin on September 2nd, 2011 2:25 pm

    Yes, yes I am! (and modest too!)

  • Andrew on September 16th, 2011 12:01 am

    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.

  • Andrew on September 16th, 2011 12:02 am

    Here’s the example-link: i53.tinypic.com/1zl9b0k.jpg

  • Lily on September 17th, 2011 8:57 am

    Your post is so helpful that I wanna hug you. Thank you sooo much :)

  • Christina on September 19th, 2011 2:41 pm

    THANK YOU SO MUCH!!! You don’t know how many lives you’ve saved!!

  • Rochas Dude on September 19th, 2011 11:41 pm

    u rock dude!

  • Tim on October 11th, 2011 7:13 am

    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.

  • Colin on October 11th, 2011 2:57 pm

    Oops!! Fixed.

  • Ed on October 13th, 2011 9:44 am

    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

  • Colin on October 13th, 2011 9:57 am

    If you donate a couple of quid (see the top right hand corner) I’ll do your job for you.

  • Ed on October 13th, 2011 9:59 am

    done

  • Colin on October 13th, 2011 10:21 am

    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.

  • Ed on October 13th, 2011 10:35 am

    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!

  • Colin on October 13th, 2011 11:00 am

    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.

  • Ed on October 13th, 2011 11:37 am

    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 ! :P 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.

  • Colin on October 13th, 2011 11:41 am

    Don’t send more money :D 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.

  • Ed on October 13th, 2011 11:43 am

    Thanks a lot mate. Unfortunately I have already send you the second bottle of water, sorry!

  • Colin on October 13th, 2011 11:44 am

    And am heading to Amsterdam in December. Come, we’ll spend that £1 :D

  • Ed on October 13th, 2011 11:54 am

    Nice! We’ll meet up and have a ball :D

  • Ed on October 13th, 2011 2:34 pm

    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

  • Colin on October 13th, 2011 2:54 pm

    There is only one solution to it…don’t query too much :D 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.

  • Ed on October 13th, 2011 2:56 pm

    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 :D

  • Tony on October 14th, 2011 3:06 am

    :O

    You save me!!! :D … 2 days trying to fix it xD
    Thanks for the detailed explanation (including the html part :P )

  • František Kocúrik on October 15th, 2011 4:56 pm

    Thanks for the explanation, very helpful ;-)

  • Ben on October 16th, 2011 7:34 pm

    Wow I was getting burned on this issue precisely!
    Thanks for the help!

  • tolinho on October 19th, 2011 1:40 am

    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

  • Avi on October 21st, 2011 9:51 am

    You saved me lot of of trouble! Great work Colin. Many many thanks! :-)

  • Avi on October 21st, 2011 9:53 am

    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?

  • Google Maps – Random References | zaus – an Orange Monks Production on November 2nd, 2011 11:09 pm

    [...] [...]

  • gopal on November 7th, 2011 6:08 am

    Nice Post and nice discussion as well………Thank u all…..great help

  • Nick on November 10th, 2011 9:21 am

    Could someone please upload their full html code in tags so i could see this working?!@ thanks!!

  • Markus on November 16th, 2011 5:30 pm

    Thank you so much. I was about to get crazy, your post just saved me.

  • Irina on November 24th, 2011 10:15 am

    Thank you! Thank you! Thank you! I just stumbled over the same problem and was looking for a fix!

  • Jason on November 28th, 2011 10:27 pm

    Thanks man, this worked great. That discovery that you can attach arbitrary properties to markers is priceless.

  • Arnold on December 4th, 2011 9:14 pm

    Awesome, great help!!! I was going around in circles trying to figure out what I was doing wrong. Perfect solution.

  • van dao on December 16th, 2011 3:51 am

    Oh my god!!! Thank you!!! My problem was fixed. Yeah!!!

  • Sam on December 18th, 2011 1:18 pm

    Legend…really useful..I think I would have been tearing my hair out without this…much appreciated!

  • Lee W on December 21st, 2011 3:51 pm

    You legend! this is what i needed!

    Lee

  • Deepak on December 27th, 2011 2:24 am

    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.

  • Agron on January 8th, 2012 10:41 pm

    Thanks man this realy was alot of help

  • Hi There, on January 13th, 2012 12:15 pm

    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

  • Colin on January 13th, 2012 1:06 pm

    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.

  • Colin on January 15th, 2012 6:38 pm

    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.

  • Matt W on January 19th, 2012 9:32 pm

    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.

  • tom on February 3rd, 2012 10:30 am

    you saved me 2 or more hours of work with this article.
    thank you

  • Casey Wise on February 3rd, 2012 6:01 pm

    You helped me massively. You program and refer to it like me, I employ many thingamabobbies!

    Thanks for taking the time! You get a gold star.

  • Colin on February 21st, 2012 1:17 pm

    Hey Jason,

    The code you posted and the link along with it didn’t work. And using eval INSIDE javascript to build javascript is just piss poor (in my humble opinion). The link you wanted to direct people to, the map in the top corner didn’t work the way people here need things to work… so I deleted your code :D Sorry bud. Your secret is crap!

    Colin
    (site owner)

  • Colin on February 21st, 2012 3:44 pm

    The demo you posted didn’t work.
    The code was crap.
    You will find that this post gets 6,000 hits a month, with tonnes of comments all saying “It works”.

    Oh and amazingly enough you demo link works now. Did you fix it today???

  • Benjamin Kaiser on February 28th, 2012 11:44 pm

    Thank you sooo much for this. I have been looking for this for hours, I knew it had to be holding onto something (the last marker) and thats why it would always show up on that one marker. But I couldnt work out how to properly reference the current index one. THANKS!!!!

  • astaza on March 7th, 2012 8:29 pm

    nice work but dos not work with google map ver 3
    do you have any update ?

  • Colin on March 7th, 2012 8:53 pm

    Hey Astaza,

    Please see the new edit above [Edit 4] to show the code working in a v3 map. I have used this code in every map I have built in the last 2 years, so I can guarantee that it does work with v3!

  • Lukas on March 8th, 2012 8:40 am

    That did it, thanks a lot!

  • Rawa on March 13th, 2012 10:58 am

    Hi, my case is that my markers are moving after some seconds, how can I find a specific marker to move it to next location?

  • Colin on March 13th, 2012 11:11 am

    As long as you are keeping track of your markers in an array e.g. var markers = []; and then doing a markers[markers.length] = { however you create your markers}, then you should be able to iterate around the array.

    Is that what you are doing?

  • Lisa on March 23rd, 2012 2:52 pm

    thank you so much for the only working post across the http://www…. really saved my day.

  • Colin on March 23rd, 2012 2:57 pm

    Why thank you! That’s the funny thing about the internet…so many examples, so few that work. I hope all of mine work.

  • Greg on March 28th, 2012 4:44 pm

    Thank you!!! no help from google. immediate fix.

  • Antto on April 4th, 2012 10:08 pm

    Dude, you’re a lifesaver. Project deadline is tomorrow and I was stuck with this problem…but not anymore!

  • MrName on April 16th, 2012 10:25 pm

    Dude! You totally rock. I read through so many blogs with lofty, overly complex solutions to this issue. You most definitely nailed a simple and extremely effective solution. Thank you so much!

  • JustJamie on April 25th, 2012 5:52 am

    OMG Thank you SOOOOOOOO much for this example. It solved the problem I have spent nearly 14 HOURS googling!!!! Please…please…please….post this in as many places as you can. This should not have been soooo difficult to figure out!

    You can see my working example at:
    Jamie’s Joint – TwisterTag

  • Lou on May 12th, 2012 1:56 am

    Thanks so much for posting this! It works amazingly well!

    I’ve been at a loss trying to replace the results for markers with data from a JSON request…


    $.getJSON("[URL]", function(json) {
    ...
    }

    Would you know of an easy way to incorporate that into this example?

  • Colin on May 18th, 2012 8:40 am

    Yeah that’s 100% the right direction. Check out this:

    function addGooglePlaces() {
    var center = map.getCenter();
    $.getJSON("/common/handlers/get-others.ashx?lat=" + center.lat() + "&lng=" + center.lng(), function (data) {
    setMarkers(map, data);
    if (data.length > 1)
    AutoCenter();

    $("#googlePlaces").hide();
    $("#disclaimer").show();
    });
    }

    this makes sure that the data that is sent back is in a known format, that you can then parse in the setMarkers function:

    function setMarkers(map, locations) {
    geocoder = new google.maps.Geocoder();
    var marker = null;
    for (var i = 0; i < locations.length; i++) {

    var siteLatLng = new google.maps.LatLng(locations[i].Lat, locations[i].Lng);
    marker = new google.maps.Marker({
    position: siteLatLng,
    map: map,
    icon: locations[i].Icon,
    lat: locations[i].Lat,
    lng: locations[i].Lng,
    html: locations[i].Html
    });

    markers[i] = marker;

    if (locations[i].Html != "") {

    google.maps.event.addListener(marker, "click", function () {
    showBubble(this);
    });
    }
    }
    markerCluster = new MarkerClusterer(map, markers, {
    gridSize: 30,
    styles: markerStyles
    });

    // setInterval(geocode, 1000);
    }

    The one thing you need to keep in mind is if you are repeatedly calling this function, to clear the previous markers.

  • Colin on May 18th, 2012 8:41 am

    http://iheartmyyogi.com/yoga/ireland/dublin/map.html

    Here is the example. The google places link is below the map, click it, and the map will populate with more markers.

  • Brian H on May 30th, 2012 5:51 am

    Great! Thanks for the information. It saved me hours of frustration.

  • Code Challenge - Curiosita LabsCuriosita Labs on June 4th, 2012 8:38 pm

    [...] show the last InfoWindow, no matter which marker I clicked on. After researching Google, I found Google Maps API V3 Multiple Markers, Multiple Infowindows. Colin Wiseman walks you through the problem and provides you with a solution. I used his solution [...]

  • Colin on June 6th, 2012 11:30 am

    Yass! People know me. The world is good!

  • Gelki on June 16th, 2012 1:56 pm

    Thank God for this site! Thanks to all of you!

  • Dre on June 19th, 2012 6:24 am

    Many thanks!! Very helpful info.

  • Ian on July 25th, 2012 8:08 pm

    Over 2 years after you posted this really helpful article it is a pity that Google don’t refer to it in their Developer documentation. You have clearly saved many people hours of head scratching. Thank you for unselfishly putting this into the public domain.

  • Ralph Varney on July 27th, 2012 3:04 pm

    After searching forever I finally found your site and example of how to use multiple markers. Thank you! If…after 2 years you are still into helping..
    How can I also include a polyline connecting two(or more)points.

  • Colin on July 27th, 2012 4:11 pm

    Yeah it takes for ever to find my site…well unless you search for Google Maps Multiple Infowindows in which case it’s quite near the top. {am pulling yer leg. Cheers for using my code :D }

  • Ralph Varney on July 27th, 2012 4:26 pm

    Would you have the time (or energy) to show me how to add a polyline to a series of points?

  • Ralph Varney on July 27th, 2012 5:44 pm

    Okay.. now the second puzzle. How do I make more markers than your sample. I have looked through every bit of code / question in this forum and no one seems to have needed to add more than 4 markers. I am assuming something needs changing in;
    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,
    title: sites[0],
    zIndex: sites[3],
    html: sites[4]
    });

    And the numbers need to be incremented in

    ['Ralph', 49.6285634, -117.6997554, 1,

  • Ralph Varney on July 28th, 2012 3:42 pm

    Sorted out my own second puzzle.. Seems by copying the 4 sample “markers” I was not including a comma on the last line as in ],

    I found my problem by looking at the code in a many marker site at http://footprint.stanford.edu/compare.html that uses the code Colin has graciously provided.

    But.. I still would like help / direction on how to add a series of polylines to my map

    Thanks all

  • Ralph Varney on August 11th, 2012 6:55 pm

    Ok.. it has been two weeks, the Olympics is soon over time to continue on my website map again. I appreciate that I am late to the party, being as the active development started over two years ago.. but.

    Is it possible to have polylines and use Colins approach to multiple markers on the same map. And if so could someone please point to a sample

    Thanks all

  • Google Maps API v3 multiple markers Infowindow | t1u on August 11th, 2012 11:24 pm

    [...] the last infowindow showing up on all markers. I’ve tried all sorts of solutions including: http://you.arenot.me/2010/06/29/google-maps-api-v3-0-multiple-markers-multiple-infowindows/ and this one [...]

  • colin on August 12th, 2012 12:21 am

    Ralph you are probably better asking this question on Stackoverflow. My blog doesn’t really cover what you are asking about.

  • Ralph Varney on August 12th, 2012 12:55 am

    Thanks.. will give them a shout

  • Google Maps API v3 multiple markers Infowindow | appsgoogleplus.com on August 12th, 2012 1:25 pm

    [...] the last infowindow showing up on all markers. I’ve tried all sorts of solutions including: http://you.arenot.me/2010/06/29/google-maps-api-v3-0-multiple-markers-multiple-infowindows/ and this one [...]

  • Rob on August 28th, 2012 7:32 pm

    Thanks a lot for making this code available. It’s one of those things that I could have wasted days trying to figure out. You’re a hero!

  • Colin on August 28th, 2012 7:56 pm

    Nah. Not a hero. Just a man doing Google’s work for them unpaid… :D

  • zawaung on September 7th, 2012 7:21 pm

    Thanks for posting this, was tearing my hair out trying to work out why this wasn’t working :)

  • Ralph Varney on September 13th, 2012 4:14 am

    My only chance to be able to include polylines to your sample is if you show me how. I have requested help on many forums and have received only cut and paste samples from Google on polylines or nothing at all.

    It seems I am late to the development phase and interest in coding for Google maps is next to zero.

    Still, your sample for markers is the best I have found and I thank you for letting me use it.

  • Colin on September 13th, 2012 7:52 am

    Sorry Raplh, but I am unable to help. I have never worked with poly lines in any anger so I’d only point you to resources out there.

    If you pay me I’d be happy to spend time learning and coming up with your answer but I would charge you £40 an hour.

  • Ralph Varney on September 14th, 2012 1:34 am

    Fair enough.. this is a for a family website so my budget is in the same category as when you said in a previous post.”Nah. Not a hero. Just a man doing Google’s work for them unpaid… :D

  • it training on September 18th, 2012 7:13 pm

    Nice blog here! Also your website loads up fast!

    What web host are you using? Can I get your affiliate link to your host?
    I wish my website loaded up as quickly as yours lol

  • Colin on September 18th, 2012 8:14 pm

    My website runs off dedicated hosting to which I pay a small fortune a month for. But it allows me to tinker and learn stuff to help my day job. ServerBeach…and they rock. No affiliate links though.

  • – What I Learned Today Series on October 1st, 2012 10:12 pm

    [...] used this resource to output multiple InfoWindows using Google Maps’ API [...]

  • Gabby on October 12th, 2012 7:37 pm

    Hi There,

    This code works great, but I don’t want the popup window first, how can I adjust the code to remove the popup window and just have the infowindows display when clicked?

  • Colin on October 15th, 2012 10:39 am

    That will be as simple as removing the call to alert(); within the code.

  • Michael on October 19th, 2012 12:21 pm

    Hi Guys,

    This link saved my life, and fix this issue more easier than this solution.

    http://stackoverflow.com/questions/11236052/gmaps-v3-markers-addlistener-getting-always-the-last-variable-index-in-the-for-l

  • Colin on October 19th, 2012 12:56 pm

    I know I am long winded above, but my solution is really only change the word “marker” to “this” inside the click listener. Anything else is overly complicated and a bunch of wank…and is also the problem with programming today – lets keep things simple!

  • Chris on October 25th, 2012 12:46 am

    Thank you, thank you, thank you! I’ve been banging my head against this all day until I found your post.

    Again,
    Thank You!

  • Gabby on October 25th, 2012 8:08 pm

    Colin – Thank you very much. I had tried that previously and it wasn’t working. I copied your source code and removed it, now it is working. Must have been a user error on my end! ;)

    Thank you for posting, responding and solving my headache!

  • Jos on November 18th, 2012 12:03 pm

    Thanks, I have been pulling my hair out over this.

  • drixe on November 25th, 2012 12:10 am

    Hi,
    And what will it give with the geocoding ?
    I love your bit of code but I can’t mix it with a geaocoding approach…
    Tx

  • Colin on November 25th, 2012 6:02 pm

    The geocoding approach will be hard due to timings involved. Because you click the pointer, and the bubble opens, but you need the data then, you can’t call the geocoder as it is an ajax call and will return to a function that doesn’t know about the pointer you clicked.

    You could though, do something like this:

    var marker_clicked = null;

    [code code code]
    google.maps.event.addListener(marker, 'click', function () {
    {
    marker_clicked = this;
    /// call your geocoding stuff here and when it returns you use marker_clicked
    /// apply your HTML but then remember to make marker_clicked = null, so things
    /// don't get mixed up
    }

    That help?

  • grisboreal on November 25th, 2012 6:05 pm

    hi,

    I’m using the code at the top of this page and it works well.
    How can i integrate marker cluster into this code ?

    thanks.

  • Colin on November 25th, 2012 6:41 pm

    Marker clustering should be separate from this, i.e. it won’t affect it. But it is also beyond the scope of this article. So you could work it out for yourself? (or pay me and I would do it for you…)

  • Google Maps API v3.0 – Multiple Markers, Multiple Infowindows :you.arenot.memStudiosTALK | mStudiosTALK on December 11th, 2012 12:15 am

    [...] Google Maps API v3.0 – Multiple Markers, Multiple Infowindows :you.arenot.me September 7, 2010 Leave a reply [...]

  • Clain Dsilva on December 11th, 2012 5:06 pm

    Love you man… I was totally lost with the multiple markers.. Google API docs had little information. You made my day… many thanks for the code.

  • Ralph Varney on January 1st, 2013 8:16 pm

    Update on my effort to get polylines to work with Colin’s code. With much trial and error.. adding this seems to work
    var map = new google.maps.Map(document.getElementById(“map_canvas”), myOptions);
    // common to both markers and polylines above, add code for polylines below this comment and stop before setMarkers(maps,sites);
    var polyline = [
    new google.maps.LatLng(39.58108, -105.63535),
    new google.maps.LatLng(40.315939, -105.440630),
    new google.maps.LatLng(43.785890, -101.90175),
    new google.maps.LatLng(39.99948, -105.28370),

    ];
    var Property = new google.maps.Polyline({
    path: polyline,
    strokeColor: “#FF0000″,
    strokeOpacity: 1.0,
    strokeWeight: 2
    });

    Property.setMap(map);
    //all polyline info to stop before this line.

    setMarkers(map, sites);

  • Colin on January 2nd, 2013 9:27 am

    Nice one Ralph. You should blog about this stuff yourself. Blogging really helps me learn at the same time. Thanks :)

  • Andy on February 23rd, 2013 10:14 am

    Ive been trying to get this to work for ages now, and would like to know whats preventing the map from rendering? I’m not getting any script errors and tried debugging it but nothing seems to be wrong? Also tried JSLint and that doesnt throw any errors either…

  • Colin on February 23rd, 2013 10:21 am

    Hey Andy,

    Looked at your code. Thanks for posting – took it out of your comment as well. Have you looked at the source code for my map demo?

    http://you.arenot.me/map.html

    In your code, it appears that:

    1. You aren’t calling : $(document).ready(function () { initialize(); });
    (unless you aren’t using jQuery). But you still need to call initialize();

    2. your setMarkers function is inside your initialize function. Take that out.

    3. is your div in your HTML called map_canvas i.e.

    Let me know if that helps.

  • Andy on February 23rd, 2013 10:39 am

    Colin,

    Thanks for the reply. I have got markers (without info windows working already on the site I’m doing) but wanted to add infowindows to them. So i followed your example.

    I’ve made the document ready function change and sorted out the braces as I’d missed it and put an extra one at the end.

    However still no joy.

    heres the code:

    var infowindow = null;
    $(document).ready(function () { initialize(); });

    function initialize() {
    var centerMap = new google.maps.LatLng(52.427, -1.700);
    var myOptions = {
    zoom: 11,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map(document.getElementById(‘map_canvas’), myOptions);

    setMarkers(map, sites);
    infowindow = new google.maps.InfoWindow({
    content: ‘loading…’
    });
    }

    var sites = [['Masons Arms Public House', 52.4119363, -1.7762272, 1, 'Masons Arms Public House'],['Starbucks', 52.4133206, -1.7792657, 2, 'Starbucks'],['John Lewis', 52.413938, -1.780450, 3, 'John Lewis'],['Fallen Angel Bakery', 52.4131195, -1.7780644, 4, 'Fallen Angel Bakery'],['Lush Cosmetics', 52.4137078, -1.7760573, 5, 'Lush Cosmetics'],['Berryfield Farm Shop', 52.4300365, -1.6411231, 6, 'Berryfield Farm Shop'],['Michaels Foodmarkets', 52.4455737, -1.783855, 7, 'Michaels Foodmarkets'],['Balsall Common Foodcentre', 52.3907374, -1.6490093, 8, 'Balsall Common Foodcentre'],['Berkswell Village Store', 52.4093881, -1.6417169, 9, 'Berkswell Village Store'],['La Delicica', 52.3928246, -1.6464652, 10, 'La Delicica'],['Oldwich Ln W', 52.360569, -1.6918703, 11, 'Oldwich Ln W'],['New Covent Garden', 52.3884441, -1.7350296, 12, 'New Covent Garden'],['One Stop Shop', 52.4037472, -1.8227041, 13, 'One Stop Shop'],['Solihull Cornucopia', 52.4291942, -1.7978353, 14, 'Solihull Cornucopia'],['Wedges Bakery', 52.3644425, -1.8055321, 15, 'Wedges Bakery'],['Field Fresh', 52.4803318, -1.7392491, 16, 'Field Fresh'],['Fleur de Lis', 52.4137601, -1.7787196, 17, 'Fleur de Lis'],['Vi Stevens Florist', 52.4062113, -1.8232528, 18, 'Vi Stevens Florist'],['Sheldon Florist', 52.3885955, -1.7343968, 19, 'Sheldon Florist'],['Flamingo Florists Ltd', 52.4455737, -1.783855, 20, 'Flamingo Florists Ltd'],['Cotswold Outdoor Co', 52.4137078, -1.7760573, 21, 'Cotswold Outdoor Co'],['M & Co', 52.4137605, -1.7780644, 22, 'M & Co'],['Monsoon/Accessorize', 52.4131195, -1.7780644, 23, 'Monsoon/Accessorize'],['Next', 52.4109457, -1.7784396, 24, 'Next'],['Top Man', 52.4124038, -1.7793879, 25, 'Top Man'],['Zara', 52.4124038, -1.7793879, 26, 'Zara'],['Boots', 52.4130676, -1.7764163, 27, 'Boots'],['Akamba Garden Centre', 52.3902978, -1.8483994, 28, 'Akamba Garden Centre'],['Café Azzurro', 52.397, -1.8042, 29, 'Café Azzurro'],['Café Shirley', 52.4047535, -1.8222885, 30, 'Café Shirley'],['Clock Hotel', 52.4438483, -1.7303281, 31, 'Clock Hotel'],['Melbicks Garden And Leisure', 52.4619907, -1.7041663, 32, 'Melbicks Garden And Leisure'],['Notcutts', 52.3828902, -1.7897604, 33, 'Notcutts'],['West Cornwall Pasty Co', 52.4136365, -1.7789121, 34, 'West Cornwall Pasty Co'],['Saracens Head', 52.4114314, -1.8271866, 35, 'Saracens Head'],['Olton Tavern', 52.4384362, -1.7827444, 36, 'Olton Tavern'],['The Bakers Oven', 52.4124038, -1.7793879, 37, 'The Bakers Oven'],['Solihull Manor House', 52.411723, -1.7774502, 38, 'Solihull Manor House'],['Lyndon Humanities College', 52.4479357, -1.7896544, 39, 'Lyndon Humanities College']];

    function setMarkers(map, markers) {

    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,
    title: sites[0],
    zIndex: sites[3],
    html: sites[4]
    });

    var contentString = 'Some content';

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

  • Andy on February 23rd, 2013 10:40 am

    and yes, the div id is correct, I checked that a few times just incase!

  • Colin on February 23rd, 2013 10:45 am

    Do you use FireBug and developer toolbar? I popped your code in and it told me that myLatlng was not defined. I changed that to centerMap and bingo. Map appeared fine.

Leave a comment
YOUR COMMENT