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.




























2 comments:

  1. Hi Manjaly,

    Good Article. We are trying to use the same methodology but via a change event from the parent to the sub-grid and the update is not working!! It seems that the JSON2 is not working after the UR 13. Any inputs please.

    Regards,
    Srini

    ReplyDelete
  2. Hi
    Very Useful
    can we use this sub grid button all around CRM. for example in a user define dashbord?
    thanks

    ReplyDelete