Monday 27 February 2012

CRM 2011: Get "Object Type Code" of custom entity on click of custom ribbon button

In this Post, I’ve used two custom entities “Flight Route” and “Airport”. I’ve launched a new Airport popup window (create mode) on click of the custom ribbon pop-up button called “Insert New Airport” located at “Flight Route” entity.

The Object Type Code (entity type code) of custom entities can differ when you move your customizations from development to Test, Acceptance or Production environments. Hence, you do not want to hard-code this Object Type Code anywhere in your code. This post will explain you how to fetch the Object Type Code of custom entity using JavaScript. Below are the steps for an entire implementation.

1. JavaScript Library as a web resource
· Create New Web Resource, this web resource will contain following two functions.

clip_image002

· Click on Text Editor.
· Insert below functions in Text editor window.
function GetObjectTypeCode(entityName) 
{
/// <summary>
/// Gets the EntityTypeCode / ObjectTypeCode of a entity
/// </summary>
/// <param name="entityName" type="string">
/// Name of entity to return object type code of
/// </param>
/// <returns type="int" />
var lookupService = new RemoteCommand("LookupService","RetrieveTypeCode");
lookupService.SetParameter("entityName", entityName);
var result = lookupService.Execute();
if (result.Success && typeof result.ReturnValue == "number") 
{
return result.ReturnValue;
} 
else 
{
return null;
}
}
 
function CreateAirport()
{
// Get the CRM URL
var serverUrl = Xrm.Page.context.getServerUrl();
//Set features for how the window will appear 
var features = "location=no,menubar=no,status=no,toolbar=no,width=700,height=600"; 
var ObjCode=GetObjectTypeCode('acm_airport');
var path = serverUrl + '/main.aspx?etc='+ObjCode+'&extraqs=%3fetc%3d'+ObjCode+'&pagetype=entityrecord'; 
//Pop the window 
window.open((path), '_blank', features, false);   
} 

To open a new Entry form of Airport entity from Flight Route entity, first you’ve to construct URL and fetch Object Type Code of the Airport entity. These two JavaScript methods help in that need.

GetObjectTypeCode(entityName)

This is a generic method, a common method to fetch entity type code by passing entity name   as parameter. Microsoft is also using a Remotecommand method to execute many of the ribbon actions. 

CreateAirport()

This method will build the URL and open Airport entity record in create mode. It fetches the server url & entity type code and use both the values to build the required URL.

2. Insert custom ribbon pop-up button on your custom entity as shown in below link.

http://ankit.inkeysolutions.com/2012/02/crm-2011-ribbon-popup-buttons-via.html

Note:- While inserting the ribbon popup button, make sure you will change the “LaunchNewEntry.js” file name with above web resource file name, if you have changed the filename. You could quickly search the file name in exported customization.

3. Now you can verify the button on your entity’s form ribbon.

image
4. On click of this button your entry form will be launched.

image

Thursday 23 February 2012

CRM 2011 – Create Ribbon Popup buttons on entity ribbon

Dynamics CRM 2011 allows us to export a solution as managed or unmanaged solution. This solution is having the customization.xml file which contains all or selected portions of the customizations and configurations for your system. In this post I have described what to change in customization.xml file to have Ribbon popup button as shown in below screen shot.

clip_image001[4]

1. Create a Solution or use an existing one.
2. Select components.

clip_image003[4]

3. Add entity for which you want to edit the ribbon, in this example I have added “Flight Route” entity (a custom entity).
4. Export the solution with unmanaged option.
5. Unzip all files and open customizations.xml in visual studio.
6. Once you open it you could find RibbonDiffxml tag underneath an Entity node. In below screen shot I have highlighted the RibbonDiffXml of “Flight Route” entity.











Once you expand this element, you could see below xml

<RibbonDiffXml>
    <CustomActions />
   <Templates>
    <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>   
   </Templates>
   <CommandDefinitions />
   <RuleDefinitions>
  <TabDisplayRules />
  <DisplayRules />
  <EnableRules />
  </RuleDefinitions>
  <LocLabels />
</RibbonDiffXml>
In above screen shot I have highlighted 3 important elements of RibbonDiffXml xml. You need to replace those empty nodes with below xml.

