As we all know Microsoft Dynamics CRM by default is
integrated with Bing Maps. We can add Bing maps on any entity we want. We
can enable or disable the feature in the Settings > Administration > System
Settings area.
This post shows you how to integrate Google maps API
with Dynamics CRM. Here we will integrate Google maps in Account entity form using
HTML web resource and we create a Dashboard where we will show all the accounts
of CRM on Google Map.
Before you start, you need Google Map API key to proceed
further.
Getting an API key is
not complicated and just requires a couple of minutes of your time. In the
process, you will need to create a billing account or use credentials of
already existing one, which will be used for payment, in case you exceed your
limits. This link will guide you on how to get Google Maps API key in 3 easy steps.
I assume you have basic Dynamics CRM and JavaScript
knowledge to perform below guided steps.
Step 1: In order to integrate Google Maps, first we create a
HTML web resource.
Code snippets:
<html> <head> <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initialize" defer="" async=""></script> <script> function initialize() { var map_canvas = document.getElementById('map_canvas'); var map_options = { center: new google.maps.LatLng(54.737686, 2.126855), zoom: 4, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(map_canvas, map_options) var geocoder = new google.maps.Geocoder(); var address = window.parent.Xrm.Page.data.entity.attributes.get('address1_composite').getValue(); var googleLocation = window.parent.Xrm.Page.data.entity.attributes.get('new_googlelocation').getValue(); var addressChanged = window.parent.Xrm.Page.data.entity.attributes.get('address1_composite').getIsDirty() ; var name = window.parent.Xrm.Page.data.entity.attributes.get('name').getValue(); var contentString = '<div><strong>' + name + '</strong><br>' + address + '<br></div>'; geocoder.geocode( { 'address': address}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { if(googleLocation == null){ var latitude = results[0].geometry.location.lat(); var longitude = results[0].geometry.location.lng(); var loc = latitude + ',' + longitude; window.parent.Xrm.Page.getAttribute("new_googlelocation").setValue(loc); window.parent.Xrm.Page.data.entity.save(); } map.setCenter(results[0].geometry.location); map.setZoom(14); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location, title: address }); var infowindow = new google.maps.InfoWindow({ content:contentString }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); } else { //alert("Geocode was not successful for the following reason: " + status); } }); } google.maps.event.addDomListener(window, 'load', initialize); </script> <meta charset="utf-8"><meta><meta><meta> </head> <body style="overflow-wrap: break-word;" dir="LTR" onfocusout="parent.setEmailRange();" lang="en-US"> <div id="map_canvas" style="width: 100%; height: 100%;"></div> </body> </html>
Understanding the code:
In the code below, the script loads the API from the specified URL.the callback parameter executes the initialize function after the API loads. The async attribute allow the browser to continue rendering the rest of your page while the API loads. The key parameter contains your API key.
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initialize" defer="" async=""></script>
The code contains in the initialize function that initializes and adds the map when the web page loads. The code below constructs a new Google maps object, and adds properties to the map including the center and zoom level. As I am working for one of the client from United Kingdom, so I choose latitude and longitude location of UK.
var map_options = { center: new google.maps.LatLng(54.737686, 2.126855), zoom: 4, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(map_canvas, map_options)
Next, we will retrieve composite address of an account record and then using Geocoding we will find out geographic coordinates. Geocoding is the process of converting addresses into geographic coordinates, which can be used to place markers on a map, or position the map.
Using Geocoding we will get the latitude and longitude for address of an Account record, we will save this details in another custom field called "new_googlelocation" which is of single line of text. This field value will be useful for us to put marker on Dashboard's map.
var googleLocation = window.parent.Xrm.Page.data.entity.attributes.get('new_googlelocation').getValue(); var addressChanged = window.parent.Xrm.Page.data.entity.attributes.get('address1_composite').getIsDirty(); if(googleLocation == null){ var latitude = results[0].geometry.location.lat(); var longitude = results[0].geometry.location.lng(); var loc = latitude + ',' + longitude; window.parent.Xrm.Page.getAttribute("new_googlelocation").setValue(loc); window.parent.Xrm.Page.data.entity.save(); }
And using an InfoWindow method we will show location on google map. An InfoWindow displays content in a popup window above the map, at a given location.
geocoder.geocode( { 'address': address}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { if(googleLocation == null){ var latitude = results[0].geometry.location.lat(); var longitude = results[0].geometry.location.lng(); var loc = latitude + ',' + longitude; window.parent.Xrm.Page.getAttribute("new_googlelocation").setValue(loc); window.parent.Xrm.Page.data.entity.save(); } map.setCenter(results[0].geometry.location); map.setZoom(14); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location, title: address }); var infowindow = new google.maps.InfoWindow({ content:contentString }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); } else { //alert("Geocode was not successful for the following reason: " + status); } });
Step 2: Next, we need to add google map on Account form.
Step 3: We have integrated google maps with our Dynamics environment, next we need to show all the accounts on Dashboard using Google Map. For this, we will create another html web-resource for dashboard.
Code snippets:
<html> <head> <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY;callback=initMap" defer="" async=""></script> <script type="text/javascript"> function initMap() { var map; var bounds = new google.maps.LatLngBounds(); var mapOptions = { center: new google.maps.LatLng(54.5260, 15.2551), zoom: 4, mapTypeId: google.maps.MapTypeId.ROADMAP }; // Display a google map on the web page map = new google.maps.Map(document.getElementById("mapCanvas"), mapOptions); map.setTilt(50); //Show multiple location markers on the google map var infoPopupWindow = new google.maps.InfoWindow(), marker, i; var req = new XMLHttpRequest(); req.open("GET", parent.Xrm.Page.context.getClientUrl() + "/api/data/v9.1/accounts?$select=name,address1_composite,new_googlelocation&$filter=_ownerid_value eq 106E5F09-48CC-4BF0-BF21-FD7C074991F8", false); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("Prefer", "odata.include-annotations=\"OData.Community.Display.V1.FormattedValue\""); req.setRequestHeader("Prefer", "odata.maxpagesize=10"); req.onreadystatechange = function () { if (this.readyState === 4) { req.onreadystatechange = null; if (this.status === 200) { var results = JSON.parse(this.response); for (var i = 0; i < results.value.length; i++) { var address = ""; var name = ""; var contentString =""; var location = ""; var latitude = ""; var longitude = ""; address = results.value[i]["address1_composite"]; name = results.value[i]["name"]; location = results.value[i]["new_googlelocation"]; latitude = location.substring(0, location.indexOf(",")).trim(); longitude = location.substring(location.indexOf(",")+1, location.len).trim(); if(address != null && name != null){ contentString = '<div><strong>' + name + '</strong><br>' + address + '<br></div>'; } var position = new google.maps.LatLng(latitude, longitude); bounds.extend(position); marker = new google.maps.Marker({ position: position, map: map, title: name }); //Attach click event to the marker. (function (marker, contentString) { google.maps.event.addListener(marker, "click", function (e) { //Wrap the content inside an HTML DIV in order to set height and width of InfoWindow. infoPopupWindow.setContent(contentString); infoPopupWindow.open(map, marker); }); })(marker, contentString); //Fitting Automatically center the screen map.fitBounds(bounds); } // Customize google map zoom level once fitBounds run var boundsListener = google.maps.event.addListener((map), '', function(event) { this.setZoom(4); google.maps.event.removeListener(boundsListener); }); } else { alert(this.statusText); } } }; req.send(); } google.maps.event.addDomListener(window, 'load', initMap); </script> <meta><meta> </head> <body style="overflow-wrap: break-word;" onfocusout="parent.setEmailRange();"> <div id="mapCanvas" style="width: 100%; height: 100%;"></div> </body> </html>
Understanding the code:
We will retrieve all the active account records from organization and using for loop we will mark the geographic location on the map and attach click event to each marker InfoWindow, so that on click of each marker on map it will show Account Name and Address of an account in InfoWindow.
Step 4: Final step, we will create dashboard and add HTML web-resource created for Dashboard.
Alright, we have completed all the customization, its time to see changes on Dashboard.
Hope it helps someone, Cheers !! Happy Learning..
No comments:
Post a Comment