31.01.2011

Advanced Google Maps Integration

Dieses Beispiel zeigt, wie sich Google Maps in das Kontakt, Firmen- und Lead-Formular integrieren lässt um die Route vom Benutzer zum Kunden anzuzeigen.

Umgebung:
Microsoft Dynamics CRM 2011 RC
(vanilla/Out-Of-The-Box)

Deployment:
onpremise

Achtung:
In CRM Online funktioniert das ganze leider nicht. Das Problem ist, den Internet Explorer dazu zubringen, einen iFrame mit HTTP-Content in einer Webseite mit HTTPS-Content anzuzeigen. Google Maps ist leider nicht über HTTPS verfügbar.


Grundlagen:

Anforderungen:
  • auf den Formularen von Firma, Kontakt und Lead soll jeweils eine neue Bereich "Navigation Map" eingeblendet werden
  • in diesem neuen Formularbereich soll ein iFrame mit Google Maps angezeigt werden
  • es wird automatische die Route vom aktuellen Benutzer zum Kunden angezeigt
  • sollte beim aktuellen Benutzer keine Adresse hinterlegt sein, wird die Adresse der BU herangezogen
  • sollte auch hier keine Adresse gefunden werden, wird die Kundenadresse als Standord angezeigt
  • die Karte auf dem Formular wir eingebettet dargestellt
  • am Formular-Ribbon soll ein Button "Map" angefügt werden
  • dieser öffnet die jeweilige Route bzw. den Standort in einem neuen Fenster mit "Google-Map-Controls"

#1: Lösung erstellen und Entitäten hinzufügen
Der neuen Lösung "Google Maps Navigation" werden die Entitäten Account, Contact und Lead hinzugefügt.

#2: Icons hinzufügen
Der Lösung werden zwei Icons als Web Resource hinzugefügt.

GoogleMapsNavigationIcon16.png





GoogleMapsNavigationIcon32.png






#3: JavaScript-Bibliothek hinzufügen
Der Lösung wird die Datei "navmaplib.js" als Web Resource mit folgendem Inhalt hinzugefügt:

var fromAddress;
var isEmbedded = true;

function formLoad() {   
    retrieveCrmObject("SystemUser", Xrm.Page.context.getUserId());
   
}

function retrieveCrmObject(entityName, entityId)
{
    // Build REST Endpoint
    var url = Xrm.Page.context.getServerUrl()
            + "/xrmservices/2011/organizationdata.svc/"
            + entityName + "Set(guid'" + entityId + "')";

    // Create CRM Request
    var request = new XMLHttpRequest();
    request.open("GET", url, true);
    request.setRequestHeader("Accept", "application/json");
    request.setRequestHeader("Content-Type",
                             "application/json; charset=utf-8");
    request.onreadystatechange = function () {
        if (request.readyState == 4) {
            if (request.status == 200) {
                var crmObject = eval('(' + request.responseText + ')').d;
                fromAddressRetrieved(crmObject);
            }
        }
    }

    // Send Crm Request
    request.send();
}

function fromAddressRetrieved(crmObject) {
    fromAddress = "";
    if (typeof (crmObject.SystemUserId) != "undefined") {
        if (crmObject.Address1_Line1 != null) {
            fromAddress = crmObject.Address1_Line1;
            fromAddress += addAddressItem(crmObject.Address1_PostalCode);
            fromAddress += addAddressItem(crmObject.Address1_City);
            fromAddress += addAddressItem(crmObject.Address1_Country);
           
            loadMap();
        }

       
        if (fromAddress == "") {
            retrieveCrmObject("BusinessUnit", crmObject.BusinessUnitId.Id);
        }       
    }
    else {
        if (crmObject.Address1_Line1 != null) {
            fromAddress = crmObject.Address1_Line1;
            fromAddress += addAddressItem(crmObject.Address1_PostalCode);
            fromAddress += addAddressItem(crmObject.Address1_City);
            fromAddress += addAddressItem(crmObject.Address1_Country);                    }
    }
    loadMap();
}

