Monday, June 20, 2011

Launch a Dialog from a Ribbon button in CRM 2011

Dialogs and Ribbon buttons are like peabutter (nutfree) and jam! I have been using them for a few months now but initally I struggled to find some examples that took me through the step-by-step approach to adding this feature in CRM 2011. I've included some screen shots and code snippets to walk you through a straight forward example.



** UPDATE - Make sure to read the following post for code samples and further details **
http://crmmongrel.blogspot.com/2011/10/launching-dialog-from-ribbon-revisted.html


Overview
For this example we will use the Case entity and create an "Escalate Case" button on the ribbon that launches a Dialog process. The Dialog will collect some information and then update the Case's Priority field by setting it to "High". The Dialog must know which Case we are working with, must be modal (so I can't click the button twice) and must refresh the Case form when it is completed so I can see the changes.

Step1: Create a Solution Package
The first thing you need to do is create a new Solution Package to contain your custom ribbon button. You will need to export some items to make changes in a text editor so a package is required. Go to the Settings area of CRM, then the Solutions node. Create a package named CustomRibbonButton.


Now you will add the Case entity to this package. In your new Solution Package, go to the Entities node and click the Add Existing button. Select the Case entity and click OK to have it added to your package.


Step2: Create the PNG Web Resources
We will need to create 2 image Web Resources for this project. The custom ribbon button will require a custom image, and you will need a 32x32 and a 16x16 resolution of that image. To help you out, I have included a custom image with both resolutions ...feel free to send $100 paypal donations ;)
32x32 png16x16 png
Let's add the 16x16 image first. In the Solution Package, click on the Web Resources node, then click on the New button. A window will appear that lets you specify the type of Web Resource you are adding. Provide a unique descriptive Name like btn_escalate16, make sure the Type is PNG format and then click the Browse button to upload your image. Click the Save and Close button, and then repeat these steps to add the 32x32 image.


Step3: Create the JavaScript WebResource
Now that we have the images added we will add the JScript that will allow us to launch the Dialog window when the custom ribbon button is clicked. Adding the JScript resource follows the same inital steps as the image, except that you pick Script (JScript) as the Type for the Web Resource. This will show a Text Editor button along with the Browse button (to select an existing JScript file from your machine).


For this example we will add the script directly by clicking on the Text Editor button to bring up the editor window. In the editor window add the following code snippet (seen in the screen shot). When you are done, click the OK button on the editor and then the Save and Close button for the Web Resource.

JScript snippet
This snippet is generic and can be used to launch any dialog window. The window will be modal (to stop users from hitting button twice or doing something else in conflict), the size is 615x480, and when it's done the parent window (Case form in this example) will be refreshed to show the changes.

Step4: Create the Dialog process
This step is where your business logic for the Dialog process comes in, for this example we will keep it pretty simple though. In the Solution Package, click on the Processes node, then click on the New button. Create a Dialog process for the Case entity and name it EscalateCase. Creating a Dialog is outside the scope of this blog article (let me know if I should blog on it) but your Dialog must contain at least 1 Prompt and Response question, and then it should update the Case's Priority field to "High". In my fancy example I ask for an escalation reason, create a Note with it, and then update the Case Priority to High. Make sure to Save and Activate your Dialog process when you are done.


Step5: Export the Solution Package... Why?
Now that we have created Web Resources for the images and JScript along with a custom Dialog to perform the record update, we are are ready to export the Solution Package. Why do we need to export the Solution Package? Because there is no built in Ribbon editor in CRM 2011 (hint hint MS) we need to tie together the custom button with the images and the JScript and finally the Dialog so they all work together.

The toolbar for your custom solution will have an Export Solution button, click this button to begin the process.The first step is to Publish all Customizations (recommended), after that click the Next button.


If there are Required Components that are missing from the Solution Package they will be identified in the next screen. However, for this example we are only dealing with the ribbon buttons so you can ignore this and click the Next button again.


The next stage will be the Export System Settings (Advanced) screen. For this example we will not be affecting any of these settings so skip this page by clicking the Next button.


The last screen will ask if your solution is Managed or UnManaged. For this example keep the solution package UnManaged (again, sorry but outside the scope of this blog article) and click the Export button. This will prompt you to save a file (CustomRibbonButton_1_0.zip) to your drive.


Step6: Edit the customizations.xml
Locate the zip file that was exported to your drive and unzip it into it's own folder. From that folder you will notice a collection of files and subfolders. The WebResources folder contains copies of the images and JScript file, the Workflows folder contains a file that outlines your custom Dialog. To get our button working we need to open the customizations.xml file in an xml editor, I suggest Visual Studio over notepad ;)


