Tuesday, 7 August 2012

Extending Google Maps' InfoWindow

Google Maps' InfoWindow...

... is good, in that you don't really need to do any extra work to get a popup to appear on a map.

But, What happens when you want to customize it? - sure, you can put whatever content you like inside the infowindow, but your stuck with the standard white box with trail arrow.. you know the one..



yeah.. that one!

I came across a very handy plugin the other day, the InfoBox plugin.

This plugin replaces the default InfoWindow object in google maps, but crucially, allows you to specify the complete HTML that makes up your popup window.

To use the infobox plug, download a copy of the source, and reference in your page:

 <script src="/path/to/infobox.js" type="text/javascript"></script>  

Then, in your code, create an instance of this object:

 var ib = new InfoBox();  

You can then call that in place of the regular infoWindow.open()

 ib.open(theMap, marker);  

however, the power of this control comes with the options. Have a check over the API Reference for the full details.

with the InfoBox options, you can

Here's a snapshot of the example from the InfoBox site:

     var myOptions = {  
          content: boxText 
         ,boxClass : 'infoBoxClass' 
         ,disableAutoPan: false  
         ,maxWidth: 0  
         ,pixelOffset: new google.maps.Size(-140, 0)  
         ,zIndex: null  
         ,boxStyle: {   
          background: "url('tipbox.gif') no-repeat"  
          ,opacity: 0.75  
          ,width: "280px"  
          }  
         ,closeBoxMargin: "10px 2px 2px 2px"  
         ,closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif"  
         ,infoBoxClearance: new google.maps.Size(1, 1)  
         ,isHidden: false  
         ,pane: "floatPane"  
         ,enableEventPropagation: false  
     };  

The main ones you want to look at are the 'content', and infoBoxClearence.

the "content" option specifies the actual HTML content that will be displayed in the popup.
Define your HTML markup inside your script, and then point it to the "content" element.

Here, I've taken the example from the API examples page:

     var marker = new google.maps.Marker({  
      map: theMap,  
      draggable: true,  
      position: new google.maps.LatLng(49.47216, -123.76307),  
      visible: true  
     });  
     var boxText = document.createElement("div");  
     boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: yellow; padding: 5px;";  
     boxText.innerHTML = "City Hall, Sechelt<br>British Columbia<br>Canada";  
     var myOptions = {  
          content: boxText  
         ,disableAutoPan: false  
         ,maxWidth: 0  
         ,pixelOffset: new google.maps.Size(-140, 0)  
         ,zIndex: null  
         ,boxStyle: {   
          background: "url('tipbox.gif') no-repeat"  
          ,opacity: 0.75  
          ,width: "280px"  
          }  
         ,closeBoxMargin: "10px 2px 2px 2px"  
         ,closeBoxURL: "http://www.google.com/intl/en_us/mapfiles/close.gif"  
         ,infoBoxClearance: new google.maps.Size(1, 1)  
         ,isHidden: false  
         ,pane: "floatPane"  
         ,enableEventPropagation: false  
     };  
     var ib = new InfoBox(myOptions);  
     ib.open(theMap, marker);  

 You can see that 'boxText' variable contains HTML elements. This is what is output to your infobox.
One thing to bear in mind, is that the HTML you provide here, will be wrapped inside of a <div> element.
If you do not specify a 'boxClass' option, then the default will be ".infoBox". Of course, specify your own if you like.

This means that you can style both the outter element, and the inner content as you please.

So, with some custom CSS, you can make rather fetching (or at least, different to the standard infowindow)





Footnote: 

Writing out your markup directly in javascript like above, can be tedious. Especially if you want to put a large amount of content into said infobox.

A better alternative to this is to use Templating. One plugin we've used recently is Handlebars. Go check it out. It makes working with HTML inside of javascript/jquery much much easier

No comments:

Post a Comment