Replace CustomActions with below xml content. In this example I have specified a publisher of solution with prefix as “acm”. My custom entity is acm_filightroute and a group name is “Airport”.

You need to replace these values with yours via find and replace feature of visual studio. Also change the label text and tool tip values  as per your need.
<CustomActions>
<CustomAction Id="acm.Form.acm_flightroute.MainTab.Airport.CustomAction" Location="Mscrm.Form.acm_flightroute.MainTab.Groups._children" Sequence="10">
<CommandUIDefinition>
<Group Id="acm.Form.acm_flightroute.MainTab.Airport" 
Command="Mscrm.Enabled" 
Template="Mscrm.Templates.Flexible2" 
Sequence="100" 
Title="$LocLabels:acm.Form.acm_flightroute.MainTab.Airport.TitleText" 
Description="$LocLabels:acm.Form. acm_flightroute.MainTab.Airport.DescriptionText">
<Controls Id="acm.Form.acm_flightroute.MainTab.Airport.Controls">
<SplitButton Id="acm.Form.acm_flightroute.MainTab.AirportPopUp" 
ToolTipTitle="Airport Popup Menu" 
ToolTipDescription="Popup Menu for Airport Entity" 
Command="Mscrm.Enabled" 
Sequence="20" 
LabelText="Airport PopUp Menu" 
Alt="Airport PopUp Menu" 
TemplateAlias="o1">
<Menu Id="acm.Form.acm_flightroute.MainTab.AirportPopUp.Menu">
<MenuSection Id="acm.Form.acm_flightroute.MainTab.AirportPopUp.MenuSection" 
Sequence="10" 
DisplayMode="Menu16">
<Controls Id="acm.Form.acm_flightroute.MainTab.AirportPopUp.Controls">
<Button Id="acmacm.Form.acm_flightroute.MainTab.Airport.InsertNewAirport" 
Command="acmacm.Form.acm_flightroute.MainTab.Airport.InsertNewAirport.Command" 
Sequence="20" 
ToolTipTitle="$LocLabels:acmacm.Form.acm_flightroute.MainTab.Airport.InsertNewAirport.LabelText" 
LabelText="$LocLabels:acmacm.Form.acm_flightroute.MainTab.Airport.InsertNewAirport.LabelText" 
ToolTipDescription="$LocLabels:acmacm.Form.acm_flightroute.MainTab.Airport.InsertNewAirport.Description" 
TemplateAlias="o1" Image16by16="$webresource:acm_/Images/sample_iconsTIcon16x16png" Image32by32="$webresource:acm_/Images/sample_iconsTIcon32x32png" />
<Button Id="acmacm.Form.acm_flightroute.MainTab.Airport.ShowDialog" Command="acmacm.Form.acm_flightroute.MainTab.Airport.ShowDialog.Command" Sequence="20" ToolTipTitle="$LocLabels:acmacm.Form.acm_flightroute.MainTab.Airport.ShowDialog.LabelText" LabelText="$LocLabels:acmacm.Form.acm_flightroute.MainTab.Airport.ShowDialog.LabelText" ToolTipDescription="$LocLabels:acmacm.Form.acm_flightroute.MainTab.Airport.ShowDialog.Description" TemplateAlias="o1" Image16by16="$webresource:acm_/Images/sample_iconsTIcon16x16png" Image32by32="$webresource:acm_/Images/sample_iconsTIcon32x32png" />
</Controls>
</MenuSection>
</Menu>
</SplitButton>
</Controls>
</Group>
</CommandUIDefinition>
</CustomAction>
<CustomAction Id="acm.Form.acm_flightroute.MainTab.Airport.MaxSize.CustomAction" Location="Mscrm.Form.acm_flightroute.MainTab.Scaling._children" Sequence="10">
<CommandDefinitions>
<CommandUIDefinition>
<MaxSize Id="acm.Form.acm_flightroute.MainTab.Airport.MaxSize" GroupId="acm.Form.acm_flightroute.MainTab.Airport" Sequence="10" Size="LargeMedium" />
</CommandUIDefinition>
</CustomAction>
<CustomAction Id="acm.Form.acm_flightroute.MainTab.Airport.Scale.Popup.CustomAction" Location="Mscrm.Form.acm_flightroute.MainTab.Scaling._children" Sequence="10">
<CommandUIDefinition>
<Scale Id="acm.Form.acm_flightroute.MainTab.Airport.Scale.Popup" GroupId="acm.Form.acm_flightroute.MainTab.Airport" Sequence="300" Size="Popup" />
</CommandUIDefinition>
</CustomAction>
</CustomActions>