Edit the customizations.xml file in Visual Studio. Before we get into the code snippet, a quick review of the customizations.xml file shows us that based on the solution we exported (which included the Web Resources, Dialog and Case entity) everything we need is referenced in this one file.


We will be modifying the RibbonDiffXml section to add our custom button. There are many sections and options when building the RibbonDiffXml (too many for this blog article) but I have included a link to the MSDN reference material. It is a good idea to review this information so that you have an idea around all the options available with the ribbon buttons. http://msdn.microsoft.com/en-us/library/gg327947.aspx

I'm going to make it easier for you by providing the XML needed to add the button. Replace the empty RibbonDiffXml section in your customizations.xml with the following snippet:

  <RibbonDiffXml>
   <CustomActions>
    <CustomAction Id="CI_formlevelEscalateCase" Location="Mscrm.Form.incident.MainTab.Actions.Controls._children" Sequence="99">
     <CommandUIDefinition>
      <Button Id="B_formbuttonEscalateCase" Command="Cmd_DialogEscalateCase" LabelText="Escalate Case" ToolTipTitle="Escalate this Case" ToolTipDescription="Escalate the current Case to high priority status." TemplateAlias="o1" Image16by16="$webresource:new_btn_escalate16" Image32by32="$webresource:new_btn_escalate32" />
     </CommandUIDefinition>
    </CustomAction>
   </CustomActions>
   <Templates>
    <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
   </Templates>
   <CommandDefinitions >
    <CommandDefinition Id="Cmd_DialogEscalateCase">
     <EnableRules>
      <EnableRule Id="Mscrm.Enabled" />
     </EnableRules>
     <DisplayRules />
     <Actions>
      <JavaScriptFunction FunctionName="launchModalDialog" Library="$webresource:new_launchDialog" >
       <!-- dialogID, typeName, recordId -->
       <StringParameter Value="???" />
       <StringParameter Value="incident" />
       <CrmParameter Value="FirstPrimaryItemId" />
      </JavaScriptFunction>
      </Actions>
    </CommandDefinition>
   </CommandDefinitions>
   <RuleDefinitions>
    <TabDisplayRules />
    <DisplayRules />
    <EnableRules />
   </RuleDefinitions>
   <LocLabels />
  </RibbonDiffXml>


You may notice in the snippet that there is highlighted ??? value for a <StringParameter> element. That needs to be replaced with the WorkflowId for the custom dialog you built earlier. Where do you find it? Scroll down the customizations.xml file and locate the <Workflows> element, you will find a <Workflow> element for your EscalateCase dialog, along with the related WorkflowId.


in the customizations.xml file

Understanding the RibbonDiffXml
In our RibbonDiffXml we used a simple example to display a button. The RibbonDiffXml elements that make up this button are:
  • <CustomAction> Identifies where the button will exist on the ribbon (where, not if)
    • <CommandUIDefinition> Specifies what command should be called, along with the label, tooltip and icons to use
  • <CommandDefinition> Is the command to be called when the button is clicked
    • <Actions> Defines whick URL or JScript to execute, along with any parameter definitions.
      • <CrmParameter> is a unique Dynamics CRM parameter type that lets you pull information from the calling Form. In our example we ask for the Case records Id value. 

Step7: Import and Publish the Solution
Once all of that is done, I save the customizations.xml file and compress all the files/folders back into a new zip file (CustomRibbonButton_1_1.zip). This file will be imported back into the CRM system.


Back in Dynamics CRM, go to the Settings area and the Solution module. Click on the Import Solution button and locate your .zip file. Then click the Next button.


The import process will check to make sure the XML is correctly formated and the solution can be imported. If everything checks out, you will see the following screen. Click the Next button. If you have included a process (workflow or dialog) in your solution, you will be be asked about activating any related processes. Flag them for activation.


When the import is finished, there will be status page that shows success/fail/warning messages. This will help to debug any solution package errors (usually poorly formated XML). If everything is good, click on the Publish All Customizations button.

You are done :)

Give it a try!
Now the fun part, within CRM go to the Service section and the Cases module. Open an existing Case that is "Low" or "Normal" priority. On the form's ribbon you should see a new Escalate Case button. Click the button to launch your custom Dialog process. When it's done, the form should refresh with the Case set to "High" priority.



That's it. Now you can create a simple Ribbon button to launch a custom Dialog process from a Form in Dynamics CRM 2011. I will introduce some more custom ribbon features in upcoming articles. Enjoy!