Saturday 19 January 2013

Microsoft Dynamics CRM 2011 - Adding a new Custom Ribbon Button

One of the best new features of CRM 2011 has to be "The Ribbon". CRM 2011 Ribbon is customizable. We can add custom buttons, add events to buttons, hide/unhide buttons, enable/disable buttons, add button groups, etc.

A custom ribbon button could be used in following scenarios:
  • There is a requirement for some user interactivity. 
  • If there is a requirement to display additional information about a record by simply clicking a button
  • If there is a requirement to execute business logic for a record by simply clicking a button

In this blog I will show how to add a new custom ribbon button to a custom entity form.

I will add a custom ribbon button labelled "Revenue" on one of my custom entity form. The custom entity is called "Movie". This entity has movie records. After adding, when we open any movie record, the button will be displayed on the ribbon. This button is supposed to calculate and display the revenue for the movie. In this blog I will only show how to add a ribbon button.

The ribbon customization is inside the entity form xml. I will create an unmanaged solution to which I will add the "Movie" entity. I will export this solution, add the ribbon button code, import the solution and publish the changes. The movie record will then display the new ribbon button.

1) I will create a new unmanaged solution called "Ribbon_new_Movie".

Unmanaged Solution

2) In this solution add the existing entity "Movie". Select "No" at "Missing Required Components" screen. We are only interested in the required entity "Movie".

Select "No" to Missing Required Components

Add "Movie" Entity to the Unmanaged Solution

3) Below is the "Movie" entity record form, before I add a new custom ribbon button. The red arrow is pointing to the place where the new ribbon button will be displayed.

Entity "Movie" Record
4) I will go to my Solutions and select unmanaged solution "Ribbon_new_Movie" to export. Click on the "Export" button.

Select the Solution "Ribbon_new_Movie" to Export

5) The solution export process will take you through various screens. I will display all the screens below. Make your selection as per what I have done below. At the end you will be asked to save your solution. I have saved the solution by its default name.

In below screen, I don't need to publish changes. So click "Next".

Export Solution Screen 1
I don't need any related components. Ignore the warning and click "Next".

Export Solution Screen 2
 Don't select any advanced settings below as we don't need any. Click "Next".

Export Solution Screen 3
Since I am not interested in a managed solution, so I will keep the default "Unmanaged" selection. Click "Next". 

Export Solution Screen 4
I will save the solution by the default name in one of my folders. The solution is saved as a zip file.

Export Solution Screen 5


6) I will unzip the solution file in the same location.

Solution File Unzipped

7) There are 3 files. We are interested in "customizations.xml". This XML file contains the code where we will add our custom ribbon button code.

You can open and modify this XML file in Visual Studio OR any XML editor OR any notepad of your choice. I am editing this in Visual Studio 2010 IDE.

"customizations.xml" in Visual Studio 2012

8) This file contains XML for the "Movie" entity form. This form code contains a section where we can enhance and customize the ribbon. Search for the markup in the code <RibbonDiffXml>. The code section between <RibbonDiffXml> and </RibbonDiffXml> is where we can customize the Ribbon.

If we open this section without any previous customizations done, it will look like:

RibbonDiffXml Code

The RibbonDiffXml is named as such because any code added here is the Ribbon Difference on top of the out of the box Ribbon. It has various markups like CustomActions, Templates, CommandDefinitions, RuleDefinitions, LocLabels and RibbonNotSupported.

<CustomActions>: We can define our custom buttons.
<Templates>: Define a ribbon template.

<CommandDefinitions>: We can define the rules ID and action web resources.

<RuleDefinitions>: We can define the actual rules to enable/disable or hide/unhide buttons.

<LocLabels>: Can contain the LocLabel elements.

<RibbonNotSupported>: Indicates that the entity does not support the ribbon.

9) I will add the code for a new custom ribbon button. The final code between the RibbonDiffXml markup will look something like:

Final Code after Adding a Custom Ribbon Button

I have defined a custom action. In this I define where to display the button. I have defined the location of the button as Location = "Mscrm.Form.new_movie.MainTab.Collaborate.Controls._children". This means the custom button will be displayed on the main tab of the form and within the "Collaborate" group.

I have defined the actual button inside the "CommandUIDefinition" markup. Inside button I have defined various attributes. One of them is Command = "Mscrm.HomepageGrid.new_movie.MovieRevenue.Command". In command we can define the display rules and actions around the button. For this blog I have just defined a placeholder value and not defining any actual rule. This means the custom button will be displayed and active at all times but will do nothing when clicked. 

The "LabelText" defines the button display name. The text in "ToolTipTitle" and "ToolTipDescription" will be displayed when you take your mouse over the button. They describe what the button does.

Inside "Image16by16" and "Image32by32" we can define the image icons for the button. In CRM there is a folder "_imgs" inside the CRM installation directory. In my case the location of "_imgs" is the default location at "C:\Program Files\Microsoft Dynamics CRM\CRMWeb\_imgs". This folder contains icon images used by CRM. You can either select any image from there or use your own custom image. I have selected already present icon images "InvoicePaid_16" and "InvoicePaid_32".

