Duncan's blog

October 8, 2011

Google Maps API – infowindows

So previously I showed how to create a basic map, then how to add markers to it. Now suppose you’re wanting to have one of those little bubbles pop up when you click on your map with some information in it. These are called infowindows in Google’s terminology.

Let’s start with the very basics – creating a map which has an infowindow already visible on it.

function initialize() {
	var homeLatlng = new google.maps.LatLng(51.476706,0);

	var myOptions = {
		zoom: 15,
		center: homeLatlng,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};

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

	var infowindow =  new google.maps.InfoWindow({
		content: 'Hello World!',
		map: map,
		position: homeLatlng
	});
}

google.maps.event.addDomListener(window, 'load', initialize);

So we create an infowindow, specify some content for it and which map it’s for, and give it a latlong position (which coincidentally also happens to be where I’ve specified this map is to be centered, although that doesn’t have to be the case). The documentation says that “After constructing an InfoWindow, you must call open to display it on the map“; however I find the above code will open the infowindow without needing to explicitly call the open function.

But this shows the infowindow immediately. Perhaps you’d rather it only appeared after some user interaction. Typically you’d put markers on the map, and when the user clicks the marker, then you’d show the infowindow.

So let’s create the infowindow slightly differently. This time, don’t specify the position attribute. Then create a marker as normal, and finally we can open the infowindow, and we pass the marker as the second parameter. So the infowindow gets anchored to the marker’s position.

var infowindow =  new google.maps.InfoWindow({
	content: 'Hello World!',
	map: map
});

var marker = new google.maps.Marker({
	position: homeLatlng, 
	map: map
});

infowindow.open(map, marker);

So we’ve now added a marker to the map, which the infowindow is then anchored to.

You probably only want this to happen after the user has clicked on that marker. For that we need to have an event listener function. There are many of these available for all the different map elements, in this case we want to listen to the mouseclick event on that marker.

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

So we say to the Google Maps event handler framework, on the marker, listen for any ‘click’ events. And when that happens, call this anonymous function which currently only has one line, to open the marker.

We could also make this infowindow appear in response to other events, e.g. if you simply hovered the mouse over the marker.

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

And then to make the infowindow disappear again when you move the mouse away from the marker, just call the close() function on mouseout.

google.maps.event.addListener(marker, 'mouseout', function() {
	infowindow.close();
});

Suppose you had several markers on your map, each of which would have its own infowindow. Here’s one way to deal with that. Firstly have an array of everything you need for each marker, arrDestinations. Then loop over them, adding a marker for each. We only have one infowindow variable, and we just update the content for it in response to user clicks. We need to delegate the event handler to an external function, bindInfoWindow, otherwise you end up just getting the content of the last array item for each marker.

