Microsoft Dynamics CRM 2011 | Overlays (crmgrid,subgrid,results)

loading_Overlay_SubGrid

In meinem heutigen Artikel möchte ich auf eine Problemstellung zu sprechen kommen, die wir in der Praxis leider nicht “supported” lösen können. Etwaige Verwendung meines Beispielcodes geschieht daher auf eigene Gefahr.

Nehmen wir an, wir führen eine Aktion aus der Listenansicht, der erweiterten Suche oder auch aus einem Unterraster heraus über einen ISV-Button aus. Diese Aktion kann dabei synchron oder asynchron stattfinden. Da sie jedoch längere Zeit in Anspruch nehmen kann, möchten wir unsere Nutzer darauf hinweisen.

Üblicherweise verwendet man dafür eine Overlay-Technik und zeigt eine animierte Grafik oder einen Hinweis-Text.

Microsoft selbst verwendet eine animierte Grafik, wenn eine Listenansicht oder ein Unterraster lädt. Für einen kurzen Moment sieht man die Grafik samt Hinweistext. Auch bei einer Erweiterten Suche ist dies der Fall. Leider ist uns Entwicklern der Zugang zu dieser Ressource nicht erlaubt.

Loading_crmGridIm CRM finden wir vier unterschiedliche Bereiche von Datensatz-darstellungen. Die Form, die Listenansicht, die Unterraster-Ansicht und die Erweiterte Suche.loading_subgrid

Für die Unterraster-Ansicht können ebenfalls ISV-Buttons hinzugefügt werden. loading_resultsFrameDiese finden dann auch Anwendung in der Datenansicht einer Erweiterten Suche.

Um ein Overlay zu erstellen arbeitet man üblicherweise mit einem DIV-Element. Die Frage stellt sich nunmehr, wie man sein eigenes DIV-Element dem jeweiligen CRM Dokument hinzufügen kann.

Beginnen wir zunächst mit unserem DIV-Code:

    var bg = document.createElement(„div“),
        box = document.createElement(„div“);
       
        bg.id = „loading-bg“;
        bg.style.position = „absolute“;
        bg.style.top = „0“;
        bg.style.left = „0“;
        bg.style.width = „100%“;
        bg.style.height = „100%“;
        bg.style.zIndex = „9000“;
        bg.style.backgroundColor = „#FFFFFF“;
        bg.style.opacity = „0.7“;
        bg.style.filter = „progid:DXImageTransform.Microsoft.Alpha(Opacity=70)“;

        box.id = „loading-box“;
        box.style.position = „absolute“;
        box.style.top = „50%“;
        box.style.left = „50%“;
        box.style.width = „100%“;
        box.style.height = „100%“;
        box.style.zIndex = „9999“;
        box.style.textAlign = „center“;
        box.style.marginLeft = „-50%“;
        box.innerHTML = ‚<span align=“center“ class=“msg“><br><br><br>’+ yourMessage + ‚</span>‘;
        box.style.background = „url(/_imgs/AboutBox.png) no-repeat top“;
        box.style.cursor = „wait“;

Es gibt natürlich auch noch andere Möglichkeiten, wie z.B. jQuery, um sich ein DIV-Element zu erstellen und mit einem CSS-Style zu versehen. Für mein Beispiel soll dieses vereinfachte Verfahren jedoch genügen.

Unser DIV-Element müssen wir nunmehr dem vorhandenen CRM-Dokument hinzufügen. Normalerweise würde man dies via document.getElementById(“body”).appendChild(…) versuchen. Dies führt im CRM jedoch zu Script-Fehlern, so dass in der Praxis ein appendChild auf body nicht möglich ist.

So hilft nur, sich den Seitenaufbau mit den F12-Entwicklertools anzusehen und die unterschiedlichen DIV-Elemente aufzuspüren, um ein Element zu finden, welches die Methode zulässt, gleichwohl aber auch keine Script-Fehler auslöst.

Zunächst der Code für ein crmGrid, also einer Listenansicht von Datensätzen:

