Disable Sub Grid record buttons in ribbon based on Parent record’s value in CRM 2011.

Hi,

Recently we had a requirement to disable Add New and Edit button of a sub grid record based on parent record’s attribute value.

For this we first need to add a new EnableRule and pass the id of the parent record to a custom function that will use this value to get value of the form and pass true and false accordingly.

FirstPrimaryItemId CRMParameter will pass the id of the parent record.

<EnableRule Id="new.new_fcm_child.EnableRule2.EnableRule">
 <CustomRule FunctionName="DisableButton" Library="$webresource:new_myScript" Default="true">
 <CrmParameter Value="FirstPrimaryItemId" />
 </CustomRule>
 </EnableRule>

Adding this EnableRule to existing CommandDefinitions

<RibbonDiffXml>
 <CustomActions />
 <Templates>
 <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
 </Templates>
 <CommandDefinitions>
 <CommandDefinition Id="Mscrm.AddNewRecordFromSubGridStandard">
 <EnableRules>
 <EnableRule Id="Mscrm.AppendToPrimary" />
 <EnableRule Id="Mscrm.EntityFormIsEnabled" />
 <EnableRule Id="new.new_fcm_child.EnableRule2.EnableRule" />
 </EnableRules>
 <DisplayRules>
 <DisplayRule Id="Mscrm.ShowForOneToManyGrids" />
 <DisplayRule Id="Mscrm.AppendToPrimary" />
 <DisplayRule Id="Mscrm.CreateSelectedEntityPermission" />
 <DisplayRule Id="Mscrm.AppendSelected" />
 <DisplayRule Id="Mscrm.HideAddNewForChildEntities" />
 </DisplayRules>
 <Actions>
 <JavaScriptFunction FunctionName="Mscrm.GridRibbonActions.addNewFromSubGridStandard" Library="/_static/_common/scripts/RibbonActions.js">
 <CrmParameter Value="SelectedEntityTypeCode" />
 <CrmParameter Value="PrimaryEntityTypeCode" />
 <CrmParameter Value="FirstPrimaryItemId" />
 <CrmParameter Value="PrimaryControl" />
 </JavaScriptFunction>
 </Actions>
 </CommandDefinition>
 <CommandDefinition Id="Mscrm.EditSelectedRecord">
 <EnableRules>
 <EnableRule Id="Mscrm.CheckBulkEditSupportForEntity" />
 <EnableRule Id="Mscrm.VisualizationPaneNotMaximized" />
 <EnableRule Id="new.new_fcm_child.EnableRule2.EnableRule" />
 </EnableRules>
 <DisplayRules>
 <DisplayRule Id="Mscrm.BulkEditPrivilege" />
 <DisplayRule Id="Mscrm.WriteSelectedEntityPermission" />
 </DisplayRules>
 <Actions>
 <JavaScriptFunction FunctionName="Mscrm.GridRibbonActions.bulkEdit" Library="/_static/_common/scripts/RibbonActions.js">
 <CrmParameter Value="SelectedControl" />
 <CrmParameter Value="SelectedControlSelectedItemReferences" />
 <CrmParameter Value="SelectedEntityTypeCode" />
 </JavaScriptFunction>
 </Actions>
 </CommandDefinition>
 </CommandDefinitions>
 <RuleDefinitions>
 <TabDisplayRules />
 <DisplayRules>
 <DisplayRule Id="Mscrm.AppendSelected">
 <EntityPrivilegeRule PrivilegeType="Append" PrivilegeDepth="Basic" AppliesTo="SelectedEntity" />
 </DisplayRule>
 <DisplayRule Id="Mscrm.AppendToPrimary">
 <EntityPrivilegeRule PrivilegeType="AppendTo" PrivilegeDepth="Basic" AppliesTo="PrimaryEntity" />
 </DisplayRule>
 <DisplayRule Id="Mscrm.BulkEditPrivilege">
 <MiscellaneousPrivilegeRule PrivilegeName="BulkEdit" />
 </DisplayRule>
 <DisplayRule Id="Mscrm.CreateSelectedEntityPermission">
 <EntityPrivilegeRule PrivilegeType="Create" PrivilegeDepth="Basic" AppliesTo="SelectedEntity" />
 </DisplayRule>
 <DisplayRule Id="Mscrm.HideAddNewForChildEntities">
 <OrRule>
 <Or>
 <EntityPropertyRule AppliesTo="SelectedEntity" PropertyName="IsChildEntity" PropertyValue="false" />
 </Or>
 <Or>
 <RelationshipTypeRule AppliesTo="SelectedEntity" AllowCustomRelationship="false" />
 </Or>
 </OrRule>
 </DisplayRule>
 <DisplayRule Id="Mscrm.ShowForOneToManyGrids">
 <RelationshipTypeRule AppliesTo="SelectedEntity" RelationshipType="OneToMany" />
 </DisplayRule>
 <DisplayRule Id="Mscrm.WriteSelectedEntityPermission">
 <EntityPrivilegeRule PrivilegeType="Write" PrivilegeDepth="Basic" AppliesTo="SelectedEntity" />
 </DisplayRule>
 </DisplayRules>
 <EnableRules>
 <EnableRule Id="new.new_fcm_child.EnableRule2.EnableRule">
 <CustomRule FunctionName="DisableButton" Library="$webresource:new_Service_Request_Script" Default="true">
 <CrmParameter Value="FirstPrimaryItemId" />
 </CustomRule>
 </EnableRule>
 <EnableRule Id="Mscrm.AppendToPrimary">
 <RecordPrivilegeRule PrivilegeType="AppendTo" AppliesTo="PrimaryEntity" />
 </EnableRule>
 <EnableRule Id="Mscrm.CheckBulkEditSupportForEntity">
 <OrRule>
 <Or>
 <SelectionCountRule AppliesTo="SelectedEntity" Minimum="1" Maximum="1" />
 </Or>
 <Or>
 <SelectionCountRule AppliesTo="SelectedEntity" Minimum="2" />
 <CustomRule FunctionName="Mscrm.RibbonActions.isBulkEditEnabledForEntity" Library="/_static/_common/scripts/RibbonActions.js">
 <CrmParameter Value="SelectedEntityTypeCode" />
 </CustomRule>
 </Or>
 </OrRule>
 </EnableRule>
 <EnableRule Id="Mscrm.EntityFormIsEnabled">
 <FormStateRule State="Disabled" InvertResult="true" />
 </EnableRule>
 <EnableRule Id="Mscrm.VisualizationPaneNotMaximized">
 <CustomRule FunctionName="Mscrm.RibbonActions.disableButtonsWhenChartMaximized" Library="/_static/_common/scripts/RibbonActions.js">
 <CrmParameter Value="SelectedControl" />
 </CustomRule>
 </EnableRule>
 </EnableRules>
 </RuleDefinitions>
 <LocLabels />