<script type="text/javascript">
function initialize() {
	var i;
	var arrDestinations = [
		{
			lat: 50.815155, 
			lon: -0.137072, 
			title: "Brighton Pier", 
			description: "Brighton Palace Pier dates to 1899"
		},
		{
			lat: 50.822638, 
			lon: -0.137361, 
			title: "Brighton Pavilion", 
			description: "The Pavilion was built for the Prince of Wales in 1787"
		},
		{
			lat: 50.821226, 
			lon: -0.139372, 
			title: "English's", 
			description: "English's Seafood Restaurant and Oyster Bar"
		}
	];
	
	var myOptions = {
		zoom: 15,
		center: new google.maps.LatLng(50.820645,-0.137376),
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	
	var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
	
	var infowindow =  new google.maps.InfoWindow({
		content: ''
	});
	
	// loop over our array
	for (i = 0; i < arrDestinations.length; i++) {
		// create a marker
		var marker = new google.maps.Marker({
			title: arrDestinations[i].title,
			position: new google.maps.LatLng(arrDestinations[i].lat, arrDestinations[i].lon),
			map: map
		});
		
		// add an event listener for this marker
		bindInfoWindow(marker, map, infowindow, "<p>" + arrDestinations[i].description + "</p>");  
	}
}

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

google.maps.event.addDomListener(window, 'load', initialize);
</script>

In production you’d probably use a server-side language to populate the array and just pass it into the initialize function. There are other ways of doing this as well. Another approach is to have multiple infowindows, one for each marker. On click, you close any open infowindows, and then just open the one that corresponds to the current marker. I don’t believe that approach is as efficient as my example though.

14 Comments »

  1. Nice post. Somewhat related- I’m trying to write script where the user clicks on the map, and an infowindow pops up in that location containing information about that place, say the county it belongs to. (Though for starters, I’d settle for an empty infowindow). I’ve tried about 18 different ways so far, with no luck.

    Frank B.
    New York

    Comment by Frank B. — November 3, 2011 @ 5:36 pm | Reply

  2. @Frank, I’ve written up a new post which might help you: https://duncan99.wordpress.com/2011/11/04/google-maps-api-adding-infowindows-in-response-to-user-clicks/ Let me know if that does/doesn’t help.

    Comment by duncan — November 4, 2011 @ 8:02 am | Reply

  3. […] response to my previous post about adding infowindows with the Google Maps API, Frank B asked if it was possible “to write a script where the user clicks on the map, and an […]

    Pingback by Google Maps API – adding infowindows in response to user clicks « Duncan’s blog — November 4, 2011 @ 1:58 pm | Reply

  4. How can I add a link to the description?

    Comment by Gabby — October 12, 2012 @ 7:24 pm | Reply

  5. @Gabby, not sure I understand your comment. What description?

    Comment by duncan — October 12, 2012 @ 9:14 pm | Reply

  6. I’m not sure but I would say ‘Gabby’ means creating a link in the infowindow. I would take a guess at just creating one using html…

    Anyway, I have a quick question.
    My infowindow doesn’t have rounded edges, do I need to apply a border radius or is it due to different browsers? I’m using, FF 16.0.1

    Comment by Allan — October 23, 2012 @ 10:49 am | Reply

  7. My apologies, I did not get notification of a reply.

    I do mean to put a link inside of the infowindow. I need each infowindow to have text, a link and an image. I tried to just add a regular tag, however it does not work, it breaks the whole map.

    Comment by Gabby — October 25, 2012 @ 4:22 pm | Reply

  8. That shouldn’t cause an error, unless something about your HTML is breaking the javascript. Can you paste some code? Alternatively try asking on stackoverflow…

    Comment by duncan — October 25, 2012 @ 5:01 pm | Reply

    • Thanks for getting back to me, I will also post on StackOverflow, but here is my code:

      var arrDestinations = [
      {
      lat: 26.603356,
      lon: -81.80823,
      title: “Salon #1”,
      description: “LineLine 2Line 3line 4”

      },

      When I try to put an code inside the description, it kills the whole map. Inside of dreamweaver when I type out the code, after I get to the colon in the URL the rest of the line turns grey. I am totally new to javascript & google API, so any help is appreciated!

      Comment by Gabby — October 25, 2012 @ 6:18 pm | Reply

  9. It’s possibly the / in the http:// that’s breaking your JS. You might need to escape them. Instead of http://www.example.com/folder/ try:
    http:\/\/www.example.com\/folder\/

    Comment by duncan — October 25, 2012 @ 9:13 pm | Reply

  10. […] now we’ve created a map, added markers and infowindows. Maybe you want to start drawing lines and shapes on […]

    Pingback by Google Maps API – polylines « Duncan’s blog — February 12, 2013 @ 6:44 pm | Reply

  11. GREAT Tutorial and was just what I was looking for! Even the Pingbacks were relevant!

    Comment by Tom — October 17, 2013 @ 4:01 pm | Reply

  12. What a lovely and useful piece of article. At work we are implementing a custom app relaying on Google maps and we needed to show the InfoWindow for every custom marker created on the map. Thank you.

    Comment by SEO Guatemala — July 13, 2018 @ 10:39 pm | Reply


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.