Below is a command definition tag. Replace the prefix and other values here as well.

<CommandDefinition Id="acmacm.Form.acm_flightroute.MainTab.Airport.InsertNewAirport.Command">
<EnableRules />
<DisplayRules />
<Actions>
<JavaScriptFunction FunctionName="CreateAirport" Library="$webresource:acm_/javascripts/LaunchNewEntry.js" />
</Actions>
</CommandDefinition>
<CommandDefinition Id="acmacm.Form.acm_flightroute.MainTab.Airport.ShowDialog.Command">
<EnableRules />
<DisplayRules />
<Actions>
<JavaScriptFunction FunctionName="LaunchModalDialog" Library="$webresource:acm_/javascripts/LaunchModalDialog.js">
<StringParameter Value="{e1e36d96-ced2-4ede-85e8-455e3cf4daaf}" />
<StringParameter Value="acm_flightroute" />
<CrmParameter Value="FirstPrimaryItemId" />
</JavaScriptFunction>
</Actions>
</CommandDefinition>
</CommandDefinitions>
 
 

Apply the same procedure to below xml too.

<LocLabels>
<LocLabel Id="acmacm.Form.acm_flightroute.MainTab.Airport.InsertNewAirport.Description">
<Titles>
<Title languagecode="1033" description="Insert New Airport Description" />
</Titles>
</LocLabel>
<LocLabel Id="acmacm.Form.acm_flightroute.MainTab.Airport.InsertNewAirport.LabelText">
<Titles>
<Title languagecode="1033" description="Insert New Airport" />
</Titles>
</LocLabel>
<LocLabel Id="acmacm.Form.acm_flightroute.MainTab.Airport.ShowDialog.Description">
<Titles>
<Title languagecode="1033" description="Show Dialog Description" />
</Titles>
</LocLabel>
<LocLabel Id="acmacm.Form.acm_flightroute.MainTab.Airport.ShowDialog.LabelText">
<Titles>
<Title languagecode="1033" description="Show Dialog" />
</Titles>
</LocLabel>
</LocLabels>

7. Save Customization.xml.
8. Create a Zip file of all extracted files (in Step 5) including the updated customization.xml.

clip_image002

9. Import this newly created zip file back to CRM server.
10. Open entity form on which you have implemented popup button.
11. In my case I can see “Airport Popup Menu” in Airport group with Dropdown as shown below.

clip_image004

12. On click Dropdown button you can see two buttons.

clip_image006

Friday 10 February 2012

CRM 2011: Launch a Dialog on click of custom ribbon button located at homepage grid (landing page) of an entity

In my previous post, I have explained how to launch a dialog on click of ribbon button located at entity form. Here, in this post I am going to describe how to open a dialog on click of ribbon button located at homepage grid (landing page) of an entity.

In this Example, I’ve used custom entity “Flight Route” contains a button called “Test Button” which will launch a dialog. Dialog will select a flight name from the option set and insert new note record on the selected flight route record.

Following are steps that demonstrate launch dialog from ribbon button.

Before to start with a launch dialog, we need to create
1. Create a dialog for “Flight Route” entity
· Select Solution.
· Select Processes.
· Create new process.

clip_image002

· Specify the Process name.
· Select Entity.
· Select “Activate as” as “Process” and “Category” as “Dialog”.
· Configure it as an on-demand process.
· For this dialog make sure that it should contain at least one “Prompt and Response”
clip_image004

2. Javascript Library as a web resource
· Create new Web resource” /javascripts/LaunchModalDialog.js”
clip_image006

