21.11.2010

Retrieve CRM data in Form Events

Nachdem ich unter CRM 4 gerade erst XmlHttpRequest gebändigt hatte um in Form Events Daten aus dem CRM auslesen zu können, zeigt eine kurze Recherche im neuen SDK, dass bei CRM 2011 alles wieder ganz anders ist.

REST? JSON? WTF? Zum Glück konnte Google mich hier schnell auf den neusten Stand aktueller Webtechnologien bringen. REST ist so eine Art Mini-Internet auf einer Datenbank und mit JSON kann man JavaScript Objekte in einen String serialisieren/deserialisieren um das ganz über HTTP durch die Gegend zu schicken.

Mit diesem neu erworbenen Wissen wollte ich nun via JavaScript im OnLoad Event (Kontakt-Formular) einen Datenssatz auslesen und einige Datenfelder zur Anzeige bringen. Für diese Beispiel soll die Adresse des Besitzer in einer Alert-Box angezeigt werden.

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

Deployment:
onpremise

#1: Herausgeber und Lösung erstellen
Um das Beispiel exportieren zu können und die Anpassungen vom CRM Standard getrennt zu halten, sollte man zuerst einen Herausgeber und eine Lösung im CRM anlegen.


1.1 Erstellen eines neuen Herausgebers


2.1 Erstellen einer neuen Lösung

#2: Kontakt-Entität hinzufügen
Der eben erstellten Lösung fügen wir nun die (bereits existierende) Entität "Kontakt" hinzu. Dadurch werden der Lösung auch noch die Entitäten "Price List" und "Service" hinzugefügt.


2.1 Neue Lösung mit Kontakt-Entität

#3: JavaScript Bibliothek erstellen
Da der Aufruf des REST Webservice asynchron erfolgt, benötigen wir diesmal zwei Funktionen: eine, die im OnLoad Event aufgerufen wird und den Request absetzt und eine, die die Daten verarbeitet, wenn diese im Client angekommen sind.

In einer dritten Funktion habe ich versucht die eigentlichen Funktionalität zu kapseln. Allerdings fehlt eine Fehlerbehandlung noch komplett.

Folgenden Quelltext benötigen wir in einer Datei:

function retrieveOwnerAddress()
{
    // Get Owner Guid from Form
    var ownerId = Xrm.Page.getAttribute("ownerid").getValue()[0].id;


    // Retrieve Owner data
    retrieveCrmObject("SystemUser", ownerId);
}


function output(crmObject)
{
    alert
    (
        "Name: " + crmObject.FullName + "\n" +
        "Address: " + crmObject.Address1_Line1 + "\n" +
        "ZIP: " + crmObject.Address1_PostalCode + "\n" +
        "City: " + crmObject.Address1_City + "\n" +
        "Country: " + crmObject.Address1_Country
    );
}


///////////////////////////////////////////////
/*                                           */
/*              GENERIC                      */
/*                                           */
///////////////////////////////////////////////

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;
                output(crmObject);
            }
        }
    }


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


#4: JavaScript Bibliothek bereitstellen
Diese Datei fügen wir der in Schritt #1 erstellten Lösung als neue Web Resource hinzu.

4.1 Die JavaScript Bbliothek als neue Web Resource der Solution hinzufügen

#5: JavaScript Bibliothek aktivieren
Nun müssen wir nur noch unsere JavaScript Bibliothek aus den Schritten #3 und #4 auf dem Kontakt-Formular im OnLoad Ereignis aktivieren. Dazu öffnen wir im Bearbeitungmodus (Kontakt Formular) die "Form Properties" und fügen unsere Bibliothek den Formular Bibliotheken hinzu.

5.1 Retrieve Owner JS-Bibliothek den Formular Bibliotheken hinzufügen

Jetzt erstellen wir einen Event Handler, der die Funktion retrieveOwnerAddress beim OnLoad des Formulars ausführt.

5.2 Event Handler, der retrieveOwnerAddress im OnLoad ausführt
#6: Anpassungen veröffentlichen
Abschließend müssen wir unsere Solution bzw. die gemachten Anpassungen noch veröffentlichen.

6.1 Solution/Anpassungen veröffentlichen

#7: Ergebnis überprüfen
 Öffnet man nun einen Kontakt, wird die Adresse des Besitzers in einer Alert-Box angezeigt.

6.1 Adresse des Besitzers wird in Alert-Box angezeigt

Damit das ganze überhaupt funktioniert müssen die Felder Street 1, City, ZIP/Postalcode, Country/Region der Mailing Address vom entsprechenden Benutzer natürlich gefüllt sein.
6.2 Benutzer mit gefüllten Adress-Feldern
--
:: Links / Weiterführende Informationen:

19.11.2010

Simple Google Maps Integration

