"тнιѕ вℓσg ¢συℓ∂ ѕανє уσυя мσηєу ιƒ тιмє = мσηєу" - ∂.мαηנαℓу

Tuesday, 3 January 2012

How to override System Ribbon Button in CRM 2011 ( Display / Enable Rule to System Ribbon Button in CRM 2011)

This post would shed light on the following.
How to override System Ribbon Button in CRM 2011 ( Display / Enable Rule to System Ribbon Button in CRM 2011)?
How to show / hide a system button based on a value on the form?


In CRM 2011, it is possible to override the System ribbon button functionality. Also we could apply Enable / Disable Rule Display / Hide Rule to the existing System Ribbon button.
In order to grasp this quickly, lets consider a scenario.


As we all know, there is a Deactivate system ribbon button on the Account form.
Suppose we would like to Enable / Disable this button based on a value on the Account form. To make it simple, lets consider the City field. 
For instance, if the city is London, then Deactivate system button should be enabled. Also we should be able to fire our custom javascript when the Deactivate System button gets clicked. This sample could take you through very useful scenarios.


There is a key to unlock the door here. what is that key ? Lets see.


If you refer the SDK, you could find the following folder and file


sdk\resources\exportedribbonxml\accountribbon.xml


Lets find out our System Deactivate button.


Please Note: We don't need to write the following piece of code. This is just an easy way to refer and then to find the key from SDK.
<Button Id="Mscrm.Form.account.Deactivate" ToolTipTitle="$Resources:Ribbon.HomepageGrid.account.Record.Status.Deactivate" ToolTipDescription="$Resources(EntityPluralDisplayName):Ribbon.Tooltip.Deactivate" Command="Mscrm.Form.Deactivate" Sequence="60" Alt="$Resources:Ribbon.HomepageGrid.account.Record.Status.Deactivate" LabelText="$Resources:Ribbon.HomepageGrid.account.Record.Status.Deactivate" Image16by16="/_imgs/ribbon/deactivate16.png" Image32by32="/_imgs/ribbon/Deactivate_32.png" TemplateAlias="o2" />


Now can you guess what's the key in this? Its nothing but the Command.


The only key thing we need to override the System Ribbon button is to know the command value. Rest is as easy as we open a door with a valid key. We need to write the CommandDefinition as shown below.




Please make sure that the code is written under right parent tags.



          <CommandDefinition Id="Mscrm.Form.Deactivate">
            <EnableRules>
              <EnableRule Id="Mscrm.Form.account.Deactivate.EnableRule"></EnableRule>
            </EnableRules>
            <DisplayRules></DisplayRules>
            <Actions>
              <JavaScriptFunction Library="$webresource:ap_DeactivateOverride.js" FunctionName="DeactivateOverride" />
            </Actions>
          </CommandDefinition>




Also the enable rule under rule definitions as show in the above picture.

         <EnableRule Id="Mscrm.Form.account.Deactivate.EnableRule">
              <ValueRule Field="address1_city" InvertResult="false" Value="London"/>
            </EnableRule>


Here we go.


Scenario1: City value is not London -- Deactivate Button got disabled.






Scenario2: City value is London -- Deactivate Button got enabled.



Scenario3: City value is London -- Deactivate Button was clicked by the user. (alert from custom js function)




As this is my first post in 2012,

"тнєяє ѕнαℓℓ вє ѕнσωєяѕ σƒ вℓєѕѕιηg тσ уσυ αℓℓ ιη тнє вℓσωιηg ƒℓσωєя -2012"














Monday, 19 December 2011

How to Update records of a Sub-grid in CRM 2011 using OData JSON JQuery

How to Update records of a Sub-grid in CRM 2011 using OData  JSON JQuery:


Lets get the ball rolling.


Odata :"The Open Data Protocol (OData) is a Web protocol for querying and updating data that provides a way to unlock your data and free it from silos that exist in applications today" Ref: http://www.odata.org/


JSON: "JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write." Ref: http://www.json.org/


JQuery: Its used to simplify AJAX interactions


Let's consider a scenario.
On Account form we have a sub-grid. This would display the Public Relations Budgets of a company. The user could view  and select these budgets and when he / she clicks the Verify button on the ribbon, the Budget records would be updated with the following field values


Verified On --- Current Date Time
Verified By --- Logged in User.


Note: The Verify Budget button would be enabled only if the user selects one record.


Lets see how we could do this using the combination of OData, JSON and JQuery in CRM 2011


