One of the neat things about mobile things is that almost all of them have some sort of awareness of their location. If there isn’t a GPS type receiver in the device itself, it can usually get a pretty good approximation of where it is using WiFi signals. So, besides the basic customer address info, I also want to display a map on the screen showing the location of the customer. I also want to be able to use the Google Maps driving direction service to compute the directions to the customer from where the user of the app is currently.
First of all, lets get the address of the customer on the screen. This is very easy with XPages and a few <xp:text> tags.
Adding Google Maps is also pretty easy. First we need to get the JS library.
<xp:script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?sensor=true" clientSide="true">
</xp:script>
Next we add a <xp:panel> in our page where we want the map to be placed. I’m also using the style attribute to tell it how big it should be.
<xp:panel id="mapCanvas" style="margin-right:20px;width: 100%; height: 360px;"> </xp:panel>
While I’m here I’ve also added a button that will get the driving directions. I’ll wire that up later.
<a href="#" data-icon="forward" data-role="button">Directions</a>
Oh, AND a button so I the user can call the customers main number:
<a href="tel:#{thisDoc.fctlPhone_WB}" data-icon="grid" data-role="button">Call</a>
Notice the href in the ‘Call’ button. By placing the prefix ‘tel:’ in front on the number I can make use of any handlers the device has for dealing with telephone numbers. On a phone, this will open the dialer. On a tablet, depending on what is installed, it may open an app like Skype.
To finish up the Google Maps bit, I need to add two JavaScript functions to the page. For simplicity sake, I am just adding this to the current page, but later I’ll move them into a .js file of their own. These functions will go into an <xp:scriptBlock> tag:
<xp:scriptBlock>
<xp:this.value escape="false">
var geocoder;
var map;
/*
First connect the google map to the panel we added
*/
function loadMap(){
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(42.559958,-70.887071);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("view:mapCanvas"), myOptions);
codeAddress();
}
/*
Using the cusomter address, ask google what the Latitude and
Longitude coordinates are so we can add a marker.
*/
function codeAddress() {
var address = '#{document1.faddLocation_SS}';
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
}
else{
alert("error getting map data");
}
});
}
/*
Use the JQuery Mobile even 'pageshow' to trigger the map to load
*/
$("#details").live('pageshow',function(event, ui){
loadMap();
});
</xp:this.value>
</xp:scriptBlock>
This script block contains 2 functions: loadMap() and codeAddress() plus wiring up an event handler to trigger the map to load when the page is displayed. So let me sum up what is going on in the JavaScript….
loadMap
This function is pretty simple. It will be the first function that gets called so it does all the setup. First it creates a ‘geocoder’ which handles the look up of an address and converts it to a set of coordinates. Then it creates a default location (which is set to be the Teamstudio Corporate Headquarters). Next are some of the options for the map itself. Then the map object is created and the id of the element where we want the map displayed is passed in. In our case this is ‘view:mapCanvas’.
The ‘view’ is just the way XPages decorates all the id’s. To figure out what your’s is going to be just look at the source of your page in a browser.
Lastly it calls ‘codeAddress’ to figure out where the customer is located.
codeAddress
This function is also pretty simple. First it get the address we are going to look up from the document object. It then passes that to the geocoder object along with a function that gets called with the result. Inside the function, of the status parameter is google.maps.GeocoderStatus.OK we create a marker on the map with the results of the look up. There is actually a lot of data that can be returned, but all we really care about right now is the location.
‘pageshow’
Finally we have the event handler for ‘pageshow’. If you have used $(document).ready() a lot. In JQM because almost all pages are loaded via AJAX, the ‘document’ is only loaded once and bits of the DOM are replaced with new parts as you navigate around. The JQM framework however, has page events that you can hook that accomplish the same kind of thing. You can read more about it here, but the basics are that you hook the ‘pageshow’ event for the div a particular id and with the role data-role=’page’. In this example the div we care about has the id of ‘details’.
So there you have it. Once all this gets wired up the end result is this: