Results for tag "dynamics-crm"

CRM 2011 – Original Ribbon Button – Andere (Javascript) Aktion hinterlegen

Hallo Leute,

aufbauend auf meinem letzten Beispiel (siehe Original Ribbon Button ausblenden) möchte ich euch nun zeigen, wie Ihr die Aktion, die hinter einem Original-Ribbon-Button liegt verändern könnt.

Im Konkreten möchte ich euch zeigen, wie Ihr dem Button „Verkaufschance als verloren schließen“ (im Form, nicht auf der Hauptseite) eine eigene Javascript-Funktion zuweisen könnt.

Dafür geht Ihr bitte wie im Artikel Original Ribbon Button ausblenden beschrieben vor.

Extrahiert also das ZIP-File und öffnet die Customizations.xml. Parallel dazu öffnet Ihr bitte wieder die „opportunityribbon.xml“-Datei aus dem SDK-Sample-Projekt.
Sucht in der XML-Datei nun nach „MarkAsLost“. Ihr werden nun folgende Zeile finden:

Kopiert das gesamte -Element am besten temporär in einen Text-Editor (Notepad) und merkt euch die ID des übergeordneten Elements. Wechselt in die Customizations.xml. Sucht dort (wie im anderen Artikel beschrieben) nach dem RibbonDiffXml-Node und fügt dort die folgenden Zeilen ein:

[sourcecode language=“xml“]
<CustomAction Id="eigeneid" Location="Mscrm.Form.opportunity.MainTab.Actions.Controls._children">
<CommandUIDefinition>

</CommandUIDefinition>
</CustomAction>
[/sourcecode]

Als Location gebt bitte die ID des übergenordneten Elements ein und fügt ein „._children“ an.
Zwischen die beiden CommandUIDefinition-Tags kopiert nun das zwischengespeichert Button-Element. Fertig sieht das nun ungefähr wie folgt aus:

[sourcecode language=“xml“]
<CustomAction Id="eigeneid" Location="Mscrm.Form.opportunity.MainTab.Actions.Controls._children">
<CommandUIDefinition>
<Button Id="Mscrm.Form.opportunity.MarkAsLost" Command="Mscrm.Form.opportunity.MarkAsLost" Sequence="4" Alt="$Resources:Ribbon.Form.opportunity.MainTab.Actions.MarkAsLost" LabelText="$Resources:Ribbon.Form.opportunity.MainTab.Actions.MarkAsLost" Image16by16="/_imgs/SFA/MarkAsLost_16.png" Image32by32="/_imgs/SFA/MarkAsLost_32.png" TemplateAlias="o1" ToolTipTitle="$Resources:Mscrm_Form_opportunity_MainTab_Actions_MarkAsLost_ToolTipTitle" ToolTipDescription="$Resources:Mscrm_Form_opportunity_MainTab_Actions_MarkAsLost_ToolTipDescription" />
</CommandUIDefinition>
</CustomAction>
[/sourcecode]

Nun ist es notwendig den „Command“ des Button-Elements zu verändern, z.B. auf: Mscrm.Isv.Form.opportunity.MarkAsLost.
Nachdem dieser „Command“ noch nicht existiert, muss er nun hinzugefügt werden, z.B. so:

[sourcecode language=“xml“]
<CommandDefinition Id="Mscrm.Isv.Form.opportunity.MarkAsLost">
<EnableRules />
<DisplayRules />
<Actions>
<JavaScriptFunction Library="$webresource:prefix_cs_opportunity" FunctionName="MarkAsLost" />
</Actions>
</CommandDefinition>
[/sourcecode]

Beachtet hier vor allem die JavaScriptFunction. Dort wird die Webresource angegeben, in der sich die JS-Methode befinden soll und der Name der JS-Methode selbst angegeben.

Passt das entsprechend euren Wünschen an und erstellt im Anschluss ein ZIP-File. Dieses kann dann wieder in gewohnter Manier in das CRM importiert werden.

Cheers,
Christian

CRM 2011 – Original Ribbon Button ausblenden

Hallo Leute,

heute mal wieder etwas „on standard“. CRM 2011 bietet ja von Haus aus einige nützliche Funktionalitäten. Nur manchmal erfüllen diese nicht ganz den Sinn und Zweck oder „overrulen“ die eigene Business-Logik.

Mit Hilfe der „HideCustomAction“ kann man ganz einfach bestehende Ribbons, Gruppen oder Tabs ausblenden.