Verify Budget button in disabled state-- No records are selected in the sub-grid.




Verify Budget button in enabled state-- One record is selected in the sub-grid.



In order to achieve our target we should have js files for jquery and json. This could be easily downloaded from various resources. Nevertheless, the best way would be to get this from SDK. 
If you have latest SDK, you could find the following folder.

sdk\samplecode\js\restendpoint\jqueryrestdataoperations\jqueryrestdataoperations\scripts
The following js files were used for this example. 
jquery1.4.1.min
json2


As you all know, firstly these two js files should be added as webresources.


We need to add these to the form library of Account form as shown below.




The simplest way to understand the above stuff is to bring back the concept of header files or Library into your mind. After this step, we could use JSON notations and JQuery syntaxes whenever required.


Now lets think about the Verify Budget Button. Here is the skeleton of Verify Budget Button.
Note: Even though we are on the Account form, the following ribbondiffxml has to be added under the Budget entity ( Remember that items of Sub-grid belongs to Budget entity)




For your convenience, I have pasted the code below.



<RibbonDiffXml>
        <CustomActions>
          <CustomAction Id="Mscrm.SubGrid.ap_budget.verify" Sequence="60" Location="Mscrm.SubGrid.ap_budget.MainTab.Management.Controls._children">
            <CommandUIDefinition>
              <Button Id="Mscrm.SubGrid.ap_budget.verifybutton" TemplateAlias="o1" Image16by16="$webresource:ap_btn.png" Image32by32="$webresource:ap_btn.png" 
                      LabelText="$LocLabels:Mscrm.SubGrid.ap_budget.verify.LabelText" ToolTipTitle="$LocLabels:Mscrm.SubGrid.ap_budget.verify.Tooltip" 
                      ToolTipDescription="$LocLabels:Mscrm.SubGrid.ap_budget.verify.TooltipDescription" Command="Mscrm.SubGrid.ap_budget.verify.Command" />
            </CommandUIDefinition>
          </CustomAction>
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.Edit.HideId" Location="Mscrm.SubGrid.ap_budget.Edit" />
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.Delete.HideId" Location="Mscrm.SubGrid.ap_budget.Delete" />
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.Deactivate.HideId" Location="Mscrm.SubGrid.ap_budget.Deactivate" />
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.Activate.HideId" Location="Mscrm.SubGrid.ap_budget.Activate" />
          <HideCustomAction HideActionId="Mscrm.SubGrid.ap_budget.BulkDelete.HideId" Location="Mscrm.SubGrid.ap_budget.BulkDelete" />
        </CustomActions>
        <Templates>
          <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
        </Templates>
        <CommandDefinitions>
          <CommandDefinition Id="Mscrm.SubGrid.ap_budget.verify.Command">
            <EnableRules>
              <EnableRule Id="Mscrm.SubGrid.ap_budget.verify.EnableRule"></EnableRule>
            </EnableRules>
            <DisplayRules></DisplayRules>
            <Actions>
              <JavaScriptFunction Library="$webresource:ap_verify.js" FunctionName="VerifyBudget" />
            </Actions>
          </CommandDefinition>
        </CommandDefinitions>
        <RuleDefinitions>
          <TabDisplayRules />
          <DisplayRules />
          <EnableRules>
            <EnableRule Id="Mscrm.SubGrid.ap_budget.verify.EnableRule">
              <SelectionCountRule AppliesTo="SelectedEntity" Minimum="1"></SelectionCountRule>
            </EnableRule>
          </EnableRules>
        </RuleDefinitions>
        <LocLabels>
          <LocLabel Id="Mscrm.SubGrid.ap_budget.verify.LabelText">
            <Titles>
              <Title languagecode="1033" description="Verify Budget" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Mscrm.SubGrid.ap_budget.verify.Tooltip">
            <Titles>
              <Title languagecode="1033" description="Verify Budget" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Mscrm.SubGrid.ap_budget.verify.TooltipDescription">
            <Titles>
              <Title languagecode="1033" description="Verify Budget" />
            </Titles>
          </LocLabel>
        </LocLabels>
      </RibbonDiffXml>


