Tuesday, August 2, 2011

Enable/Disable Out of Box buttons (Sub Grid) based on a custom rule in crm 2011

You may have read millions of blogs on this topic. Here is my attempt.

Scenario:

We have an entity with “Many to One relationship” to multiple entities. We want to disable “Add Existing” button on subgrids of some of those entities.
In this example, I am disabling a “Add Existing Contact” button for all the entities except account. I am modifying the ribbon of contact entity.

Steps: There are 3 major steps to accomplish this solution

  1. JavaScript web resource
  2. Button id and command definition of the button we want to disabale/enable.
  3. Modify the ribbon definition of the entity ribbon.
Here are steps the steps in detail

Step 1: Javascript WebResource

  • Create a new javascript webresource with name new_CustomRule.js and add the following lines in it.
function HideExisting( PrimaryEntityTypeCode)
 {
  if (PrimaryEntityTypeCode ==1)
        {
        return true;
         }
         else
         {
          return false;
          }
 }
  • Save the webresource and publish it.
The HideExisting function is checking value of PrimaryEntityTypeCode parameter passed to it. If the PrimaryEntityTypeCode is 1(account) the function will return true otherwise it will return false.The function will enable the “Add Existing Contact” if it is on account form but disable the button on any other entity form.

Step 2: Getting the button id/s and command definitions of the button/s


  • If you don’t have CRM2011 SDK, download one. Go to location sdk\samplecode\cs\client\ribbon\exportribbonxml in SDK.

  • If you are using system entity and it’s ribbon has not been modified before, click on exportedribbonxml folder and open up the ribbon of your entity.

  • If you are working with a custom entity or with the system entity whose ribbon has been modified, open the exportribbonxml solution in Visual studio. If you are using a custom entity enter your entity name in ExportRibbonXml.cs in the following section.

image



  • Run the program and it will generate the ribbon definitions for the all the entities mentioned in the program.
  • Open the entity ribbon from exportedribbonxml folder and search for the button you are interested in. We are looking for “AddExisting” buttons in this case scenario. we need the whole <Buttons>tags for this solution

image

AddExistingStandard button is used when we embed a grid on the form and AddExistingAssoc is used when we click on native left navigation link. Look at “Command” name in the button tags above. We need the command definitions for these commands.

Step 3: Modify the Ribbon definition of Contact entity

  • Create a new solution in CRM, add contact entity to the solution and export the solution.

  • Open the customization file from the exported solution and look for <RibbonDiffXML> . It will look like following. We are making changes to 3 areas of the definition highlighted in red.
<RibbonDiffXml>
        <CustomActions />         
        <Templates>
               <RibbonTemplates Id=“Mscrm.Templates“></RibbonTemplates>
        </Templates>
        <CommandDefinitions />
        <RuleDefinitions>
       <TabDisplayRules />
       <DisplayRules />
       <EnableRules />
       </RuleDefinitions>
       <LocLabels />
</RibbonDiffXml>
  • Repalce the <CustomActions /> with
 <CustomActions>
            <CustomAction Id="AddExistingCustomAction"  Location="Mscrm.SubGrid.contact.AddExistingAssoc"  Sequence="40">
              <CommandUIDefinition>
                <Button Id="Mscrm.SubGrid.contact.AddExistingAssoc"  Command="Mscrm.AddExistingRecordFromSubGridAssociated"  Sequence="40" LabelText="$Resources(EntityDisplayName):Ribbon.SubGrid.AddExisting" Alt="$Resources(EntityDisplayName):Ribbon.SubGrid.AddExisting" Image16by16="/_imgs/ribbon/AddExistingStandard_16.png" Image32by32="/_imgs/ribbon/AddExistingStandard_32.png" TemplateAlias="o1" ToolTipTitle="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddExistingAssoc_ToolTipTitle" ToolTipDescription="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddExistingAssoc_ToolTipDescription" />
              </CommandUIDefinition>
            </CustomAction>
            <CustomAction Id="AddExistingCustomAction2"  Location="Mscrm.SubGrid.contact.AddExistingStandard"  Sequence="40">
              <CommandUIDefinition>
                <Button Id="Mscrm.SubGrid.contact.AddExistingStandard" Command="Mscrm.AddExistingRecordFromSubGridStandard" Sequence="30" LabelText="$Resources(EntityDisplayName):Ribbon.SubGrid.AddExisting" Alt="$Resources(EntityDisplayName):Ribbon.SubGrid.AddExisting" Image16by16="/_imgs/ribbon/AddExistingStandard_16.png" Image32by32="/_imgs/ribbon/AddExistingStandard_32.png" TemplateAlias="o1" ToolTipTitle="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddExistingStandard_ToolTipTitle" ToolTipDescription="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddExistingStandard_ToolTipDescription" />
              </CommandUIDefinition>
            </CustomAction>
 </CustomActions>
We need a <CustomAction> to change the behaviour of the button. Make sure location property of <CustomAction> tag is exactly the same as Id property of <Button> tag.
The <Button >tags has been copied from contactribbon file from exportedribbonxml folder mentioned in step 2.
  • Repalce the <CommandDefinitions /> with the command definition from contactribbon file from step 2.
