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:

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 () {, 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 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);, this);

Notice the change from marker to this. As you have all seen the event fires for each marker, but as you were calling, 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.


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) {
//  Fit these bounds to the map

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

257 thoughts on “Google Maps API v3 – Multiple Markers, Multiple Infowindows”

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

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

  3. 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”

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

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

  6. 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?

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

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

    Thank You!

  9. 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!

  10. 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?

  11. 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 ?


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

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

    //all polyline info to stop before this line.

    setMarkers(map, sites);

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

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

  16. 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?

    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.

  17. 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);, this);

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

  19. I am trying to get the info window to only display when a link on a side bar is clicked. I currently got it working when you click on an icon on the map. How would you use your code to obtain this result?


  20. Thank you so much; it worked like a charm. I have been trying to figure it out since noon. Many thanks

  21. Hello, how I do to get Html dinamically? Example, I have an Hotel List and when I click in any Marker, I want to get INDEX for this marker, but when I try to do it, INDEX is ever the last position!

  22. This really helped me get half of the stuff fixed.

    But what if I have some additional array along with markers? I can’t access their index using ‘this’. :/

  23. THANKS YOU VERY MATCH!!! Дякую тобі, чоловіче, первелике! Я вже не одинь день у пошуках відповіді на це запитання!

  24. Today, while I was at work, my sister stole my apple ipad and
    tested to see if it can survive a thirty foot drop, just
    so she can be a youtube sensation. My iPad is now broken and she has 83 views.
    I know this is completely off topic but I had to share it with someone!

  25. Small meals (10% of total daily ration) are one option for the rest period.
    We humans love the taste sensations of dinner and like to sit and savior the meals and
    share our thoughts or spices, preparation, and the cleaning up.
    Dogs will love lard and gound beef tallow, but these are high in saturated fats
    and low in fatty acids (which can be needed for a good

  26. Hi, I have a problem with close infowindow made with array.

    g_map.wClose = function(){
    for(var p=0;p<17;p++)

    I did like this, but "Cannot call method 'close' of undefined ".
    Please Help me!

  27. Thanks! was thinking that ‘this’ keyword had to play some role in it,,, and thanks again for the second suggestion, i was about to need it….

  28. like this tutorial. please I intend to labels such that each marker appear with a label and displays its info window on it when it is clicked. Thanks

Leave a Reply

Your email address will not be published.