Wie das geht möchte ich euch am Beispiel der Verkaufschance zeigen. Dieses Beispiel zeigt, wie man den „Verkaufschance als gewonnen abschließen“-Ribbon Button entfernt.

Zunächst ist es einmal wichtig zu wissen, wie der Ribbon-Button heißt. Leider kann man das dem Ribbon nicht direkt entnehmen. Es ist daher notwendig die SDK auf dem Rechner installiert zu haben. Im SDK befindet sich unter „sdksamplecodecsclientribbonexportribbonxml“ eine kleine Konsolenanwendung, die euch für jede Entität eien XML-Datei generiert, in der ALLE Ribbon Buttons (auch potentiell selbst hinzugefügte) der jeweiligen Entität enthält.

Die zur Verkaufschance passende Datei heisst „opportunityribbon.xml“. Die englische Bezeichnung für diesen Button heißt „MarkAsWon“, muss man sich also irgendwie zusammenreimen, die Lokalisierungen sind in dieser Datei leider (?) nicht enthalten, würde die Geschichte vermutlich auch unübersichtlich machen.

Nun findet man den Button zwei Mal. Ein Mal für das „Homepagegrid“ (damit ist das kontextbezogene Ribbon-Menü im Hauptfenster gemeint) und einmal für das Formular selbst.

Damit wissen wir nun welche ID’s wir ausblenden wollen.

