jQuery and Google Maps Tutorial: #1 Basics
There are many times I want to leverage jQuery's strengths to create a custom Google Maps mashup. In this tutorial, I will walk you through how to get started using jQuery inside the Google Maps environment. I will assume nothing, and explain each piece in detail.
If you are already familiar with Google Maps API, skip to step #5, or so.
Step #1: Get API key
First, grab yourself an API key for Google Maps, you will need this in the next step.
Step #2: Load Google Maps and jQuery
We want to load up jQuery and Google Maps with the Google AJAX Libraries API.
JavaScript:
<script type="text/javascript" src="http://www.google.com/jsapi?key=YOUR_API_KEY_HERE"> <script type="text/javascript" charset="utf-8"> google.load("maps", "2.x"); google.load("jquery", "1.3.1"); </script>
Make sure to replace YOUR_API_KEY_HERE with your API key. By using the Google AJAX Libraries API, it allows you to load the JavaScript libraries you need right from Google's servers. This increases the chance that your users will be able to load the scripts faster from their browser cache, as well as shuffle the jQuery script loading off your server.
Step #3: Create the Google Map

To create our Google Map, we need to create a container div and use CSS to give it a width and a height.
HTML:
<div id="map"></div>
Css:
<style media="screen" type="text/css"> #map { width:500px; height:500px; } </style>
Use the GMap2 function to make a map instance. Then, set the center of the map. I wrapped this code block in jQuery's document ready function so that the code is run after the page has loaded.
JavaScript:
$(document).ready(function(){ var map = new GMap2(document.getElementById('map')); var burnsvilleMN = new GLatLng(44.797916,-93.278046); map.setCenter(burnsvilleMN, 8); });
Here, I used Burnsville, MN's latitude and longitude because it is where I live right now. There are many ways to get the latitude and longitude of an address, like this simple service by iTouchMap.
The second parameter for setCenter is the zoom level, which is a number. I set the zoom level to "8" here because it is about in the middle.
At this point we should have a simple map.
Step #4: Load the Google Maps Example

To have some points to work with, let's paste in the google maps example.
JavaScript:
// setup 10 random points var bounds = map.getBounds(); var southWest = bounds.getSouthWest(); var northEast = bounds.getNorthEast(); var lngSpan = northEast.lng() - southWest.lng(); var latSpan = northEast.lat() - southWest.lat(); var markers = []; for (var i = 0; i < 10; i++) { var point = new GLatLng(southWest.lat() + latSpan * Math.random(), southWest.lng() + lngSpan * Math.random()); marker = new GMarker(point); map.addOverlay(marker); markers[i] = marker; }
Note that I added a markers array to the example code. This will be used in the next step.
Step #5: Loop Through Markers and Add Basic Click Event to Markers
In this step, we start to use jQuery and Google Maps together. We want to be careful to use Google Map's built-in API as much as possible, leaving jQuery only for what it is best at.
Let's take that array of markers and loop through them with jQuery's each method.
JavaScript:
$(markers).each(function(i,marker){ GEvent.addListener(marker, "click", function(){ map.panTo(marker.getLatLng()); }); });
Inside the loop, let's use Google Maps's GEvent namespace to attach a click event to each marker. Then, we will add a panTo behavior to center the map on the marker. marker.getLatLng(); returns the latitude and longitude of the marker, while map.panTo(GLatLng) allows us to center the map on that latitude and longitude.
Step #6 - Make a Clickable List of Markers
Let's add a clickable list next to the map. Insert a ul.
HTML:
<ul id="list"></ul>
Then let's style it up a bit by floating the map left and float our list element next to it. We also want to add a hover effect to the list items to give visual feedback to the user that they can click on each item in the list.
Css:
<style type="text/css" media="screen"> #map { float:left; width:500px; height:500px; } #list { float:left; width:200px; background:#eee; list-style:none; padding:0; } #list li { padding:10px; } #list li:hover { background:#555; color:#fff; cursor:pointer; cursor:hand; } </style>
In our jQuery each loop from last step, let's append the clickable list items to the list.
") .html("Point "+i) .click(function(){ map.panTo(marker.getLatLng()); }) .appendTo("#list");JavaScript:
$("<li />") .html("Point "+i) .click(function(){ map.panTo(marker.getLatLng()); }) .appendTo("#list");
Here I am just setting the content to "Point (the count)", adding that same panTo action from before, then appending the list item to our list.
Step #7 - Add a Custom Message