</RibbonDiffXml>

The JavaScript code

// function to disable related record
 function DisableButton(id) {

 //CRM Server Url:
 var result = true;
 var serverUrl = Xrm.Page.context.getServerUrl();

// OData Call to get the data
 var ServiceRequestQuery = "new_CustomEntitySet?$select=attr1,attr2&$filter=attrId eq guid'" + id + "'";
 var ServiceRequestUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc/" + ServiceRequestQuery;
 // make synchronous call
 var ServiceRequest= syncODataCall(ServiceRequestUrl);
 // get the option set value
 if (ServiceRequest[0].attr1 != null && ServiceRequest[0].attr2 != null) {
 var attr1Value = ServiceRequest[0].attr1.Value;
 var attr2Value = ServiceRequest[0].attr2 .Value;

if (attr1Value != "863600004" && attr2Value == "279640002") {
 result = false;
 }
 else {
 result = true;
 }
 }
 return result;
 }

// function to make synchronous oData call
 function syncODataCall(odataSelect) {
 var request = new XMLHttpRequest();
 request.open("GET", odataSelect, false);
 request.setRequestHeader("Accept", "application/json");
 request.setRequestHeader("Content-Type", "application/json; charset=utf-8");
 request.send();
 var objJQuery = JSON.parse(request.responseText);
 return objJQuery.d.results;
 }

Hope it helps

Using RetrieveEntityRibbonRequest to get the ribbon definition of an Entity

