Google Maps Display Template – SharePoint 2013 – Part 2

5 minute read

As described in my previous post we will be creating a display template for Google maps. When you did not have the change to read part 1 you can do this by using the below link:

Google Maps Display Template – SharePoint 2013 – Part 1 

In part one we created the item display template and because we could not insert the JavaScript of adding markers to the map in the display template we have inserted the information in hidden inputs.

First of there is 1 important thing to notice. If you would like to use Google maps on you page you have to add a JavaScript file on you page. Within display control template you can use a specific method called “$includeScript();”. This method will include the script to the page for you. But there is a catch for as far as I could investigate if your JavaScript file doesn’t end  with “.js” it will not be included on the page. The Google maps API is a file that does not end with “.js”. The only option you have is to add the Google API file by using a script editor.

Embed Code Toolbar

Embed code

<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>

In the control template we will begin by reading out that information and placing them on the map.

To get a new control template you will need to copy an existing control template, for this example we will create a copy of the “Control_List.html” and rename it to “Control_GoogleMaps.html”.

On each hidden input we have specified an id in order to retrieve the values, the id consist of a text value and the number of the result. In the Control Display Template we can retrieve the number of the result by using the “ctx” object and the property “CurrentItemIdx”. Each marker will become an Item in the “markers” array and will be a array itself. In the iteration we also construct the information window for each marker.

var markers = new Array();

for(var i=0;i<=ctx.CurrentItemIdx;i++){
    var inputValue = document.getElementById(i+'-Location').value
    var itemArray = inputValue.split(";");

     var contentString = '<div style="height:100px;" id="content">'+ 
     '<b>' + itemArray[0] + '</b>'+
     '<hr><div id="bodyDescription" style="margin-top:2px;">'+ itemArray[3] + '</div>' +
     '<div id="bodyAddress" style="margin-top:2px;">'+ itemArray[4] + '</div>' +
     '<a href="'+ itemArray[5] + '"><div style="font-weight:bold;margin-top:5px;">Office Information</div></a></div>';

     itemArray[3] = contentString;
     markers[i] = itemArray;             
}

When we have the information of the markers we can start by placing the markers on the map. For more information on how to use the Google Maps API go here.

var mapOptions = {
     zoom: 4,
     mapTypeId: google.maps.MapTypeId.HYBRID
}

var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var bounds = new google.maps.LatLngBounds();

var infowindow = new google.maps.InfoWindow(), marker, i;
for (i = 0; i < markers.length; i++) {  
    
    var title = markers[i][0];
    var latitude = markers[i][1];
    var longitude = markers[i][2];
    var pointLatlng = new google.maps.LatLng(latitude,longitude);
    bounds.extend(pointLatlng);
        
    marker = new google.maps.Marker({
                position: pointLatlng ,
                map: map,
                title:title,
                icon:'/PublishingImages/point.png'
    });
    
    google.maps.event.addListener(marker, 'click', (function(marker, i) {
      return function() {
        infowindow.setContent(markers[i][3]);
        infowindow.open(map, marker);
      }
    })(marker, i));
}

map.fitBounds(bounds);

By saving each point within a LatLngBounds object in the example above the bounds object we can specify on the map that it has to load all point within the first view by using the method “map.fitBounds(bounds)”. 

When tying this all together you will get a control display template like below:

<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"> 
<head>
<title>Google Maps</title>

<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
<mso:MasterPageDescription msdt:dt="string">This is the default Maps Display Template that will show a map with all of the items. For this map you should have managed properties with the longtitude and latitude of locations. Also make sure you reference the google map api: (https://maps.googleapis.com/maps/api/js?v=3.exp)</mso:MasterPageDescription>
<mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106601</mso:ContentTypeId>
<mso:TargetControlType msdt:dt="string">;#Content Web Parts;#</mso:TargetControlType>
<mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
</mso:CustomDocumentProperties>
</xml><![endif]-->
</head>

<body>
    
    <script>
        $includeLanguageScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");
    </script>

    <div id="Control_List">
    <!--#_ 
    if (!$isNull(ctx.ClientControl) && !$isNull(ctx.ClientControl.shouldRenderControl) && !ctx.ClientControl.shouldRenderControl()){
        return "";
    }

    ctx.ListDataJSONGroupsKey = "ResultTables";
    var $noResults = Srch.ContentBySearch.getControlTemplateEncodedNoResultsMessage(ctx.ClientControl);
    var noResultsClassName = "ms-srch-result-noResults";
    _#-->
    
         _#= ctx.RenderGroups(ctx) =#_
        
    <!--#_

    function initialize() {

          var mapOptions = {
                zoom: 4,
              mapTypeId: google.maps.MapTypeId.HYBRID
          }

          var markers = new Array();
          var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
          var bounds = new google.maps.LatLngBounds();

          for(var i=0;i<=ctx.CurrentItemIdx;i++){
              var inputValue = document.getElementById(i+'-Location').value
              var itemArray = inputValue.split(";");

              var contentString = '<div style="height:100px;" id="content">'+ 
                 '<b>' + itemArray[0] + '</b>'+
                 '<hr><div id="bodyDescription" style="margin-top:2px;">'+ itemArray[3] + '</div>' +
                 '<div id="bodyAddress" style="margin-top:2px;">'+ itemArray[4] + '</div>' +
                 '<a href="'+ itemArray[5] + '"><div style="font-weight:bold;margin-top:5px;">Office Information</div></a></div>';

            itemArray[3] = contentString;
            markers[i] = itemArray;             
          }
    
          var infowindow = new google.maps.InfoWindow(), marker, i;
    
          for (i = 0; i < markers.length; i++) {  

               var title = markers[i][0];
               var latitude = markers[i][1];
               var longitude = markers[i][2];
               var pointLatlng = new google.maps.LatLng(latitude,longitude);
               bounds.extend(pointLatlng);
        
               marker = new google.maps.Marker({
                  position: pointLatlng ,
                  map: map,
                  title:title,
                  icon:'/PublishingImages/point.png'
               });