Now lets traverse through JS code.
Please note the comments along with the code.
function VerifyBudget()
{


    var gridControl = document.getElementById("PubilcRelationsBudget").control;
    var ids = gridControl.get_selectedIds(); // Get the selected Ids of Sub-Grid
    for (i = 0; i < ids.length; i++)
 {


        var budgetToVerify= new Object(); // object to be sent to CRM
        var currentDate = new Date();
        var formatDate = new Date(currentDate);
        budgetToVerify.ap_verifiedon = formatDate;
        budgetToVerify.ap_verifiedby = { Id: Xrm.Page.context.getUserId(), Name: "", LogicalName: "systemuser" };  // You could keep the name empty in this case
        var jsonEntity = window.JSON.stringify(budgetToVerify);


        var ODataPath = Xrm.Page.context.getServerUrl() + "/XrmServices/2011/OrganizationData.svc/ap_budgetSet";
        var id = ids[i].replace("{", "").replace("}", "");
//AJAX Call using JQuery syntax. Please note the type--POST. To post something to CRM
//To update a record you must pass GUID which is the identifier of the record.
//For retrieval type would be GET
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            data: jsonEntity,
            url: ODataPath + "(guid'" + id + "')",
            beforeSend: function (XMLHttpRequest) {
                XMLHttpRequest.setRequestHeader("Accept", "application/json");
                XMLHttpRequest.setRequestHeader("X-HTTP-Method", "MERGE");
            },
            success: function (data, textStatus, XmlHttpRequest) {
// Refresh the Sub-Grid to reflect the changes.


                document.getElementById("PubilcRelationsBudget").control.refresh();
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) { }
        });


    }
}







Here is your pie.




























Tuesday, 13 December 2011

How to refresh a Sub-Grid in CRM 2011 using Javascript

Code Snippet:
gridControl = Xrm.Page.ui.controls.get("yourSubGridName");
gridControl.refresh();
Alternatively, you could use the following.
document.getElementById("yourSubGridName").control.refresh();

Monday, 12 December 2011

How to retrieve the Selected Record Ids of a Sub Grid in CRM 2011 using javascript

How to retrieve the Selected Record Ids of a Sub Grid in CRM 2011 using javascript
Code Snippet:
    var gridControl = document.getElementById("yourSubGridName").control;
    var ids = gridControl.get_selectedIds();

Saturday, 3 December 2011

How to hide Left Navigation items of a Form in CRM 2011

Related post : http://crmdm.blogspot.com/2011/02/editing-form-left-navigation-items-drag.html


Its possible to hide the entire left navigation items of a form in CRM 2011.
For instance, consider a custom entity called Budget.
Following is the form with left navigation.



Now lets see where is the setting to be done for this. Well, its on the form properties as shown below.


And here is the form without any left navigation items.


"Easy Peasy Lemon Squeezy"


Tuesday, 22 November 2011

Developer Toolkit For CRM 2011 Download

Microsoft released the Developer Toolkit for CRM 2011. It could be downloaded along with the latest SDK. The download link is 


The Developer Toolkit could be found in the downloaded   sdk\tools\developertoolkit   folder.

You could also find a post in this blog which does the walkthrough of the beta version of Developer Toolkit for CRM 2011.



Saturday, 5 November 2011

Customize Ribbon Tab, Group, Button in CRM 2011 OR How to insert a custom tab at Ribbon area in CRM 2011

Let's see how to customize a ribbon tab in CRM 2011 with a group and a few buttons in it. Remember there are some pitfalls while customizing ribbon tab in CRM 2011. So we are going to crack the nut.


In the following screen shot, please note the following.


1. Tab - Departments
2. Group 1- Marketing
3. Group 2.- Sales
4. Button Legal under Marketing Group
5. Button Public Relations under Marketing under Marketing Group
6. Button Customer under Sales under Sales Group





So obviously the hierarchy is 

Tab--Group--Button

So our nut is " Place a new tab for Account entity form with groups Marketing (2 buttons) and Sales (1 button)"

Lets have a look at the customization.xml. Our playground is the area under RibbonDiffXml.

To make it more simple, lets have a broad view at 4 main regions.

1. Custom Actions -- Where you could define tab, group ,button etc
2. Command definitions -Where you could define the action on the button or group
3. Rule Definitions-- Show / Hide or Enable Disable rule definitions
4. LocLabels --For Localization of labels.

So first we would have a look at the 1.Custom Actions 

Pitfall : Scaling
Scaling is one of the pitfalls.  Scaling defines how the groups are presented to the Ribbon. There is a tag called Maxsize which defines largest layout possible for a group. Now the pitfall is, if you have 2 groups you must define 2 Maxsize as shown. Otherwise it would display tab, group but no buttons on it.

Secondly, 2. Command Definitions