When I create a Google Maps mashup, I usually want to replace the built-in info window with something custom. With jQuery, we can add any arbitrary HTML in place of the info window. This is great when you want complete control over what the info window looks like.
Add a message div with some test text.
HTML:
<div id="message" style="display:none;"> Test text. </div>
Then add some basic styling to the message.
Css:
#message { position:absolute; padding:10px; background:#555; color:#fff; width:75px; }
We have to place the message div inside the map. To do this, we can use jQuery to append it to an object. The map view is seperated into panes. Each pane is a div layered on top of the other. To get the div object that we want to attach our message div to, we can use map.getPane(PANE). The G_MAP_FLOAT_SHADOW_PANE is the layer that I find works best for attaching custom messages.
JavaScript:
$("#message").appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE));
To show the message div in place of the info window, we need to separate the click action into a separate function. Replace the map.panTo(marker.getLatLng(); with displayPoint(marker, i);, a call to the new displayPoint function shown below.
JavaScript:
function displayPoint(marker, i){ map.panTo(marker.getPoint()); var markerOffset = map.fromLatLngToDivPixel(marker.getPoint()); $("#message").show().css({ top:markerOffset.y, left:markerOffset.x }); }
We put the panTo action in our new function. Then the magic function here is the map.fromLatLngToDivPixel(GLatLng); which converts the latitude/longitude of the marker into a pixel on the map div. This returns a object containing x (amount of pixels from the left of the map) and y (amount of pixels from the top of the map).
Final Step #8 - Add Some Spice
To finish up, we will add an event when the map stops panning. We can do this by attaching the "movend" event map object. This way, after panning to the marker you've clicked on we can use jQuery's fadeIn method to add some spice.
JavaScript:
function displayPoint(marker, index){ $("#message").hide(); var moveEnd = GEvent.addListener(map, "moveend", function(){ var markerOffset = map.fromLatLngToDivPixel(marker.getLatLng()); $("#message") .fadeIn() .css({ top:markerOffset.y, left:markerOffset.x }); GEvent.removeListener(moveEnd); }); map.panTo(marker.getLatLng()); }
There you have it. We've come a long ways by adding our own custom click event, a clickable list and a custom info window. In the next tutorial, I'll show you how to store and retrieve points with a server-side language.
Comments
I noticed that you use document.getElementById() in your example, but you can also do this via the jQuery $() function. This is how I solve this:
var map = new google.maps.Map2($("#map").get(0));
Don't forget to append the .get(0)!
How would I go about having the map zoom in closer when a user clicks on a location? I've tried a bunch of things and nothing seems to work. It keeps the default zoom.
Thanks
map.setZoom(number);sets the zoom of the map.Pretty sure you'll like it.
http://www.youtube.com/watch?v=I9TtDecveCE
You can see it in action at www.erikwhite.net/gmapjquery.html
Note: I haven't tested it in anything besides Firefox 3 yet so there could be some cross-browser issues
It now uses an array to store the locations which means you can add data such as labels and text for the markers. When the page loads, it cycles through the array and shows each array item in sequence. If you add more items to the array it will speed up so you don't have to sit and wait for too long. It also allows you to toggle markers which doesn't work in your version and shows an active state when you click on a marker or a list item.
A picture, for example.
Thanks.
Good job on everything,I like everything you are doing.
Thanks for sharing.
Great tutorial! Thanks especially for introducing me to an easy way to recreate the infoWindow.
I am having trouble, however, with loading content from PHP/MySQL into the infoWindow and then acting upon that content with jQuery... I can get the content there, but can't get the jQuery working. I think it comes down to the event handling, but I am really not sure. A lot of people on the Google Maps list seem to be having similar trouble...
My point is: I think a lot of folks could use a tutorial on this issue (myself included) and you are obviously a good teacher, so how about it?
Thanks again for the great tutorial!
i can combine between your gmapJquery with Drag&drop Jquery
here is the script
//asumption this is the MAP Script----
//and this is drag&drop script
$(function() {
// there's the gallery and the cart
var $gallery = $('.kiri')//, $cart = $('#cart');
// let the gallery items be draggable
$('#compare').draggable({
cancel: 'a.ui-icon',// clicking an icon won't initiate dragging
revert: 'invalid', // when not dropped, the item will revert back to its initial position
containment: $('#demo-frame').length ? '#demo-frame' : 'document', // stick to demo-frame if present
helper: 'clone',
cursor: 'move'
});
if i see in firebug, it say " $("#compare").draggable is not a function "
can anyone help me??
I do have one question though. with the moveend event listener, what happens if you were to have one point and its set as the center. The map doesn't move then and therefore the listener is never triggered, any thoughts on how to get around that?
Once question though, although google allows you to load up jQuery form their server, I can still use my own on my server correct? Obviously I'll try myself, but figured I'd ask as well.
Thanks for the great resource!
Rob
The code shows the usage of latitude and longitude?
Thanks
I want to be able to just provide an address.. unless there is a way to automatically (via php?) get the latitude and longitude values of a given addres..
Thanks a lot,
Mark.
You can try it at http://erikwhite.net/gmapjquery.html
My code builds on Marc's code by adding:
-Cycling of markers on load
-Linking marker click activity to list highlighting
-Improved toggling behaviour for markers and list items
-Loading marker locations from an array which also stores marker labels and extra information
-Dynamically calculating the cycle time between markers, depending on the total number of markers
You can see another example here (this site isn't quite finished yet):
http://southamptonspitfires.co.uk/media/venues
First: This is by far the best jquery / Gmap tutorial ever :D
But i have a problem, i am building a restaurantsite where you can choose areas in Stockholm and all restaurants within a chosen category and area will be displayed on the map.
The problem is the $("#message").appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE));
The message-DIV it does not appear when i do a second search on the page, only the first time.
Im not even sure where to start debugging :( is this some kind of memory leakage ?
I would really appreciate if you have some advice to this problem
Here is a link to the beta page of the map:
http://testwebb.restaurangbloggen.se/Restaurangkartan.aspx
just choose anything from the drop down menus, first round will display the #message on the map
but the second time you do a search with the drop down menu the #message does not appear anymore
//Kim
$("#message").show()takes care of your problem.cheers mate =)
just got home from work checked everywhere on page, im not sure it is because it is display none
Since
$("#message").fadeIn().css({ top: markerOffset.y, left: markerOffset.x });
should show the #message div, the weird thing is that it does work the first round but not the second round when i do a new search.
Might there be some kind of DOM object i have to clear/empty?
I have built on your tutorial and tweaked it to display marker points between 2 points. I use KML data from Google Maps and then parse it to display the markers.
http://www.sandboxm.com/jquery-and-google-maps/
The final demo is here: http://www.sandboxm.com/examples/DirectionsGmapJQuery.html
Thanks once again!
M
I arrive your page when I Google with this keyword combinations "showing google maps in jquery".
Your page is at the first. I get the right place. :)
Your tutorial save me (as well as all others).
Thanks again.
http://code.google.com/apis/maps/articles/customicons.html
If so it would be great!
Before you create your marker, create an icon. Then in the "new GMarker" add the icon you just created...
var icon = new GIcon();
icon.image = "http://www.mysite.com/images/marker_icon.png";
icon.iconSize = new GSize(45, 48);
icon.iconAnchor = new GPoint(8, 42);
icon.infoWindowAnchor = new GPoint(43, 6);
var marker = new GMarker(point, icon);
^^^^
That's all there is to it. You can also create a separate shadow image as an attribute of the icon.
Hope that helps.
Thanks
Paul
Also Suzy I found this great for generating markers
http://www.powerhut.co.uk/googlemaps/custom_markers.php
First off thanks. This is great.
I was wondering if anybody has added zoom-in / zoom-out to this push button navigation? I'm going to be working with a large custom map and was curious there's a way include a zoom out from current point, then pan normally at the higher elevation; then zoom in to the new point. A pull-out/push in sort of thing.
Granted this is tile intensive but....suggestions?
Brilliant tutorial thanks, really well written and easy to follow! Now I'm going to go and get an API key to have a play!
Thanks,
Tom
Brilliant tutorial , really well written and easy to follow! Now I'm going to go and get an API key to have a play!
Thanks Marc Grabanski,
chandler
I need something to ask about the pane options. You are using G_MAP_FLOAT_SHADOW_PANE as a default pane in your tutorial. In my case, I should create form inside info window (which is using your method, in this tutorial), since I need the info window appear on top of all layer (to make the click/focus events work on my form) so I change pane option to G_MAP_FLOAT_PANE because that's the highest layer AFAIK.
When we click the map, the map should create a new marker (done and no problem) and the info window that contains the form is open. But when I try to click a button or fill the form, the info window didn't react anything to my event and the map added a new marker instead of react to the form event.
Do you have any suggestion about this, and sorry could not give you a code because the code running on my local and a little bit bulk to copy paste in here :)
Thanks in advance Marc
Thanks.
That's what I was looking for.
Thank you very much
Did you find some improvements with API v3 ? I still need v2 for some project like own map layer integration and switching to euclidian projection. Will be interesting to adapt this article with API v3. yes ? Thank's anyway for sharing.
First of all thanks for the great tutorial.
I managed to put everything working just as i want in all browsers but not in IE 6/7/... versions.
When cliclink in the marks nothing happens. The script stops and i don't know hot to debug using IE.
Please check it here:
http://www.amena.tcpnsa.com/Amena/Localizacao
or here:
http://www.amena.tcpnsa.com/Associados-e-Profissionais
Any help would be appreciated.
Thanks in advance. And again ... congratulations on the great job you have done!
noel
Cheers!
Coz as we know in the standart GMaps api openInfoWindowHTML, javascript is not allowed.
i want to create map like this
http://aredesforgirls.com.br/ ( Click on the "localizao" Button )
Hope you 'll find it.
Thanks with regards
Yash Mistrey
keep the good working flowing!
Kim - and anyone else who is wondering why the message doesn't appear when you click the marker a second time - it's because the function assigned to var moveEnd is attached to the GMaps "moveEnd" event, and this event only fires if the map actually has to pan. The second time you click the marker the map doesn't have to mover anywhere, so the message is not faded in.
You can fix this by removing these lines from the finished code:
var moveEnd = GEvent.addListener(map, "moveend", function(){
...[leave the content here!]...
GEvent.removeListener(moveEnd);
});
The downside is that the message will appear before the map finishes panning to the marker location - but if you move the line
map.panTo(marker.getLatLng());
to the top of the displayPoint function then this is barely noticeable.
Is there any way of making a clickable link inside #message? I have tried, but when there is a marker under it, it selects this instead of the link
thanks
Keep posting!
<!--
<div class="map" address="1050 Massachusetts Ave, Cambridge, MA 02138-5359"></div>
<div class="map" address="380 Cross Creek Drive, Huntingtown, MD 20639"></div>
<script language="Javascript" type="text/javascript">
$(document).ready(function(){
function drawMap(result, map) {
if (result.Status.code == G_GEO_SUCCESS) {
var geocode = result.Placemark[0].Point.coordinates;
var center = new GLatLng(geocode[1], geocode[0]);
map.setCenter(center, 9);
map.addOverlay(new GMarker(center));
}
}
var geo = new GClientGeocoder();
$('.map').each(
function(n, elm) {
var map = new GMap2($(elm).get(0));
geo.getLocations($(elm).attr('address'), function(result) {drawMap(result, map)});
}
);
});
</script>
-->