if (document.getElementById(„crmGrid“)) {
document.getElementById(„crmGrid“).appendChild(bg);
document.getElementById(„crmGrid“).appendChild(box);
}

Nun der Code für die Erweiterte Suche:

if (document.getElementById(„fetchResults“)) {
document.getElementById(„fetchResults“).appendChild(bg);
document.getElementById(„fetchResults“).appendChild(box);
}

Bei einem Unterraster, z.B. für Weitere Adressen in meinem Beispiel, sieht es etwas komplizierter aus, das die ID des DIV-Elementes in Abhängigkeit zur Entität benannt wird:

if (document.getElementById(„crmGrid_Account_CustomerAddress“)) {
        document.getElementById(„crmGrid_Account_CustomerAddress“).appendChild(bg);
        document.getElementById(„crmGrid_Account_CustomerAddress“).appendChild(box);
}
       
if (document.getElementById(„crmGrid_Contact_CustomerAddress“)) {
        document.getElementById(„crmGrid_Contact_CustomerAddress“).appendChild(bg);
        document.getElementById(„crmGrid_Contact_CustomerAddress“).appendChild(box);
}

Hier wird zwar auch crmGrid verwendet. Es wird jedoch auch auf die Beziehung hingewiesen _Account_CustomerAddress bzw. _Contact_CustomerAddress. Hat man das Prinzip jedoch einmal verstanden, so gelingt es schnell auch die anderen DIV-IDs zu ermitteln.

Bleibt noch die Fragestellung, wie man sein Overlay nach erfolgreicher Aktion wieder entfernt. Dies geschieht mit der removeChild(…)-Methode.

Exemplarisch der Code für das Entfernen auf der Listenansicht:

if (document.getElementById(„crmGrid“)) {
        document.getElementById(„crmGrid“).removeChild(document.getElementById(„loading-bg“));
        document.getElementById(„crmGrid“).removeChild(document.getElementById(„loading-box“));
}

Den gesamten Code noch in zwei Funktionen verpackt, haben wir damit die Möglichkeit, unseren Nutzern eine Nachricht während unserer Aktion zukommen zu lassen.

Auf eine Besonderheit möchte ich jedoch noch eingehen. Verwendet Ihr Beispielsweise ein AJAX in Eurem Code, der durch Klick auf den ISV-Button ausgelöst wird und der Request erfolgt dabei synchron, so haben die Browser die Angewohnheit, zunächst die Abfrage auszuführen, bevor Euer Browser wieder reagiert und Euch das erzeugte DIV-Element anzeigen würde.

Wenn Ihr jedoch auf die synchrone Verarbeitung notwendig ist und Ihr trotzdem Euer DIV vorher zur Anzeige bringen wollt, solltet Ihr jQuery einbinden. Ihr habt dann mit

// Euer Aufruf des DIV-Overlays
            $(‚#loading-box‘).show().delay(100).queue(function() {
            // Euer synchroner AJAX-Call
            });

Mit Hilfe von .delay().queue() “trickst” Ihr die Verarbeitungsabfolge aus und sorgt dafür, dass nunmehr Euer Overlay erst angezeigt wird, bevor die synchrone Verarbeitung Eures AJAX-Calls stattfindet.

Zusatz: In diesem Fall könnt Ihr keine animierte Grafik verwenden, da die Animation während der synchronen Verarbeitung nicht erfolgen würde. Arbeitet in diesem Fall lieber mit einer Grafik + Text, wie in meinem Beispiel.

Nochmal der Hinweis: Da wir mit document.getElementById arbeiten und DOM-Manipulationen vornehmen, gilt diese Methode als “unsupported”. Die Verwendung geschieht daher auf eigene Gefahr.

Ich hoffe, das Produkt-Team wird uns schon bald via SDK eine “supported” Methode geben, um derartige Hinweise auch für Listenansichten, Unterraster oder Erweiterte Suche-Ergebnislisten auszugeben.

Wenn auch Ihr dieser Meinung seid, könnt Ihr auf der Connect-Feedback-Seite für meinen Vorschlag voten und dazu beitragen, dass wir eine solche Erweiterung schon bald sehen werden.

 

Technorati Tags:

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s