Please note the bridge between the Custom Action and Command Definition is Command ID.
While defining a tab, group or button we are defining a Command.

Pitfall: If you define a command for tab, group or button, you should use the same as Command ID in Command definition to define an action.

Here we are calling javascript function in Actions. You could also define DisplayRules and EnableRules if you want to.

Now we are into 3rd level , 3. Rule Definitions.


This shows how we could define the display rule for a tab. In our case we would like to display the tab ONLY on the entity form. So the context is Form

Following are possible scope of Context:

Form --For the form ribbon.

HomePageGrid---For the ribbon that is displayed for the list of records that appear in the main application navigation pane.

SubGridStandard --For the ribbon that is displayed for the list of records that appear in a subgrid in a form.

SubGridAssociated ---For the ribbon that is displayed for the list of records that appear in the navigation area of a form.



and thus we reached 4th level which is 4. LocLabels.

This is very simple and its used for Localization of labels. Remember the fact that ID is the link to refer these labels.


For your convenience, the whole code is given below.

<RibbonDiffXml>
        <CustomActions>
          <CustomAction Id="Mscrm.Isv.GlobalCustomAction" Location="Mscrm.Tabs._children" Sequence="100">
            <CommandUIDefinition>
              <Tab Id="account.DepartmentsTab" Command="Mscrm.account.DepartmentsTab" Description="$LocLabels:Account.Form.Departments.LabelText" Title="$LocLabels:Account.Form.Departments.LabelText" Sequence="1000">
                <Scaling Id="account.DepartmentsTab.Scaling">
                  <MaxSize Id="account.DepartmentsTab.Group0.MaxSize" Sequence="10" GroupId="account.DepartmentsTab.Group0" Size="Large" />
                  <MaxSize Id="account.DepartmentsTab.Group1.MaxSize" Sequence="20" GroupId="account.DepartmentsTab.Group1" Size="Large" />
                </Scaling>
                <Groups Id="account.DepartmentsTab.Groups">
                  <Group Id="account.DepartmentsTab.Group0" Sequence="10" Command="account.DepartmentsTab.Group0" Description="$LocLabels:Account.Form.Marketing.LabelText" Title="$LocLabels:Account.Form.Marketing.LabelText" Template="Mscrm.Templates.Flexible">
                    <Controls Id="account.DepartmentsTab.Group0.Controls"></Controls>
                  </Group>
                  <Group Id="account.DepartmentsTab.Group1" Sequence="11" Command="account.DepartmentsTab.Group1" Description="$LocLabels:Account.Form.Sales.LabelText" Title="$LocLabels:Account.Form.Sales.LabelText" Template="Mscrm.Templates.Flexible">
                    <Controls Id="account.DepartmentsTab.Group1.Controls"></Controls>
                  </Group>
                </Groups>
              </Tab>
            </CommandUIDefinition>
          </CustomAction>
          <CustomAction Id="Mscrm.Form.account.Legal" Sequence="55" Location="account.DepartmentsTab.Group0.Controls._children">
            <CommandUIDefinition>
              <Button Id="Mscrm.Form.account.LegalButton" TemplateAlias="o1" Image16by16="$webresource:ap_btn.png" Image32by32="$webresource:ap_btn.png" LabelText="$LocLabels:Account.Form.Legal.LabelText" ToolTipTitle="$LocLabels:Account.Form.Legal.Tooltip" ToolTipDescription="$LocLabels:Account.Form.Legal.TooltipDescription" Command="Mscrm.Form.account.Legal.Command" />
            </CommandUIDefinition>
          </CustomAction>
          <CustomAction Id="Mscrm.Form.account.PublicRelations" Sequence="55" Location="account.DepartmentsTab.Group0.Controls._children">
            <CommandUIDefinition>
              <Button Id="Mscrm.Form.account.PublicRelationsButton" Image16by16="$webresource:ap_btn.png" Image32by32="$webresource:ap_btn.png" TemplateAlias="o1" LabelText="$LocLabels:Account.Form.PublicRelations.LabelText" ToolTipTitle="$LocLabels:Account.Form.PublicRelations.Tooltip" ToolTipDescription="$LocLabels:Account.Form.PublicRelations.TooltipDescription" Command="Mscrm.Form.account.PublicRelations.Command" />
            </CommandUIDefinition>
          </CustomAction>
          <CustomAction Id="Mscrm.Form.account.Customer" Sequence="55" Location="account.DepartmentsTab.Group1.Controls._children">
            <CommandUIDefinition>
              <Button Id="Mscrm.Form.account.CustomerButton" Image16by16="$webresource:ap_btn.png" Image32by32="$webresource:ap_btn.png" TemplateAlias="o1" LabelText="$LocLabels:Account.Form.Customer.LabelText" ToolTipTitle="$LocLabels:Account.Form.Customer.Tooltip" ToolTipDescription="$LocLabels:Account.Form.Customer.TooltipDescription" Command="Mscrm.Form.account.Customer.Command" />
            </CommandUIDefinition>
          </CustomAction>
        </CustomActions>
        <Templates>
          <RibbonTemplates Id="Mscrm.Templates"></RibbonTemplates>
        </Templates>
        <CommandDefinitions>
          <CommandDefinition Id="account.DepartmentsTab.Group0">
            <EnableRules />
            <DisplayRules />
            <Actions />
          </CommandDefinition>
          <CommandDefinition Id="account.DepartmentsTab.Group1">
            <EnableRules />
            <DisplayRules />
            <Actions />
          </CommandDefinition>
          <CommandDefinition Id="Mscrm.Form.account.Legal.Command">
            <EnableRules></EnableRules>
            <DisplayRules>
            </DisplayRules>
            <Actions>
              <JavaScriptFunction Library="$webresource:ap_legal.js" FunctionName="Legal" />
            </Actions>
          </CommandDefinition>
          <CommandDefinition Id="Mscrm.Form.account.PublicRelations.Command">
            <EnableRules></EnableRules>
            <DisplayRules>
            </DisplayRules>
            <Actions>
              <JavaScriptFunction Library="$webresource:ap_publicrelations.js" FunctionName="PublicRelations" />
            </Actions>
          </CommandDefinition>
          <CommandDefinition Id="Mscrm.Form.account.Customer.Command">
            <EnableRules></EnableRules>
            <DisplayRules>
            </DisplayRules>
            <Actions>
              <JavaScriptFunction Library="$webresource:ap_customer.js" FunctionName="Customer" />
            </Actions>
          </CommandDefinition>
        </CommandDefinitions>
        <RuleDefinitions>
          <TabDisplayRules>
            <TabDisplayRule TabCommand="Mscrm.account.DepartmentsTab">
              <EntityRule EntityName="account" Context="Form" />
            </TabDisplayRule>
          </TabDisplayRules>
          <DisplayRules />
          <EnableRules />
        </RuleDefinitions>
        <LocLabels>
          <LocLabel Id="Account.Form.Departments.LabelText">
            <Titles>
              <Title languagecode="1033" description="Departments" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Departments.Tooltip">
            <Titles>
              <Title languagecode="1033" description="Departments" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Departments.TooltipDescription">
            <Titles>
              <Title languagecode="1033" description="Departments" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Marketing.LabelText">
            <Titles>
              <Title languagecode="1033" description="Marketing" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Marketing.Tooltip">
            <Titles>
              <Title languagecode="1033" description="Marketing" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Marketing.TooltipDescription">
            <Titles>
              <Title languagecode="1033" description="Marketing" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Sales.LabelText">
            <Titles>
              <Title languagecode="1033" description="Sales" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Sales.Tooltip">
            <Titles>
              <Title languagecode="1033" description="Sales" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Sales.TooltipDescription">
            <Titles>
              <Title languagecode="1033" description="Sales" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Legal.LabelText">
            <Titles>
              <Title languagecode="1033" description="Legal" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Legal.Tooltip">
            <Titles>
              <Title languagecode="1033" description="Legal" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Legal.TooltipDescription">
            <Titles>
              <Title languagecode="1033" description="Legal" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.PublicRelations.LabelText">
            <Titles>
              <Title languagecode="1033" description="Public Relations" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.PublicRelations.Tooltip">
            <Titles>
              <Title languagecode="1033" description="Public Relations" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.PublicRelations.TooltipDescription">
            <Titles>
              <Title languagecode="1033" description="Public Relations" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Customer.LabelText">
            <Titles>
              <Title languagecode="1033" description="Customer" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Customer.Tooltip">
            <Titles>
              <Title languagecode="1033" description="Customer" />
            </Titles>
          </LocLabel>
          <LocLabel Id="Account.Form.Customer.TooltipDescription">
            <Titles>
              <Title languagecode="1033" description="Customer" />
            </Titles>
          </LocLabel>
        </LocLabels>
      </RibbonDiffXml>



So here is our cracked nut.