<CommandDefinitions>
            <CommandDefinition Id="Mscrm.AddExistingRecordFromSubGridStandard">
              <EnableRules>
                <EnableRule Id="Mscrm.AppendToPrimary" />
                <EnableRule Id="Mscrm.EntityFormIsEnabled" />
                <EnableRule Id="Mscrm.AddExistingCustomRule" />
              </EnableRules>
              <DisplayRules>
                <DisplayRule Id="Mscrm.ShowForOneToManyGrids" />
                <DisplayRule Id="Mscrm.AppendToPrimary" />
                <DisplayRule Id="Mscrm.AppendSelected" />
                <DisplayRule Id="Mscrm.CanWriteSelected" />
              </DisplayRules>
              <Actions>
                <JavaScriptFunction FunctionName="Mscrm.GridRibbonActions.addExistingFromSubGridStandard" Library="/_static/_common/scripts/RibbonActions.js">
                  <CrmParameter Value="SelectedEntityTypeCode" />
                  <CrmParameter Value="SelectedControl" />
                </JavaScriptFunction>
              </Actions>
            </CommandDefinition>
            <CommandDefinition Id="Mscrm.AddExistingRecordFromSubGridAssociated">
              <EnableRules>
                <EnableRule Id="Mscrm.AppendPrimary" />
                <EnableRule Id="Mscrm.AppendToPrimary" />
                <EnableRule Id="Mscrm.EntityFormIsEnabled" />
                <EnableRule Id="Mscrm.AddExistingCustomRule" />
              </EnableRules>
              <DisplayRules>
                <DisplayRule Id="Mscrm.ShowForManyToManyGrids" />
                <DisplayRule Id="Mscrm.AppendPrimary" />
                <DisplayRule Id="Mscrm.AppendToPrimary" />
                <DisplayRule Id="Mscrm.AppendSelected" />
                <DisplayRule Id="Mscrm.AppendToSelected" />
                <DisplayRule Id="Mscrm.CanWriteSelected" />
              </DisplayRules>
              <Actions>
                <JavaScriptFunction FunctionName="Mscrm.GridRibbonActions.addExistingFromSubGridAssociated" Library="/_static/_common/scripts/RibbonActions.js">
                  <CrmParameter Value="SelectedEntityTypeCode" />
                  <CrmParameter Value="SelectedControl" />
                </JavaScriptFunction>
              </Actions>
            </CommandDefinition>
          </CommandDefinitions>

The only thing we changed in the commandefinition is the <EnableRule> highlighted in Blue.
<EnableRule Id="Mscrm.AddExistingCustomRule" />

  • Now I need to define this rule. Change the <EnableRules /> with
<EnableRules>
      <EnableRule Id="Mscrm.AddExistingCustomRule">
       <CustomRule FunctionName="HideExisting" Library="$webresource:new_CustomRule.js" Default="false" >
          <CrmParameter Value="PrimaryEntityTypeCode" />
        </CustomRule>
      </EnableRule>
 </EnableRules>
In the <CustumRole> I am calling a function HideExisting from webresource CustomRule.js mentioned in step 1. The default return value for this function false.The <CustomRule> is also passing PrimaryEntityTypeCode as parameter to HideExisting function If the function return true, the system will enable the “Add Existing Contact” button otherwise it will be disable the button.

  • Save the file and overwrite the Customization file in your exported solution zip file with this file.
  • Import the solution zip file and publish it. It’s done.
Note: If your solution is not working. The reason may be, when you click on left navigation or click on subgrid on the form the javascript starts loading. But it won’t call the function. But if you click on some other option and come back it will work the second time.This problem has been fixed in Rollup 2 . I spent 2 days to sort this out.
Install rollup 2 and you are good to go.

11 comments:

  1. Thank you soooooooo much!! you saved me a lot of time trying to figure this one out. I must say, I was close, just had the custom action ID different to the button which explains why it didn't work. But once I found your blog it was very easy to follow and get working!! I can't thank you enough! :)

    ReplyDelete
  2. Hi,

    We tried to implement this for a custom entity and it did not work as expected. The system is throwing a javascript error.

    Our requirement is to Enable/Disable the subgrid ribbon button, based on the value of a picklist on the main form. (For example, disable the contact subgrid 'Add Existing' button for the Account based on a picklist value in the Account form).

    Please help.

    ReplyDelete
  3. Hi It should, I think you don't even need javascript to do that. Check the valuerule, where you can specify the field value.
    http://technet.microsoft.com/en-us/library/gg334317.aspx

    ReplyDelete
  4. Our requirement is to Enable/Disable the subgrid ribbon button, for example "A sales or a leasing executive could add or remove their assigned projects after enquiry creation, this permission should be removed for executive, should be only available for managers and higher."

    ReplyDelete
  5. Microsoft Dynamics CRM training will help you manage and prioritize your business goals, customize.we teach MS Dynamics CRM training and class available at Hyderabad.

    ReplyDelete
  6. I need to disable the New button on a cutom entity based on a Security Role

    ReplyDelete
  7. Try this
    http://ribbonworkbench.uservoice.com/knowledgebase/articles/76681-hide-a-standard-out-of-the-box-button-based-on-a

    ReplyDelete
  8. Try this one.this may be helpful.
    http://crmsolutionbuket.blogspot.com/2012/09/in-crm-entities-xml-and-details-are.html

    ReplyDelete
  9. Hi, Thanks for article. I want to hide "open sharepoint" button from document location of account entity.

    ReplyDelete
  10. When I follow the exact process listed in the article above, I get an error when I try and re-import the solution. Please see https://community.dynamics.com/crm/f/117/t/181183 for details. If anyone knows how to fix this, I would greatly appreciate it. Thanks in advance.

    ReplyDelete