Hi,

Recently I was assigned a task to find out programmatically if a particular button is already defined on an entity or not. For this we can make use RetrieveEntityRibbonRequest class.

Sample C# Code


// Initialize RetrieveEntityRibbonRequest
RetrieveEntityRibbonRequest ribbonReq = new RetrieveEntityRibbonRequest();

// RibbonLocationFilters

// All - Retrieve all Ribbons. Equivalent to Default. Value = 7.
// Default - Retrieve all Ribbons. Equivalent to All. Value = 7.
// Form - Retrieve just the form ribbon. Value = 1.
// HomepageGrid -  Retrieve just the ribbon displayed for entity grids. Value = 2.
// SubGrid -  Retrieve just the ribbon displayed when the entity is displayed in a subgrid or associated view. Value = 4.
// if not specified it returns only the definition
ribbonReq.RibbonLocationFilter = RibbonLocationFilters.All;

// specify the entity schema name
ribbonReq.EntityName = currentEntityName;
RetrieveEntityRibbonResponse ribbonRes = (RetrieveEntityRibbonResponse)_serviceProxy.Execute(ribbonReq);
Byte[] bytes = unzipRibbon(ribbonRes.CompressedEntityXml);
string ribbonDiffString = System.Text.Encoding.GetEncoding("utf-8").GetString(bytes);
if (ribbonDiffString.Contains("RibbonButtonID"))
{
// logic
}

public byte[] unzipRibbon(byte[] data)
{
System.IO.Packaging.ZipPackage package = null;
MemoryStream memStream = null;
memStream = new MemoryStream();
memStream.Write(data, 0, data.Length);
package = (ZipPackage)ZipPackage.Open(memStream, FileMode.Open);
ZipPackagePart part = (ZipPackagePart)package.GetPart(new Uri("/RibbonXml.xml", UriKind.Relative));
using (Stream strm = part.GetStream())
{
long len = strm.Length;
byte[] buff = new byte[len];
strm.Read(buff, 0, (int)len);
return buff;
}
}

Bye.

Using multiple JavaScriptFunction for Actions in CRM 2011 Ribbon.

Hi,

We had a requirement in which we wanted to add some functionality on the existing Distribute Campaign Activity button for Campaign Activity entity.

For e.g. before we start the distribution we wanted to check for a specific value for all the Marketing Lists associated to that Campaign Activity. Based on it we wanted to proceed further or stop the distribution.

So we created a new custom button using the same definitions used for the existing Distribute Campaign Activity button (i.e. same CommandDefinitions and RuleDefinitions). The only thing we added was the new JavaScriptFunction in the Actions menu. It was referring to the function name CheckMLUA inside the webresource name new_CheckML

Now inside this new JavaScriptFunction we wanted to call the CallDistribute function that is being used by the OOB Distribute Campaign Activity button

For this to work we defined the FunctionName as isNAN for campaignactivity.js.

“For each library, add a <JavaScriptFunction Library=”$webresource:webresourceName” FunctionName=”isNaN” /> node. It requires a function name, so we’ve just been putting isNaN in there so there’s no error.”

<JavaScriptFunction
Library=$webresource:new_CheckML
FunctionName=CheckMLUA />

<JavaScriptFunction
FunctionName=isNaN
Library=/_static/ma/campaignactivity/campaignactivity.js>

<CrmParameter
Value=PrimaryEntityTypeCode />

</JavaScriptFunction>

And our function

RibbonDiffXML