Nun ist es notwendig die Lösung zu exportieren (Wichtig, Eure Lösung muss das Element „Anwendungsmenübänder“ enthalten!

Nun könnt Ihr eure Lösung exportieren und das heruntergeladene ZIP-File extrahieren. IM ZIP-File findet Ihr die Datei „Customizations.xml“.
Sucht in der Datei nun die Entität „opportunity“ und sucht die „RibbonDiffXml“-Node.

An dieser Stelle können wir nun die „HideCustomAction“s hinzufügen. Fertig sieht das dann wie folgt aus:

Nun aus den extrahierten Dateien wieder ein ZIP-File erstellen und die Lösung importieren.

That’s it.

Cheers
Christian

CRM 2011 – Custom Ribbon Button – Mehr als 3 Elemente – Buttons deaktiviert

Mal wieder etwas spannendes…

Vergisst man beim Definieren der Ribbon-Buttons im customization.xml die Sequence hochzuzählen, so zeigt dies zunächst keine Auswirkungen.
Die Buttons 1-3 werden wie erwartet dargestellt und entsprechend der Rules aktiviert/deaktiviert.

Fügt man jedoch einen 4. oder 5. Button hinzu, werden diese sofort deaktiviert, die Enable/Display-Rule gar nicht mehr aufgerufen.

Funktioniert:
[sourcecode language=“xml“]
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control0" Sequence="10" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control0" LabelText="$LocLabels:BestellungGenerieren.Label" ToolTipTitle="$LocLabels:BestellungGenerieren.Tooltip" ToolTipDescription="$LocLabels:BestellungGenerieren.Description" Image16by16="$webresource:hcs_bestellung_32" Image32by32="$webresource:hcs_bestellung_32" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control1" Sequence="10" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control1" LabelText="$LocLabels:AngebotSenden.Label" ToolTipTitle="$LocLabels:AngebotSenden.Tooltip" ToolTipDescription="$LocLabels:AngebotSenden.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_mail" Image32by32="$webresource:prefix_icon_kalkulation_angebot_mail" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control2" Sequence="10" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control2" LabelText="$LocLabels:AngebotWord.Label" ToolTipTitle="$LocLabels:AngebotWord.Tooltip" ToolTipDescription="$LocLabels:AngebotWord.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_word" Image32by32="$webresource:prefix_icon_kalkulation_angebot_word" TemplateAlias="o1"></Button>
[/sourcecode]

Funktioniert nur für die ersten 3 Buttons:
[sourcecode language=“xml“]
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control0" Sequence="10" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control0" LabelText="$LocLabels:BestellungGenerieren.Label" ToolTipTitle="$LocLabels:BestellungGenerieren.Tooltip" ToolTipDescription="$LocLabels:BestellungGenerieren.Description" Image16by16="$webresource:hcs_bestellung_32" Image32by32="$webresource:hcs_bestellung_32" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control1" Sequence="10" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control1" LabelText="$LocLabels:AngebotSenden.Label" ToolTipTitle="$LocLabels:AngebotSenden.Tooltip" ToolTipDescription="$LocLabels:AngebotSenden.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_mail" Image32by32="$webresource:prefix_icon_kalkulation_angebot_mail" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control2" Sequence="10" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control2" LabelText="$LocLabels:AngebotWord.Label" ToolTipTitle="$LocLabels:AngebotWord.Tooltip" ToolTipDescription="$LocLabels:AngebotWord.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_word" Image32by32="$webresource:prefix_icon_kalkulation_angebot_word" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control3" Sequence="10" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control3" LabelText="$LocLabels:AngebotUebergeben.Label" ToolTipTitle="$LocLabels:AngebotUebergeben.Tooltip" ToolTipDescription="$LocLabels:AngebotUebergeben.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_uebergeben" Image32by32="$webresource:prefix_icon_kalkulation_angebot_uebergeben" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control4" Sequence="10" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control4" LabelText="$LocLabels:AngebotObsolet.Label" ToolTipTitle="$LocLabels:AngebotObsolet.Tooltip" ToolTipDescription="$LocLabels:AngebotObsolet.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_obsolet" Image32by32="$webresource:prefix_icon_kalkulation_angebot_obsolet" TemplateAlias="o1"></Button>
[/sourcecode]

UPDATE!!!! Die Sequence sollte man in mind. 10er Schritten hochzählen. Verwendet man Einerschritte, ist beim 5. Button Sense und das Problem, dass der Button automatisch deaktiviert und die EnableRule ignoriert wird, tritt wieder auf!!

Richtig:
[sourcecode language=“xml“]
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control0" Sequence="10" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control0" LabelText="$LocLabels:BestellungGenerieren.Label" ToolTipTitle="$LocLabels:BestellungGenerieren.Tooltip" ToolTipDescription="$LocLabels:BestellungGenerieren.Description" Image16by16="$webresource:hcs_bestellung_32" Image32by32="$webresource:hcs_bestellung_32" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control1" Sequence="20" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control1" LabelText="$LocLabels:AngebotSenden.Label" ToolTipTitle="$LocLabels:AngebotSenden.Tooltip" ToolTipDescription="$LocLabels:AngebotSenden.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_mail" Image32by32="$webresource:prefix_icon_kalkulation_angebot_mail" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control2" Sequence="30" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control2" LabelText="$LocLabels:AngebotWord.Label" ToolTipTitle="$LocLabels:AngebotWord.Tooltip" ToolTipDescription="$LocLabels:AngebotWord.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_word" Image32by32="$webresource:prefix_icon_kalkulation_angebot_word" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control3" Sequence="40" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control3" LabelText="$LocLabels:AngebotUebergeben.Label" ToolTipTitle="$LocLabels:AngebotUebergeben.Tooltip" ToolTipDescription="$LocLabels:AngebotUebergeben.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_uebergeben" Image32by32="$webresource:prefix_icon_kalkulation_angebot_uebergeben" TemplateAlias="o1"></Button>
<Button Id="Mscrm.Isv.prefix_angebot.Form.Group0.Control4" Sequence="50" Command="Mscrm.Isv.prefix_angebot.Form.Group0.Control4" LabelText="$LocLabels:AngebotObsolet.Label" ToolTipTitle="$LocLabels:AngebotObsolet.Tooltip" ToolTipDescription="$LocLabels:AngebotObsolet.Description" Image16by16="$webresource:prefix_icon_kalkulation_angebot_obsolet" Image32by32="$webresource:prefix_icon_kalkulation_angebot_obsolet" TemplateAlias="o1"></Button>
[/sourcecode]

Cheers,
Christian

CRM 2011 – Custom Lookup (addCustomView) – OK Button disabled – Eintrag kann nicht ausgewählt werden

Wie der Titel des Artikels schon sagt, gilt es bei der Erstellung eines Custom Lookups ein paar Kleinigkeiten zu beachten. Tut man dies nicht, kann es dazu führen, dass man im Lookup zwar die richtigen Werte angezeigt bekommt, diese aber nicht übernehmen (per Klick auf den Record oder per Klick auf den OK-Button) kann.

Unter anderem geschieht dies, wenn das Layout-XML und Fetch-XML nicht genau aufeinander abstimmt. In meinem Fall hat es geholfen, darauf zu achten, dass überall der PrimaryKey der Entität verwendet wird.

Beispiel:

[sourcecode language=“xml“]
<grid name="resultset" object="1" jump="new_id" select="1" icon="1" preview="1"><row name="result" id="new_id"><cell name="new_name" width="300"/></row></grid>

<fetch version=’1.0′ output-format=’xml-platform‘ mapping=’logical‘ distinct=’true‘>
<entity name=’new_id‘>
….
</fetch>
[/sourcecode]

Bei mir hat das geholfen. Was sind eure Erfahrungen damit?

Cheers,
Chris

CRM 2011 – N:M Relation mit selber Entity – entityA n : m entityA – Retrieve Items

Mal wieder etwas spannendes aus der CRM Welt. Ich habe hier schon mal über Relationen gebloggt (siehe: Relationen). Nun kam mir etwas spannendes unter.

Und zwar musste eine N:M Relation abgebildet werden, wobei es sich auf beiden Seiten um die selbe Entität handelt. Also eine Adresse kann N andere Adressen referenziert haben und umgekehrt.

Betrachtet man das in nem Classdiagram, sieht’s wie folgt aus:

Man sollte denken, dass die Relation nun zwei ID’s hat, welche beide „entityiaid“ heissen. Das ist aber nicht der Fall. CRM hängt dem zweiten Schlüssel ein „one“ an. Das ist irrsinnig wichtig zu beachten, da es sonst zu kryptischen Fehlern bei FetchXml oder QueryExpressions kommt.

Cheers,
Christian

CRM 2011 – Verkaufschance abschließen – „gewonnen“/“verloren“

Nachfolgend findet Ihr zwei nützliche Funktionen, mit welchen Ihr programmatisch eine Verkaufschance abschließen (als ‚gewonnen‘ schließen bzw. als ‚verloren‘ schließen) könnt:

[sourcecode language=“csharp“]

/// <summary>
/// Marks as lost.
/// </summary>
/// <param name="organization">The organization.</param>
/// <param name="entityId">The entity id.</param>
/// <returns></returns>
public Result MarkAsLost(IOrganization organization, string entityId)
{
try
{
LoseOpportunityRequest req = new LoseOpportunityRequest();
Entity opportunityClose = new Entity("opportunityclose");
opportunityClose.Attributes.Add("opportunityid", new EntityReference("opportunity", new Guid(entityId)));
opportunityClose.Attributes.Add("subject", "opportunity lost");
req.OpportunityClose = opportunityClose;

OptionSetValue o = new OptionSetValue();
o.Value = 4;
req.Status = o;
LoseOpportunityResponse resp = (LoseOpportunityResponse) Helper.OrgService(organization).Execute(req);

return Helper.CreateResult("ok", Result.StatusCodes.Ok, null);
}
catch (Exception ex)
{
return Helper.CreateResult(ex.Message, Result.StatusCodes.Error, null);
}
}

/// <summary>
/// Marks as won.
/// </summary>
/// <param name="organization">The organization.</param>
/// <param name="entityId">The entity id.</param>
/// <returns></returns>
public Result MarkAsWon(IOrganization organization, string entityId)
{
try
{
WinOpportunityRequest req = new WinOpportunityRequest();
Entity opportunityClose = new Entity("opportunityclose");
opportunityClose.Attributes.Add("opportunityid", new EntityReference("opportunity", new Guid(entityId)));
opportunityClose.Attributes.Add("subject", "opportunity won");
req.OpportunityClose = opportunityClose;

//The Status parameter corresponds to Status Reason in the Microsoft CRM application. If you pass -1 for this parameter, the platform sets the status to the appropriate value for the Microsoft CRM application.
req.Status = new OptionSetValue(-1);

WinOpportunityResponse res = (WinOpportunityResponse)Helper.OrgService(organization).Execute(req);
return Helper.CreateResult("ok", Result.StatusCodes.Ok, null);
}
catch (Exception ex)
{
return Helper.CreateResult(ex.Message, Result.StatusCodes.Error, null);
}
}

[/sourcecode]

Happy coding!

CRM 2011 – „assembly must be registered in isolation“-Error

Nach längerer Zeit mal wieder was neues von der „Front“.

Wir haben letztens von unserem Implementierungspartner eine neue Solution zugesendet bekommen. Es gab jedoch Probleme beim Einspielen der neuen Solution, der „bekannte“ Fehler „Assembly must be registered in isolation“.

Was tun? Zunächst haben wir festgestellt, dass eine „alte“ Version der Assembly am Server direkt in CRM registriert war. Beim Versuch diese zu aktualisieren, kam der gleiche Fehler. Die Recherche unseres Partners hat ergeben, dass man für Änderungen – welche mit Assemblies zu tun haben – „Deployment Manager“ sein muss. Anstatt einer sprechenden Fehlermeldung kam jedoch der oben beschriebene Fehler.

Nachfolgend eine Sammlung von Links, welche bei der Lösung geholfen haben:

http://juicysnippets.blogspot.com/2011/03/assembly-must-be-registered-in.html
http://blogs.msdn.com/b/crminthefield/archive/2011/08/17/error-message-assembly-must-be-registered-in-isolation-when-registering-plugins-in-microsoft-dynamics-crm-2011.aspx
http://martinbodocky.wordpress.com/2011/05/12/assembly-must-be-registered-in-isolation/
http://social.microsoft.com/Forums/en/crm/thread/8fabc9a7-595f-4ebe-8ea2-b89848acf59d

Ich hoffe, ich konnte euch ein wenig weiterhelfen. Und natürlich DANKE an die Blogger, die dieses Problem bereits gelöst hatten 🙂

Cheers,
Christian

CRM 2011 – Custom View – Filter auf N:M Relation

Folgendes Beispiel:

Ihr habt in eurem Projekt folgende Entitätshierarchie:

Adresse ( n:m ) Gebäude ( n: 1 ) Standort

Am Formular des Standorts soll der Benutzer nun zunächst in einem Lookup das entsprechende Gebäude auswählen können (kein Filter). Nach Auswahl des Gebäudes sollen nur noch jene Adressen ausgewählt werden können, welche eine Verknüpfung mit dem ausgewählten Gebäude haben. Vom Prinizp eine Funktionsweise wie bei einer dependend Dropdownlist.

Normalerweise greift man jetzt einfach zu einem „FetchXML“ und baut sich das Konstrukt entsprechend auf. Aber hier beginnts zu haken: Beim Einrichten des Filters merkt man schnell, dass sich eine N:M-Relation nicht, wie z.B. eine 1:1/1:n-Relation, an einem Fremdschlüssel „aufhängt“, es fehlt also das Filter-Attribut. Jetzt wird man im Internet relativ schnell fündig, dass man in solchen Fällen einfach eine „Linked-Entity“ in das Fetch-Xml einbauen kann/muss. Problem hierbei: die addCustomView-Methode erwartet eine Entität, keine Relation.

Die Lösung sieht nun wie folgt aus:

Zunächst baut man das Fetch-XML wie gewohnt auf und lässt es mittels „Linked Entity“ auf die Relation verweisen. Innerhalb der Linked Entity, welche ja eig. keine Entität sondern eine Relation ist, hat man Zugriff auf die beiden Primary-Key-Felder der Relation. In meinem Fall „Adressid“ und „Gebaeudeid“. Dort lässt sich dann der Filter entsprechend einrichten.

Das fertige Fetch-XML sieht nun in meinem Fall wie folgt aus:

[sourcecode language=“xml“]
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="<strong>new_address</strong>">
<attribute name="new_name" />
<attribute name="new_line1" />
<attribute name="new_city" />
<attribute name="new_stateorprovince" />
<link-entity name="<strong>relationname</strong>" from="primarykey" to="primarykey" >
<all-attributes/>
<filter type="and">
<condition attribute="primarykey" operator="eq" value="{1BF2077D-B6F0-E011-8481-005056A20041}" />
</filter>
</link-entity>
<order attribute="createdon" decending="true" />
</entity>
</fetch>
[/sourcecode]

Happy programming!
Chris

CRM 2011 – Ribbons via Javascript deaktivieren (disable Ribbons with javascript)

Jeder CRM Developer wird wohl schon vor folgendem Problem gestanden sein: Einen Ribbon Button deaktivieren, weil dieser im aktuellen Kontext keinen Sinn macht. Andere Buttons verwirren den Kunden, wiederrum andere sollen überhaupt verschwinden.

In einem meiner Projekte hatten wir nun die Situation, dass wir in einem bestimmten Prozess-Stati alle Ribbon Buttons von ca. 15-20 Entitäten sperren sollten. Inklusive der Original-Ribbon-Buttons (Datei, Entität, Hinzufügen, Listentools, etc.). Microsoft stellt dafür keinen vernünftigen Weg zur Verfügung, schlägt nur die Customizations.xml vor, was für ca. 400 Buttons ein enormer Zeitaufwand wäre, abgesehen von der extremen fehleranfälligkeit.

Ich habe daher, trotz aller Warnungn von div. CRM-Spezialisten („dieser Weg wird von MS nicht supportet“, etc.), einen Weg mittels Javascript gefunden, mittels welchem sich die Ribbon Buttons deaktivieren oder ganz ausblenden lassen, seht selbst:

[sourcecode language=“javascript“]

function HideRibbonButtons () {

var dateiButton = parent.document.getElementById("jewelcontainer"); // versteckt den "Datei"-Ribbon. Diesen zu deaktivieren habe ich nicht getestet!
dateiButton.style.display = ’none‘;

var ribbon = parent.document.getElementById("Mscrm.Ribbon");
var container = ribbon.childNodes[2].childNodes[0]; // container = Ein Tab, oberhalb der dargestellten Ribbons.

for (var i = 0; i < container.childNodes.length; i++) {
var group = container.childNodes[i];

if (group.id.indexOf(‚Isv‘) > 0) { // selbst hinzugefügte tabs enthalten bei mir den Hinsweis "Isv" und werden explizit ausgenommen.
// do nothing…
}
else {
DisableAllChilds(group);
}
}
}

// iteriert über alle child elements, bis das element mit der Rolle "button" gefunden wurde.
// An dieser Stelle kann dann die Deactivate oder Hide Funktionalität aufgerufen werden
function DisableAllChilds(element) {

for (var i = 0; i < element.childNodes.length; i++) {
var subElement = element.childNodes[i];

if (subElement.childNodes.length > 0)
DisableAllChilds(subElement);
}

if (element.role == "button") {

DeactivateRibbonButton(element);

}

}

// nachdem sich ein button nicht so ohne weiteres deaktivieren lässt (der dahinterliegende Event lässt sich nicht ausschalten),
// habe ich das element einfach geklont und das original-Element durch das erzeugte Element ersetzt.
function DeactivateRibbonButton(element) {
var link = document.createElement("a");
link.role = "button";
link.className = "ms-cui-ctl-large ms-cui-disabled";

try {
link.appendChild(element.childNodes[0]); // image/buttion
link.appendChild(element.childNodes[0]); // label
}
catch (exception) {
// do nothing…
}

element.parentNode.replaceChild(link, element);
}

// einen Button ausblenden ist hingegen recht easy und sollte keine negativen Auswirkungen haben.
function HideRibbonButton(element) {
element.style.display = ’none‘;
}

[/sourcecode]

Wichtig ist es noch zu wissen, dass das CRM nur den ersten Tab voll lädt, bedeutet, die Ribbons für alle weiteren Tabs werden erst bei erstmaligem Aufruf nachgeladen. Daher ist es notwendig, die Funktion „HideRibbonButtons()“ mehrmals aufzurufen, ich mache dieses mittels einem „setInterval“. Einen eleganteren Weg habe ich leider nicht finden können.

Abschließend nochmals explizit der Hinweis: Dies ist ein von Microsoft nicht unterstützter Weg! Bitte überlegt euch daher gut, ob ihr diesen gehen wollt!

Viel Spaß beim Nachmachen!

CRM 2011 – Custom View für Subgrid

In einem anderen Blog beschreibe ich, wie man einen Custom View zu einem Lookup hinzufügen kann. Heute habe ich die gleiche Funktionalität für ein Subgrid benötigt. Nachdem ich nicht gleich eine Lösung dafür gefunden habe, möchte ich euch meine nicht vorenthalten bzw. die Unterschiede zeigen:

[sourcecode language=“javascript“]
//Add your new view to the Lookup’s set of availabe views and make it the default view
$("#" + lookupFieldId).attr("disableViewPicker", "0");
Xrm.Page.getControl(lookupFieldId).addCustomView(viewId, entityName, viewDisplayName, fetchXml, layoutXml, viewIsDefault);
$("#" + lookupFieldId).attr("disableViewPicker", "1");
[/sourcecode]
So funktionierts für ein Lookup…

[sourcecode language=“javascript“]
var grd = document.getElementById(lookupFieldId);
if (grd.readyState != "complete") {
setTimeout("SetLookupForm(…params…);", 500);
}

grd.control.setParameter("fetchXml", fetchXml);
grd.control.refresh();
[/sourcecode]
… und so für ein Subgrid.

Achtet besonders auf die Abfrage auf „readystate“. Wenn Ihr die Funktionalität im OnLoad-Event verwendet, muss das Grid noch nicht geladen sein!! In diesem Fall rufe ich die Funktion einfach erneut auf…

Viel Spaß beim Nachmachen!