Skip to content

Use Google Maps API to create custom marker InfoWindows with jQuery Gmap3

View the Demo

If you are creating customised maps for a site you may be using the Google Maps API to do so. The API gives a huge level of flexibility in drawing maps if you need it to accept dynamic input.

The API is greatly simplified by using the jQuery plugin, Gmap3. But it comes at a cost and it seems a certain layer of flexibility is removed in favour of this simpler coding format.

What we are going to do.

In this example, I want to be able to locate my markers that will be specified by addresses saved in JSON format. The JSON will also include the content I want to display for this marker when it is clicked on. This ‘InfoWindow’ that pops up on the click event I want to be able to style it in a specific way and not the default Google Maps way. In the API, the ‘InfoWindow’ has a very limited design scope.

One way it would be tackled using the native Google Maps API code would be to use the InfoBox library which extends the OverlayView class. I found that trying to find a resource with this feature implemented for the Gmap3 jQuery library was scarce.

Realising the class that the ‘InfoBox’ library extends (OverlayView) I thought I could create overlays for my markers that are triggered on click. Overlays are a lot more flexible, we can wrap our own div around them.

Let’s begin

The first thing to do would be to make sure all of our relevant libraries and scripts for accessing the Google Maps API are in place.

In your document <head> (or wherever you load your scripts)

<!-- jQuery -->
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<!-- The Google Maps API lib -->
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?v=3&sensor=false"></script>
<!-- The Gmap 3 lib -->
<script type="text/javascript" src="http://cdn.jsdelivr.net/gmap3/5.1.1/gmap3.min.js"></script>

Now we want to create an element for our map to go in.

In the <body> of your document

<style type="text/css">
.gmap {
    width:450px;
    height:450px;
}
</style>
<div class="gmap"></div> <!-- Our map will appear here -->

The next part is to build an example JSON structure with our information in it. Of course you can add as much meta information to this JSON as you’d like but this is a basic example.

Inside a <script> tag in your document

$(window).ready(function() {
  // JSON
  var data = JSON.parse('[{"address":"New Street, Salisbury, UK","content":"hello world from salisbury","status":"live"},{"address":"86000 Poitiers, France","content":"hello world from poitiers"},{"address":"66000 Perpignam, France","content":"hello world from perpignam"}]');
});

To follow the same Gmap3 examples route that you’d normally find online, I am going to set some defaults which will include the opening centre of the map.

$(window).ready(function() {
  // JSON
  var data = JSON.parse('[{"address":"New Street, Salisbury, UK","content":"hello world from salisbury","status":"live"},{"address":"86000 Poitiers, France","content":"hello world from poitiers"},{"address":"66000 Perpignam, France","content":"hello world from perpignam"}]');
 
  var $map = $('.gmap');
 
  // Gmap Defaults
  $map.gmap3({
    map:{
        options:{
            center:[46.578498,2.457275],
            zoom: 5
        }
    }
  });
});

The next part of the code will loop through the JSON and output the markers. It will also bind a click event to each marker which will spawn an overlay for it.

$(window).ready(function() {
  // JSON
  var data = JSON.parse('[{"address":"New Street, Salisbury, UK","content":"hello world from salisbury","status":"live"},{"address":"86000 Poitiers, France","content":"hello world from poitiers"},{"address":"66000 Perpignam, France","content":"hello world from perpignam"}]');
 
  var $map = $('.gmap');
 
  // Gmap Defaults
  $map.gmap3({
    map:{
        options:{
            center:[46.578498,2.457275],
            zoom: 5
        }
    }
  });
 
  // Json Loop
  $.each(data, function(key, val) {
      $map.gmap3({
          marker:{
              values:[{
                  address:val.address,
                  events: {
                      click: function() {
 
                          gmap_clear_markers();
 
                          $(this).gmap3({
                              overlay:{
                                  address:val.address,
                                  options:{
                                      content:  '<div class="infobox">'+val.content+'</div>',
                                      offset:{
                                          y:-32,
                                          x:12
                                      }
                                  }
                              }
                          });
                      }
                  }
              }]
          }
      });
  });
});

