jQuery Mobile with Google Maps
Introduction
jQuery Mobile is an HTML-5 user interface framework for smartphones and mobile devices. Having recently developed NZQuake using Grails, I wanted to see how rapidly a mobile version of the application could be created without rolling a native iOS or Android application. At this point in time, I’m willing to forgo the benefits of native applications on mobile devices for the sake of simplicity and meeting self-imposed deadlines.
Given that a key feature of NZQuake is integration with Google Maps v3 and QuakeML it was essential that the mobile version of the application also offered this functionality. I decided that there would be a list view and details view for earthquake related information to convey the information as succinctly as possible. This article focuses on the details view which contains the Google Map and provides JavaScript and CSS code to render a Google Map using jQuery Mobile.
Visit the live NZQuake Mobile site at http://m.nzquake.co.nz to see the code from this article working in action.
CSS Code
The following is contained in mobile.css
html, body {
font-size: .9em;
font-family: Arial, Helvetica, Sans-serif;
background: #666666;
padding: 0px;
}
.details-page {
width: 100%;
height: 100%;
}
#map_content {
padding: 0px;
width: 100%;
height: 100%;
overflow: hidden;
}
#map_canvas {
width: 100%;
height: 100%;
padding: 0;
text-shadow: none;
}
The map_canvas div and the containing map_content div must use 100% of the screen height and width. Due to the fact that jQuery Mobile uses text shadow for fonts, I have deliberately removed the text shadow from the map_canvas to enhance readability for text rendered on the map. Specifying overflow: hidden; ensures that no scrollbars are drawn in the viewport.
JavaScript Code
The following is contained in mobile.js
/*!
NZQuake (c) Copyright Greg Smith
*/
var map;
function createQuakeEventMarker(quakeEventLatlng) {
return new google.maps.Marker({position: quakeEventLatlng, map: map});
}
function setupMap(lat, lng, mapZoom, showOverviewControl) {
var mapLatlng = new google.maps.LatLng(lat, lng);
var myOptions = {
zoom: mapZoom,
center: mapLatlng,
overviewMapControl: showOverviewControl,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL,
position: google.maps.ControlPosition.LEFT_TOP
},
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
The zoom control is configured to use small icons that will fit within the viewport of a mobile device.
HTML Markup
The HMTL code for the detail page is vanilla markup with a few attributes specific to jQuery Mobile. Items of significance have been highlighted and explained in more detail.
<!DOCTYPE html>
<html>
<head>
<title>Details | ComDynamics NZQuake</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" />
<link rel="stylesheet" href="/nzquake/css/mobile.css" />
<meta name="layout" content="mobile"/>
</head>
<body>
<div id="details" data-role="page" class="details-page">
<div data-role="header" data-theme="a">
<h3>NZQuake Details</h3>
<a href="/nzquake/history" data-icon="home" data-iconpos="notext" data-direction="reverse" class="ui-btn-right jqm-home" data-ajax="false">Home</a>
</div>
<div data-role="content" id="map_content" data-theme="a">
<div id="map_content">
<div id="map_canvas"></div>
</div>
</div>
</div>
<script type="text/javascript" src="/nzquake/js/mobile.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
<script type="text/javascript">
function initialize() {
setupMap(-43.60132, 172.11984, 11, true);
var quakeEventLatlng = new google.maps.LatLng(-43.601, 172.12);
var marker = createQuakeEventMarker(quakeEventLatlng)
marker.setAnimation(google.maps.Animation.DROP)
}
// Initialize the map when the jQuery Mobile pageshow event is triggered
$('.details-page').live("pageshow", function() {
if (map == null) {
initialize();
}
});
</script>
</body>
</html>
Line 13 specifies that the page class is called “details-page” which allows the binding of the jQuery Mobile pageshow event to the details page.
Line 41 is the jQuery Mobile handler triggered for a pageshow event.
Important: Due to the way jQuery Mobile injects values into the DOM tree, line 16 has uses data-ajax="false" for navigating back to the list view. The navigation link from the list view to the details view also uses data-ajax="false" to ensure the map initialization JavaScript function is called when the pageshow event is triggered. The implications of this are that jQuery Mobile page transitions are not used when navigating between pages however this ensures the map is correctly drawn each time the page is loaded.
Screenshot
On an iPhone 4 the page renders showing map zoom controls positioned on the top left as specified in the JavaScript code. The map is fully scrollable within the viewport.
Conclusion
When using a RAD full-stack web framework like Grails or Rails, it is possible to develop a Google Maps and jQuery Mobile site with minimal effort for use on a variety of smartphones and mobile devices. Visit the live NZQuake Mobile site at http://m.nzquake.co.nz to see the code from this article working in action.
NZQuake Beta Release
After considerable effort and numerous late nights using limited spare time I have completed development of NZQuake and deployed a beta version of the application to production. NZQuake was built to satisfy an urge for learning a new full-stack application framework – Grails – and act as a technology proof of concept for future projects.
The application presents earthquake related information in a clear and concise manner by combining QuakeML with Google Maps. It is primarily informative and, as a resident of Christchurch, New Zealand, has provided me with a creative output for dealing with the stresses of living through a series of unprecedented earthquakes and aftershocks which began with the magnitude 7.1 earthquake on September 4th in 2010, shortly followed by the deadly magnitude 6.3 earthquake on February 22nd 2011.
The learnings taken from this project will be documented in a series of posts looking at the various technologies in the application stack.
Regards,
Greg








