Tuesday, January 6, 2015

Google Map PI v3 with Jquery Mobile

Using Google Maps JavaScript API v3 with jQuery Mobile

 Jul 18, 2013
First let us talk about how Gmap v3 API can be used inside a classic web application, it will give us a good perspective when we switch back to jQuery Mobile. In the beginning of a map craze iframe was a standard delivery solution but as a time went by it become an outdated technology, more like an obstacle them a successful delivery technology.

 
The new JavaScript Maps API Version 3 was built from the ground up by Google to offer a clean, fast and powerful maps application development platform for both desktop Web browsers and mobile devices. The v3 API lets developers embed Google Maps in their own Web pages and is specially designed to be faster and more applicable to mobile devices, as well as traditional desktop browser applications, according to Google.
 
Unlike v2 API which worked on IE6+, Firefox 2.0+, older versions of Chrome v3 API will work on every HTML5 supported browser ranging from IE8+, Firefox 3.0 + up to iOS, Android and BlackBerry 6+ browsers. Which makes it an excellent solution for jQuery Mobile applications. But let me first show you how it works in a classic web page.
 

Classic solution


 
 
Working jsFiddle example can be found here: http://jsfiddle.net/Gajotres/T4H5X/
 
As you can see it is an extremely easy solution. It uses vanilla javascript to initialize and display the map. Map is created from numerous canvas elements and it is fully responsive.
 
<!DOCTYPE html>  <html>      <head>          <title>Google Maps JavaScript API v3 Example: Map Simple</title>          <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>          <meta charset="utf-8"/>          <style>              html, body, #map_canvas {              margin: 0;              padding: 0;              height: 100%;              }          </style>          <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>          <script>              var map;              function initialize() {              var mapOptions = {              zoom: 8,              center: new google.maps.LatLng(-34.397, 150.644),              mapTypeId: google.maps.MapTypeId.ROADMAP              };              map = new google.maps.Map(document.getElementById('map_canvas'),              mapOptions);              }                            google.maps.event.addDomListener(window, 'load', initialize);          </script>      </head>      <body>          <div id="map_canvas"></div>      </body>  </html>  
 
Map container can be dynamically changed and a map will automatically resize to fill new available space.
 

jQuery Mobile solution


 
 
Combine jQuery Mobile and v3 API and everything becomes a little bit complicated. Unlike classic web development jQuery Mobile, pages are responsive by its nature which means page dimensions will become a problem here. During the jQuery Mobile page initialization page is constantly changing and resizing. Basically page height can be successfully calculated only during the pageshow event.
 
For those who still don't have much experience with jQuery Mobile pageshow event is a last state to be called during the page initialization. It best jQuery counterpoint would be window ready. That means in order to successfully initialize v3 API we must do it after pages has been displayed which brakes its usefulness.
 
 
As always there's a solution to every problem. If we have a good idea how our page is going to look we can force content div to resize according to available space even before pageshow event. This can be done with this CSS rules:
 
#content {      padding: 0;      position : absolute !important;       top : 40px !important;        right : 0;       bottom : 40px !important;        left : 0 !important;       }  
 
This CSS will remove classic content padding and absolutely position content div to cover all available space, giving only some space to page header. Bottom rule can be a changed to 40px in case footer is also needed.
 
Working jsFiddle example can be found here: http://jsfiddle.net/Gajotres/7kGdE/
 
 
 


<!DOCTYPE html>  <html>      <head>          <title>jQM Complex Demo</title>          <meta name="viewport" content="initial-scale=1, maximum-scale=1"/>          <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />          <style>              #content {                  padding: 0;                  position : absolute !important;                   top : 40px !important;                    right : 0;                   bottom : 40px !important;                    left : 0 !important;                   }          </style>          <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>              <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>             <script>  		$(document).on('pageinit', '#index',function(e,data){      		   var minZoomLevel = 12;    		   var map = new google.maps.Map(document.getElementById('map_canvas'), {  			  zoom: minZoomLevel,  			  center: new google.maps.LatLng(38.50, -90.50),  			  mapTypeId: google.maps.MapTypeId.ROADMAP  		   });                  });          </script>       </head>      <body>          <div data-role="page" id="index">              <div data-theme="a" data-role="header">                  <h3>                      First Page                  </h3>              </div>                            <div data-role="content" id="content">                  <div id="map_canvas" style="height:100%"></div>              </div>                            <div data-theme="a" data-role="footer" data-position="fixed">                  <h3>                      First Page                  </h3>              </div>          </div>      </body>  </html>      
 

Second jQuery Mobile solution


 
 
Unfortunately, a first solution will not be useful every time. Sometimes we will not know our page dimensions or what will be available space for our content div, this is where jQuery comes to help.
 
Here's a nifty function that will calculate available content height. It can be then used to dynamically set new content height. That combined with window resize event will give you best responsiveness.
 
function getRealContentHeight() {  	var header = $.mobile.activePage.find("div[data-role='header']:visible");  	var footer = $.mobile.activePage.find("div[data-role='footer']:visible");  	var content = $.mobile.activePage.find("div[data-role='content']:visible:visible");  	var viewport_height = $(window).height();    	var content_height = viewport_height - header.outerHeight() - footer.outerHeight();  	if((content.outerHeight() - header.outerHeight() - footer.outerHeight()) <= viewport_height) {  		content_height -= (content.outerHeight() - content.height());  	}   	return content_height;  }  
 
And here's also a working jsFiddle example: http://jsfiddle.net/Gajotres/xbr2v/

No comments:

Post a Comment