function addAddressItem(crmAttribute)
{
    if(crmAttribute != null)
        return "," + crmAttribute;
    else return "";
}

function loadMap() {
    var url = getUrl();
    var embedded = "";
    if(isEmbedded)
        embedded = "&output=embed";
    if (url != "") {
        // Set iFrame source to google maps url
        Xrm.Page.ui.controls.get("IFRAME_navigationmap").setSrc(url + embedded);
    }
    else {
        Xrm.Page.ui.controls.get("IFRAME_navigationmap").setSrc("about:blank");
    }
}

function getUrl() {
    // Get address data from form
    var toAddress = "";
    if (Xrm.Page.getAttribute("address1_line1").getValue() != null) {
        toAddress = Xrm.Page.getAttribute("address1_line1").getValue();
        toAddress += addAddressItem(Xrm.Page.getAttribute("address1_postalcode").getValue());
        toAddress += addAddressItem(Xrm.Page.getAttribute("address1_city").getValue());
        toAddress += addAddressItem(Xrm.Page.getAttribute("address1_country").getValue());
    }
   
    // Build google maps url   
    var url = "";
    if (toAddress != "") {
        if (fromAddress == "") {
            url = "http://maps.google.de/maps?q=" + toAddress;
        }
        else {
            url = "http://maps.google.de/maps?q=from: " + fromAddress + " to:" + toAddress;
        }
    }

    return url;
}

function openMap() {
    var url = getUrl();
    if(url != "") {
         window.open(url, "mywindow", "width=800,height=600,resizable=Yes");
    }
    else
    {
        alert("No Addresses found.");
    }
   
}
 
#4: JavaScript-Bibliothek im Formular registrieren
In den Formularen von Firma, Kontakt und Lead ist die JavaScript-Bibliothek sowie die Funktion "buttonClick" im "OnLoad"-Ereignis zu registrieren.

4.1 JavaScript-Bibliothek und -Funktion im Formular registrieren


#5: Button-XML (RibbonDiffXml) in die Lösung einfügen
Dieses Arbeitspaket wurde detailliert in der Post "Simple Form-Button w/ JavaScript-Function" beschrieben.
Folgende Änderungen werden zusätzlich gemacht:
  • der neue XML-Knoten wird jeweils einmal in den Entities account, contact und lead hinterlegt
  • die Namender Web Resourcen werden angepasst
  • der FunctionName wird auf "openMap" gesetzt
--
:: Links / Weiterführende Information:

4 Kommentare:

  1. Hallo Danke für den tollen Beitrag!
    Ich möchte geren in einem iFrame Buttons für neue Aktivitäten Platzieren wie muss ich wohl die Linkaufrufe starten.? O:-)

    AntwortenLöschen
  2. Ich verstehe die Frage leider nicht ganz. Was sind genau die Anforderungen von dem, was Du machen möchtest?

    AntwortenLöschen
    Antworten
    1. Hallo,
      Ich habe eine erweiterte Ansicht von Kontakten. In einem iFrame lasse ich mir alle Aktivitäten mit diesem Kontakt anzeigen.
      Jetzt möchte ich im iFrame Buttons für neu anzulegende Aktivitäten implementieren. Im Prenzip sind es die gleichen Buttons die auch im Menü-Band unter Hinzufügen sind. Das Problem ist das es keine Klassischen HTML Links sind () dann Könnte man ja den href nach bauen.

      Löschen
    2. Es gibt doch bereit einen Hinzufügen-Button für Aktivitäten - warum sollte man einen Zweiten implementieren?
      Falls man dennoch einen Button benötigt, der einen Datensatz via JavaScript im CRM erzeugt, gibt es hier ein gutes Beispiel:

      http://garethtuckercrm.com/2011/02/15/creating-crm-records-from-
      jscript-in-2011using-the-rest-end-point/

      Löschen