Dieses Beispiel zeigt, wie sich Google Maps auf einfache Weise in das Kontakt-Formular integrieren lässt.



Umgebung:
Microsoft Dynamics CRM 2011 Beta
(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.

#1: Herausgeber und Lösung erstellen
Um die Funktionalität exportieren zu können und die Anpassungen vom CRM Standard getrennt zu halten, sollte man zuerst einen Herausgeber und eine Lösung im CRM anlegen.

1.1 Erstellen eines neuen Herausgebers

1.2 Erstellen einer neuen Lösung
#2: iFrame auf dem Formular einfügen
Der eben erstellten Lösung fügen wir nun die (bereits existierende) Entität "Kontakt" hinzu. Dadurch werden der Lösung auch noch die Entitäten "Price List" und "Service" hinzugefügt. Dem Kontakt-Formular spendieren wir einen neuen Registerkarte inklusiv iFrame.
2.1 Auf dem Kontakt Formular ein neues iFrame einfügen - unter "Formatting" kann man optional noch die "Number of Rows" erhöhen (z.B. auf 15), um die angezeigte Karte zu vergrößern.

#3: JavaScript Bibliothek erstellen
Nun benötigen wir eine JavaScript Datei mit folgendem Inhalt:

function loadMap()
{
    // Get address data from form
    var strasse = Xrm.Page.getAttribute("address1_line1").getValue();
    var plz = Xrm.Page.getAttribute("address1_postalcode").getValue();
    var ort = Xrm.Page.getAttribute("address1_city").getValue();
    var land = Xrm.Page.getAttribute("address1_country").getValue();
   
    // Build google maps url
    var url = "
http://maps.google.de/maps?output=embed&q="
            + strasse + "," + plz + " " + ort + "," + land;
    // Set iFrame source to google maps url
    Xrm.Page.ui.controls.get("IFRAME_googlemapsdemo").setSrc(url);

#4: JavaScript Bibliothek bereitstellen
Diese Datei fügen wir der in Schritt #1 erstellten Lösung als neue Web Resource hinzu.


4.1 Die JavaScript Bbliothek als neue Web Resource der Solution hinzufügen


#5: JavaScript Bibliothek aktivieren
Nun müssen wir nur noch unsere JavaScript Bibliothek aus den Schritten #3 und #4 auf dem Kontakt-Formular im OnLoad Ereignis aktivieren. Dazu öffnen wir im Bearbeitungmodus (Kontakt Formular) die "Form Properties" und fügen unsere Bibliothek den Formular Bibliotheken hinzu.
5.1 Google Maps JS-Bibliothek den Formular Bibliotheken hinzufügen

Jetzt erstellen wir einen Event Handler, der unser Funktion beim OnLoad des Formulars ausführt.
5.2 Event Handler, der loadMap im OnLoad ausführt

#6: Anpassungen veröffentlichen
Abschließend müssen wir unsere Solution bzw. die gemachten Anpassungen noch veröffentlichen.

6.1 Solution/Anpassungen veröffentlichen

#7: Ergebnis überprüfen
Nun wird auf dem Kontatformular der Standort auf einer Karte angezeigt - vorausgesetzt man hat eine valide Adresse eingetragen.

7.1 Eine valide Adresse in das Kontakt Formular eintragen und speichern

7.2 Die Adresse wird direkt im Kontakt Formular als Location auf einer Google Map angezeigt

--
:: Links / Weiterführende Information:

18.11.2010

JavaScript Common Snippets (Form)

GET: Auslesen eines Wertes
var x = Xrm.Page.getAttribute("attributeName").getValue();

SET: Setzen eines Wertes
Xrm.Page.getAttribute("attributeName").setValue("attributeValue");

GET: Selektierten Wert einer Pickliste auslesen
Xrm.Page.getAttribute("attributeName").getSelectedOption().text;

HIDE TAB: Verbergen einer Registerkarte
Xrm.Page.ui.tabs.get(tabNumber).SetVisible(false);

SET iFRAME URL: iFrame URL setzen
Xrm.Page.getControl("IFRAME_name").setSrc("http://google.com");

GET: GUID des aktuellen Benutzer auslesen
var userId = Xrm.Page.context.getUserId();

SET: Feld den Fokus geben
Xrm.Page.getControl("attributeName").setFocus(true);

FIRE: OnChange-Ereignis auslösen
Xrm.Page.getAttribute("attributeName").fireOnChange();

BREAK: Speichern eines Forms abbrechen
event.returnValue = false;

SET: Requirement Level setzen
var level = "none":
//var level = "required":
//var level = "recommended":
Xrm.Page.getAttribute("attributeName").setRequiredLevel(level);


CUSTOM: getServerURL
var customServerURL = document.location.protocol + “//” + document.location.host + “/” + Xrm.Page.context.getOrgUniqueName();

--
:: Links / Weiterführende Informationen