</pre>
<RibbonDiffXml>
 <CustomActions>
 <CustomAction Id="WWB.Form.campaignactivity.MainTab.Actions.Distribute.CustomAction" Location="Mscrm.Form.campaignactivity.MainTab.Actions.Controls._children" Sequence="41">
 <CommandUIDefinition>
 <Button Id="WWB.Form.campaignactivity.MainTab.Actions.Distribute" Command="WWB.Form.campaignactivity.MainTab.Actions.Distribute.Command" Sequence="0" ToolTipTitle="$LocLabels:WWB.Form.campaignactivity.MainTab.Actions.Distribute.LabelText" LabelText="$LocLabels:WWB.Form.campaignactivity.MainTab.Actions.Distribute.LabelText" ToolTipDescription="$LocLabels:WWB.Form.campaignactivity.MainTab.Actions.Distribute.Description" TemplateAlias="o1" Image16by16="/_imgs/MA/CampaignActivityDistribute_16.png" Image32by32="/_imgs/MA/CampaignActivityDistribute_32.png" />
 </CommandUIDefinition>
 </CustomAction>
 </CustomActions>
 <Templates>
 <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
 </Templates>
 <CommandDefinitions>
 <CommandDefinition Id="WWB.Form.campaignactivity.MainTab.Actions.Distribute.Command">
 <EnableRules>
 <EnableRule Id="WWB.Form.campaignactivity.MainTab.Actions.Distribute.Command.EnableRule.FormStateRule" />
 </EnableRules>
 <DisplayRules>
 <DisplayRule Id="WWB.Form.campaignactivity.MainTab.Actions.Distribute.Command.DisplayRule.EntityPrivilegeRule" />
 </DisplayRules>
 <Actions>
 <JavaScriptFunction Library="$webresource:new_CheckML" FunctionName="CheckMLUA" />
 <JavaScriptFunction FunctionName="isNaN" Library="/_static/ma/campaignactivity/campaignactivity.js">
 <CrmParameter Value="PrimaryEntityTypeCode" />
 </JavaScriptFunction>
 </Actions>
 </CommandDefinition>
 </CommandDefinitions>
 <RuleDefinitions>
 <TabDisplayRules />
 <DisplayRules>
 <DisplayRule Id="WWB.Form.campaignactivity.MainTab.Actions.Distribute.Command.DisplayRule.EntityPrivilegeRule">
 <EntityPrivilegeRule EntityName="activitypointer" PrivilegeDepth="Basic" PrivilegeType="Create" />
 </DisplayRule>
 </DisplayRules>
 <EnableRules>
 <EnableRule Id="WWB.Form.campaignactivity.MainTab.Actions.Distribute.Command.EnableRule.FormStateRule">
 <FormStateRule State="Existing" />
 </EnableRule>
 </EnableRules>
 </RuleDefinitions>
 <LocLabels>
 <LocLabel Id="WWB.Form.campaignactivity.MainTab.Actions.Distribute.Description">
 <Titles>
 <Title languagecode="1033" description="Distribute Description" />
 </Titles>
 </LocLabel>
 <LocLabel Id="WWB.Form.campaignactivity.MainTab.Actions.Distribute.LabelText">
 <Titles>
 <Title languagecode="1033" description="Distribute" />
 </Titles>
 </LocLabel>
 </LocLabels>
 </RibbonDiffXml>
<pre>

The helpful links

http://rajeevpentyala.wordpress.com/2012/05/23/loading-dependent-jscript-libraries-in-ribbon-buttons-execution-crm-2011/

http://social.microsoft.com/Forums/is/crmdevelopment/thread/02ed3c05-05c2-4638-a139-e070db4561b0

Bye.

Try out – Ribbon Workbench for Dynamics CRM 2011

Hi,

Today i came across this new tool for Ribbon editing in CRM 2011.

http://www.develop1.net/public/page/Ribbon-Workbench-for-Dynamics-CRM-2011.aspx

The tools looks really wonderful.

Will try it out soon.

Bye.

 

 

Filtered lookup for n:n relationship.

Hi,

Daniel Cai has recently posted about his solution for filtered lookup in case of n:n relationship in his blog.

It works like a charm.

Do check it out.

http://danielcai.blogspot.com/2011/12/filtered-lookup-for-existing-button-of.html

Bye.

The best Ribbon Editor Tool for CRM 2011.

Hi,

Just a few days back came to know from my friend that a new ribbon editor tool was has been released.

http://erikpool.blogspot.com/2011/10/new-crm-2011-ribbon-editing-tool.html

So thought of giving it a try.

After using it for few days I can easily say that this is exactly the tool many of us would have been waiting for ribbon editing.

There are other posts as well in the Erik Pool’s blog for understanding how exactly ribbon can be customized. Do have a look at them.

http://erikpool.blogspot.com/2011/10/understanding-crm-ribbon-xml-part-3.html

Bye.