I have also defined a placeholder for rules inside "CommandDefinitions" and "CommandDefinition". The Id="Mscrm.HomepageGrid.new_movie.MovieRevenue.Command" has the same value which I had defined in button as Command = "Mscrm.HomepageGrid.new_movie.MovieRevenue.Command". This way we can bind the rules and actions to the button. For this blog I have just created placeholder and not creating any rules and actions. I have created this placeholder to show where we can enhance the button functionality. I will write blogs in the future to show how to enable/disable, hide/unhide and fire JScript on a custom ribbon button.

10) After changing the XML in the file "customizations.xml" now we have to import it back. Include this "customizations.xml" file from unzipped location back to the zipped file. We can open the zipped file, drag and drop the changed file back in.

Now import this changed zip file back into CRM.

Go to CRM Solutions and click Import.

Import the Solution

I have pasted the screenshots for every screen in the import process. Select the unmanaged zip file to import.

Import Solution Screen 1
Ignore the warning. This warning indicates we cannot uninstall this solution. Since there is no such requirement, so we can ignore this warning. Click "Next".

Import Solution Screen 2
This will start the import process.

Import Solution Screen 3
This screen shows us that the solution import process has been completed successfully.

Import Solution Screen 4
Click "Publish All Customizations". This will publish all the changes which I did on the "Movie" entity form.

Import Solution Screen 5
11) When I open the "Movie" entity form, the new custom button "Revenue" appears where I had intended it to be.

New Custom Ribbon Button "Revenue" Added
If I take my mouse over this button I can see the text values I added for "ToolTipTitle" and "ToolTipDescription" in the XML file.

New Custom Ribbon Button "Revenue"

I hope this blog about 'Microsoft Dynamics CRM 2011 - Adding a new Custom Ribbon Button' was informative. Please feel free to leave your comments.

7 comments:

  1. Thanks Ashish - the blog is very informative and to the detail. Appreciate your help in putting these screen shots painstakingly.
    Cheers:)

    ReplyDelete
    Replies
    1. Thanks Atul. I am glad this blog was informative and helpful to you.

      Delete
  2. Hi Ashish, Thanks for such an informative & detailed presentation of whole process.
    My requirement is also pretty much similar to what u described above.
    However, i want to know few things/concerns based on reading and understanding of above :
    - From where are u defining/getting Field Name and its Value ? For eg, Year of Make - 2011.
    - What if i want to perform some action on button click. For eg, fetching some of existing
    field(s) value(s) ?

    Im still very new to this CRM , so would appreciate if u can clarify above concerns of mine so that i can have more clarity in order to proceed further.

    Thanks

    ReplyDelete
    Replies
    1. Hi Mayank,

      Thanks.

      - The field names are created from settings and customization. You create new fields in the entity and add them on the form. Then they are available to populate.

      - I have not written any blog, yet, on executing JavaScript from a Ribbon Button. Have a read of this blog by Nishant on "Using JavaScript in a custom button in CRM 2011": http://nishantrana.wordpress.com/2010/11/04/using-javascript-in-a-custom-button-in-crm-2011/

      You will get an idea of how to call and execute JavaScript through a Ribbon button.

      Also in case you need to know how to run a JavaScript through the CRM form, you can read one of my blogs: http://ashishmahajancrm.blogspot.com.au/2013/02/microsoft-dynamics-crm-2011-and.html

      I hope this helps.

      Delete
    2. Hi Ashish,
      Thanks for spontaneous Reply to my post.
      Our Requirement is such that , we need to perform some action on click of Button.
      To be more specific, on button click, it'll fetch value from some Contact Form fields like Business Phone, etc. and then have to pass this & other parameters to external CTI (Cisco UCCX)function.

      Also im trying to fetch above field value thru JS as mentioned by you like :
      var nameControlLabel = Xrm.Page.getControl("telephone1").getLabel();
      But its giving JS error while Page Load.

      Kindly assist !

      Thanks

      Delete
    3. Hi Mayank,

      I suggest you enter your questions on official Microsoft Dynamics CRM forums. This way you will get immediate and appropriate answers to your questions. Due to my commitments I might not be able to reply immediately.

      The path to the forums is:
      http://social.microsoft.com/forums/en/crm/threads

      Thanks.

      Delete
    4. Hi Ashish,
      Ok i'll also put up question on official Microsoft Dynamics CRM forums as u said. One more question i do have is , can i call some 3 party DLL and its API's/Methods from within MSCRM ?
      As i mentioned, my requirement is such that,
      - click on custom button will fetch value from certain form fields (this much we've managed to do, thanks to your above detailed example and suggestions)
      - We've to pass fetched field values as as input parameter to some custom 3-party DLL API/Method which is written in C++ and meant for performing Cisco UCCX CTI operations.
      Is it possible and what r acheivable alternatives ?

      Thanks for ur assistance.

      Delete