It's pretty common to embed a map on a contact page. But you want this map only on this page. So you don't need to load the Google Map API on every page of your site
Coupled with adress microdata (which you should already have in place), it becomes easy to load a google map on demand with a marker to the desired address.
1. Load Google Map
To load google map is simple. Just call in the URL of the Ajax API. But we must ensure proper load and execute the following script when it's completly loaded. Otherwise, you call functions that doesn't exist on the page.
A simple callback on the load of the script isn't sufficient because Google actually loads an other JS file, corresponding to the current Google Map API version.
I you readSi the doc, you understand you can add a callback that will be called by the APi once loaded
We'll write a function to load this JS file and add a callback given as a parameter. A small addition will permit to load it only one time.
var gmapUrl = 'http://maps.google.com/maps/api/js?sensor=false', gmapLoaded = false, loadGmap = function(clb) { if (!gmapLoaded) { window.gMapClb = function() { window.gMapClb = null; gmapLoaded = true; clb(); }; $.ajax({url: gmapUrl+'&callback=gMapClb', dataType: 'script'}); } else { clb(); } };
We can now dynamically load the Google Map API and execute a function when everything has come up.
2. Read microdata
The purpose of the code we're writing is to be called on a container, find Address microdata and display the corresponding map.
Once the address is found, we will use geocode from Googme Map to locate the map and add a marker.
Reading microdata is pretty easy thanks to jQuery. We're adding every element in an array:
var adr = me.find('[itemtype="http://data-vocabulary.org/Address"]'); if (adr.length) { var search = [], elm; $.each(['street-address', 'postal-code', 'locality', 'region', 'country-name'], function() { elm = adr.find('[itemprop="'+this+'"]'); if (elm.length) search.push(elm.text()); }); }
Once the address is on the search Array, it only remains to call the geocoder to find its location.
3. Locate address and show the map
We've got the address. We can load the Google Map API on demand with a callback. We still have to find the address location. And if we have it, show the map. To search it, I won't discuss here all the details of Geocoder.
When getting a result from geocoder, a div[class=map] is append to the containing element and the Google Map instance will be created on it. It's the CSS duty to positionnate this div and giving it a height and width.
To allow a toffle of this map, we will save a reference of the map container, a reference of the Google map and the location of the result. A marker is automaticall added at the result location.
loadGmap(function() { var geocoder = new google.maps.Geocoder(); geocoder.geocode({address: search.join(', ')}, function(results, status) { if (results.length && status == google.maps.GeocoderStatus.OK) { var map = $('<div class="map" />').appendTo(me), GMap = new google.maps.Map(map.get(0), { center: results[0].geometry.location, mapTypeId: google.maps.MapTypeId.ROADMAP, zoom: defaultZoom }); new google.maps.Marker({ map: GMap, visible: true, position: results[0].geometry.location }) me.data('gmap', { map: map, GMap: GMap, location: results[0].geometry.location }); } }); });
Note the defaultZoom variable defined elsewhere. (required to create a map)
4. Put it all together
We have the 3 necessary elements to view the map. Let's put that in a jQuery plugin, add functionnality to hide/show it on each call of this plugin and we get this:
$(function() { var defaultZoom = 15, gmapUrl = 'http://maps.google.com/maps/api/js?sensor=false', gmapLoaded = false, loadGmap = function(clb) { if (!gmapLoaded) { window.gMapClb = function() { window.gMapClb = null; gmapLoaded = true; clb(); }; $.ajax({url: gmapUrl+'&callback=gMapClb', dataType: 'script'}); } else clb(); }; $.fn.extend({ myGmap: function() { return this.each(function() { var me = $(this); if (!me.data('gmap')) { var adr = me.find('[itemtype="http://data-vocabulary.org/Address"]'); if (adr.length) { var search = [], elm; $.each(['street-address', 'postal-code', 'locality', 'region', 'country-name'], function() { elm = adr.find('[itemprop="'+this+'"]'); if (elm.length) search.push(elm.text()); }); if (search.length) { loadGmap(function() { var geocoder = new google.maps.Geocoder(); geocoder.geocode({address: search.join(', ')}, function(results, status) { if (results.length && status == google.maps.GeocoderStatus.OK) { var map = $('<div class="map" />').appendTo(me), GMap = new google.maps.Map(map.get(0), { center: results[0].geometry.location, mapTypeId: google.maps.MapTypeId.ROADMAP, zoom: defaultZoom }); new google.maps.Marker({ map: GMap, visible: true, position: results[0].geometry.location }) me.data('gmap', { map: map, GMap: GMap, location: results[0].geometry.location }); } }); }); } } } else { me.data('gmap').map.fadeToggle(function() { if (me.data('gmap').map.is(':not(:visible)')) { me.data('gmap').GMap.setZoom(defaultZoom); me.data('gmap').GMap.panTo(me.data('gmap').location); } }); } }); } }); });
When the map is hidden, the map is centered again and the default zoom is resset to the default value.
Enjoy!
Comments.
No comments for the moment.
Add a comment.