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

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.







Thursday, 6 October 2011

How to set up Configuration Page of Solution in CRM 2011

As you all know, the new concept called 'Solution' which bundles the components was introduced in CRM 2011. In Solution, it is possible to set up a configuration page. Following are some of the possible options to make use of Configuration Page.

1. Branding.

2. Product Details

3. Advanced functionalities ( eg: Contract renewal ,validation etc )



The configuration page should be an HTML page. It must be uploaded to web resources. But remember you could refer other web resources from the HTML Page, which is a very good feature. For instance, if you need to display an image as a cool branding idea, you could upload the image to Web resources and then refer it from the HTML page.

Sample HTML:
<HTML>
<BODY contentEditable=true>
<P align=center>Contract Renewal</P>
<TABLE cellPadding=3>
<TBODY>
<TR><IMG src="alfapen.jpg"></IMG></TR>
<TR>
<TD align=right>Please Enter your Product Key<INPUT type=textbox name=license></TD>
<TD></TD>
<TD><button type="button">Continue</button></TD>
<TR>
</TBODY></TABLE></BODY></HTML>


In the above code the image is referred from the Web resources. There is a sample button on this html page. The logic (contract renewal, validation etc.) could be implemented for the click event of the button as per your idea. Or you could simply display the image or product details for branding

Well, look at the sky and that is the limit ! You could try some cool branding ideas which would make your solution Configuration page more attractive.

Here is a sample Configuration page.