Let’s break this bit down a moment. Basically we are looping through each of the JSON rows and for each row we are adding a new marker based on the address key. Moving down the code, we have an ‘events’ binding which we have included a ‘click’ event that once clicked will spawn an overlay which contains the content from our JSON key ‘content’ and is wrapped around an infobox div that we can style using CSS. Another parametre we set here is the offset which is the X/Y position of the box in relation to the marker.

One thing I’ve not yet mentioned is the gmap_clear_markers() function that is called inside the click event. Since there are no default bindings for clearing the overlays (unlike InfoBoxes or InfoWindows) we need to take care of this ourselves otherwise the user can open more than 1 overlay at a time. We need to add this function to our script.

$(window).ready(function() {
  // JSON
  var data = JSON.parse('[{"address":"New Street, Salisbury, UK","content":"hello world from salisbury","status":"live"},{"address":"86000 Poitiers, France","content":"hello world from poitiers"},{"address":"66000 Perpignam, France","content":"hello world from perpignam"}]');
 
  var $map = $('.gmap');
 
  // Gmap Defaults
  $map.gmap3({
    map:{
        options:{
            center:[46.578498,2.457275],
            zoom: 5
        }
    }
  });
 
  // Json Loop
  $.each(data, function(key, val) {
      $map.gmap3({
          marker:{
              values:[{
                  address:val.address,
                  events: {
                      click: function() {
 
                          gmap_clear_markers();
 
                          $(this).gmap3({
                              overlay:{
                                  address:val.address,
                                  options:{
                                      content:  '<div class="infobox">'+val.content+'</div>',
                                      offset:{
                                          y:-32,
                                          x:12
                                      }
                                  }
                              }
                          });
                      }
                  }
              }]
          }
      });
  });
});
 
// Function Clear Markers
function gmap_clear_markers() {
    $('.infobox').each(function() {
        $(this).remove();
    });
}

Now when an overlay is visible and a non-related marker is clicked, the other overlay will disappear.

Enhancing this map

Unfortunately, by using this method there are a few things that Google Maps will do by default that this will not do, so we will need to add these ourselves. Let’s make sure that the centre point changes when we click on our markers. You can add 3 objects to the click event. marker, event and context

The event object contains the coordinates matched by the address in your JSON. When the marker is clicked on, this can now be our centre point.

Add the following to your script

$(window).ready(function() {
  // JSON
  var data = JSON.parse('[{"address":"New Street, Salisbury, UK","content":"hello world from salisbury","status":"live"},{"address":"86000 Poitiers, France","content":"hello world from poitiers"},{"address":"66000 Perpignam, France","content":"hello world from perpignam"}]');
 
  var $map = $('.gmap');
 
  // Gmap Defaults
  $map.gmap3({
    map:{
        options:{
            center:[46.578498,2.457275],
            zoom: 5
        }
    }
  });
 
  // Json Loop
  $.each(data, function(key, val) {
      $map.gmap3({
          marker:{
              values:[{
                  address:val.address,
                  events: {
 
                      // NEW SCOPE
                      click: function(marker, event, context) {
 
                          // ADD THIS
                          $map.gmap3({
                            map:{
                              options:{
                                center:event.latLng
                              }
                            }
                          });
 
                          gmap_clear_markers();
 
                          $(this).gmap3({
                              overlay:{
                                  address:val.address,
                                  options:{
                                      content:  '<div class="infobox">'+val.content+'</div>',
                                      offset:{
                                          y:-32,
                                          x:12
                                      }
                                  }
                              }
                          });
                      }
                  }
              }]
          }
      });
  });
});
 
// Function Clear Markers
function gmap_clear_markers() {
    $('.infobox').each(function() {
        $(this).remove();
    });
}

Obviously there is loads more you can do with this if you study the Gmap3 documentation. But this should be enough to get started. This method helped me a great deal in some bespoke Google Maps work I’ve been undertaking, and I hope this helps someone else too.

View the Demo

About 

I run a small web development agency in Salisbury, UK. We provide both front-end/back end solutions and infrastructure management. My specific role is to identify the needs of our clients and providing an online solution that is easy to administer, secure, scalable and maintainable.

 

My agency website is white-fire.co.uk. Contact us if you need a consultant.

Published inJavaScript

One Comment

  1. COOL

    How would you insert a diferent icon imagem in eatch marker? and you dont have the close box icon.

    Sorry my bad inglish. I’m from portugal 😀

Leave a Reply

Your email address will not be published. Required fields are marked *