· Click on Text Editor.
· Insert below functions in Text editor window.
   1: function LaunchModalDialog(dialogId,typeName,recordId)
   2: {
   3:     recordId = recordId.toString();    
   4:     recordId =recordId.replace("{", "");        
   5:     recordId =recordId.replace("}", "");
   6:  
   7:     dialogId=dialogId.replace("{", "");
   8:     dialogId=dialogId.replace("}", "");
   9:  
  10:     var serverUrl = getServerUrl();
  11:     // Load modal
  12:     var serverUri = serverUrl +'/cs/dialog/rundialog.aspx';
  13:  
  14:     var mypath =  serverUri +'?DialogId=%7b' +dialogId.toUpperCase()  +'%7d&EntityName=' + typeName+'&ObjectId=%7b' +recordId+'%7d';
  15:  
  16:     // First item from selected contacts only
  17:     window.showModalDialog(mypath);
  18:  
  19:     // Reload form.
  20:     window.location.reload(true);
  21: }

In above JavaScript method I have used 3 different parameters.

dialogId is id of the dialog we need to open from button (String Parameter)
typeName is entity’s logical name (CRM Parameter)
recordId is entity’s current record id form where the dialog will be launched(CRM Parameter).


   1: function getServerUrl()
   2: {
   3:     // Generate the URL schema using a basic check for SSL
   4:     var url = 'http' + (WEB_SERVER_PORT == 443 ? 's' : '') + '://';
   5:     
   6:     if (IS_SPLA)
   7:     {
   8:         // Add the Organisation name in the IFD format 
   9:         url += ORG_UNIQUE_NAME + '.';
  10:     }
  11:     
  12:     // Append the web server host
  13:     url += WEB_SERVER_HOST;
  14:     
  15:     // Add your custom URL suffix
  16:     //url += '.mycompanyname.com'
  17:     
  18:     if (WEB_SERVER_PORT != 80 && WEB_SERVER_PORT != 443)
  19:     {
  20:         // Add the port if it is not standard HTTP or HTTPS
  21:         url += ':' + WEB_SERVER_PORT;
  22:     }
  23:     
  24:     if (IS_ONPREMISE)
  25:     {
  26:         // Add the on-premise organisation name
  27:         url += '/' + ORG_UNIQUE_NAME;
  28:     }
  29:     
  30:     // Return the URL
  31:     return url;
  32: }

The above function will create server URL according to the CRM configuration. This takes into account IFD and On-premise environments. You can modify or simplify this as needed.

3. Get the Dialog Id Value

· Once you have created new dialog.
· Click Start Dialog.

clip_image002[4]

· That will open new dialog window.
· Get the dialog id value from the URL(Ctrl+N) and note it down somewhere for future use .

clip_image003

4. Insert custom button on entity’s Homepage (landing page) using Visual Ribbon Editor. ( To create a new button on ribbon, you can refer below link---)

http://ankit.inkeysolutions.com/2012/01/crm-2011-how-to-use-visual-ribbon.html


5. After inserting a new custom button, follow the below steps to add javascript function with parameters

· Click on Add link for specifying the “Function name” and “Library”

         a. Specify function name and library name.
         b. Click on “Add” link as shown below. It will open a list of parameter types which you can pass
             with the function.

clip_image004

As discussed earlier (refer step 2) we need 3 different parameters to call JavaScript method. Pass those values as described below. The first parameter will be the value which we have noted in step 3. The second one is entity name. And the last one is the record GUID.

clip_image005

· Now you can set Enable Rule for this button.
· Click on “Add” link and select “SelectionCountRule” in “Enable Rules” as shown below.

clip_image006

· Specify the require details as shown below.

clip_image007[4]

Due to above Rule user cannot select more than one record to launch a dialog. By default this custom ribbon button will be disabled. Once you select a record it gets enabled. Also, while user selects more than 1 record, this button gets disabled.

· Clicks on save. It will save and publish the changes on CRM server.

6. Now you can verify the button on your entity’s Homepage ribbon.

clip_image009

7. On click of this button your dialog will be launched.

clip_image011

8. Select Flight Name from the list and click next and then Finish on the last screen.

clip_image013

9. At the end, a note will be generated on Flight Route entity

image