Tag Archives: java script

How-To Series 10: How To get Selected Record Entity Name from Activities or Queue Item Entity Home Page Grid

Hi All,
           We know that we can use “SelectedEntityTypeName” to get the selected record’s “Entity Name” in a Grid. This is useful for every entity with an exception to couple of entities like “Queue Item” and “Acitivity” HomePage Grids as these will display records belongs to more than one entity. For an instance, “Activities” will display “EMail, Phonecall, Appointment etc..”. 
           So, if you want to retireve the selected record’s entity name then use the following function. The following function requires all the views in the grid to have the entity name as one of the column at the same location. It will retrieve selected record’s Id along with its entity name. Its the same way we used to do in CRM 4.0’s ISV.Config.
function ShowSelectedIdsWithEntityName()
{
var selectedrecords = document.all[‘crmGrid’].InnerGrid.SelectedRecords;
for (var i=0; i < selectedrecords.length; i++)
{
//This will return the selected record guid
alert(“Selected Record Id: “+selectedrecords [i][0]);
// This will return the 5th column data. OOB, in “Queue Item” entity “Type(Entity Name)” is the 5th column for all views.
alert(“Selected Entity Name: “+selectedrecords [i][3].cells[4].innerText);
}
}

Following is for “Queue Item” entity.
 

Hope it helps….

Cheers
Vikranth P.

How To – Series 8: Cross Domain Issue while working with CRM 2011 Web Services in JScript

Back to blogging after long time. Recently I faced a “Cross Domain” issue while working with Jscript ODATA query. Below is the code which I have used:
    var ODATA_ENDPOINT = “/XRMServices/2011/OrganizationData.svc”;
    var context = GetGlobalContext();
    var serverUrl = context.getServerUrl();
   
    //Asynchronous AJAX function to Retrieve a CRM record using OData
    $.ajax({
        type: “GET”,
        contentType: “application/json; charset=utf-8”,
        datatype: “json”,
        url: serverUrl + ODATA_ENDPOINT + “/AccountSet?$filter=Address1_City eq ‘Redmond'”,
        beforeSend: function (XMLHttpRequest)
        {
            XMLHttpRequest.setRequestHeader(“Accept”, “application/json”);
        },
        success: function (data, textStatus, XmlHttpRequest)
        {
              // Success Call Back
        },
        error: function (XmlHttpRequest, textStatus, errorThrown)
        {
              // Error Call Back
        }
    });
The REST End point “url “ which I am passing in the above code is: http://<server>/<orgname>/XRMServices/2011/OrganizationData.svc/AccountSet?$filter=Address1_City eq ‘Redmond’.This code only works when we open CRM records using CRM “Server” name. It fails in other cases like when we open it using IP Address or localhost. The primary reason for this is due to “Cross Domain Policy”. The blocker is the REST End point which we are using. 
So, I thought of replacing server name with IP Address as follows.
I ran it in the browser…. It worked…!!!! J
So, I got a simple solution. 
Use the following instead of getting “ServerUrl” from the context object.
    var serverUrl = window.location.protocol + “//” + window.location.host + “/” + context.getOrgUniqueName();
Here we just need to use the window.location property to get the current window protocol and host and build the REST Endpoint.
Hope it helps…!!!! Please let me know if we have any other alternative solution. 
Cheers
Vikranth Pandiri.

How To – Series 7: How To override(Enable, Disable, Show, Hide, Custom Logic) Out of the Box HomePageGrid ribbon elements – CRM 2011

Hope my earlier posts on Ribbon elements helps you. In this post we will see how to Enable/Disable Out of the Box ribbon elements in Dynamics CRM 2011. After going through the SDK, it seems there is no direct solution to override existing <CommandDefinition>. However, the documention says using <CustomAction> we can Add or Replace items in the ribbon. It gives me an idea to replace existing OOB(Out of the Box) ribbon item with Custom ribbon item and define our own <CommandDefinition> for that. At the same time we can also go with the OOB <CommandDefinition>. Lets see how we can do that stuff.

Lets consider “Edit” ribbon item on the “Account” entity “HomePageGrid”. I want to disable this “Edit” button when user selects more than one record in the sub grid(i.e I don’t want “Bulk Edit” feature for Account records). The same can be achieved with security roles. However, for the sake of simplicity and to focus more on how we can override <EnableRules>, <DisplayRules> and <Actions> for an OOB item I have considered this scenario.

 

Step 1:

 

Open “accounribbon.xml” file from the “sdksamplecodecsclientribbonexportribbonxmlexportedribbonxml” location in the CRM 2011 SDK.

 

Below is the definition for “Edit” button

 

<Button Id=”Mscrm.HomepageGrid.account.Edit” ToolTipTitle=”$Resources:Ribbon.HomepageGrid.MainTab.Management.Edit” ToolTipDescription=”$Resources(EntityDisplayName):Ribbon.Tooltip.Edit” Command=”Mscrm.EditSelectedRecord” Sequence=”20″ LabelText=”$Resources:Ribbon.HomepageGrid.MainTab.Management.Edit” Alt=”$Resources:Ribbon.HomepageGrid.MainTab.Management.Edit” Image16by16=”/_imgs/ribbon/Edit_16.png” Image32by32=”/_imgs/ribbon/edit32.png” TemplateAlias=”o1″ />

 

 

Below is the <CommandDefinition> for “Edit” button.

 

 

<CommandDefinition Id=”Mscrm.EditSelectedRecord”>

 

        <EnableRules>

 

          <EnableRule Id=”Mscrm.CheckBulkEditSupportForEntity” />

 

          <EnableRule Id=”Mscrm.VisualizationPaneNotMaximized” />

 

        </EnableRules>

 

        <DisplayRules>

 

          <DisplayRule Id=”Mscrm.BulkEditPrivilege” />

 

          <DisplayRule Id=”Mscrm.WriteSelectedEntityPermission” />

 

        </DisplayRules>

 

        <Actions>

 

          <JavaScriptFunction FunctionName=”Mscrm.GridRibbonActions.bulkEdit” Library=”/_static/_common/scripts/RibbonActions.js”>

 

            <CrmParameter Value=”SelectedControl” />

 

            <CrmParameter Value=”SelectedControlSelectedItemReferences” />

 

            <CrmParameter Value=”SelectedEntityTypeCode” />

 

          </JavaScriptFunction>

 

        </Actions>

 

      </CommandDefinition>

 

 

Copy both of the definitions and we gonna use them in the next steps.

 

Step 2:

 

Add “Account” entity to a solution. Export it. Open “Customizations.xml” file.

 

Go to <EnableRules> section and add following <EnableRule> which will return “true” when only one item is selected in the sub grid.

 

 

   <EnableRule Id=”Sample.account.grid.OnSelection.EnableRule”>

 

              <SelectionCountRule AppliesTo=”SelectedEntity” Maximum=”1″ Minimum=”1″/>

 

            </EnableRule>

 

 

Step 3:

 

 

Go to <CommandDefinitions> section and add copied <CommandDefintion> form the Step1. Rename “Id” value to “Sample.account.grid.DisableExisting.Command”

 

<CommandDefinition Id=”Mscrm.EditSelectedRecord”>

 

        <EnableRules>

 

          <EnableRule Id=”Mscrm.CheckBulkEditSupportForEntity” />

 

          <EnableRule Id=”Mscrm.VisualizationPaneNotMaximized” />

 

        </EnableRules>

 

        <DisplayRules>

 

          <DisplayRule Id=”Mscrm.BulkEditPrivilege” />

 

          <DisplayRule Id=”Mscrm.WriteSelectedEntityPermission” />

 

        </DisplayRules>

 

        <Actions>

 

          <JavaScriptFunction FunctionName=”Mscrm.GridRibbonActions.bulkEdit” Library=”/_static/_common/scripts/RibbonActions.js”>

 

            <CrmParameter Value=”SelectedControl” />

 

            <CrmParameter Value=”SelectedControlSelectedItemReferences” />

 

            <CrmParameter Value=”SelectedEntityTypeCode” />

 

          </JavaScriptFunction>

 

        </Actions>

 

      </CommandDefinition>

 

 

Add    <EnableRule Id=”Sample.account.grid.OnSelection.EnableRule”/> to the <EnableRules> section.

 

 

<CommandDefinition Id=”Mscrm.EditSelectedRecord”>

 

        <EnableRules>

 

          <EnableRule Id=”Mscrm.CheckBulkEditSupportForEntity” />

 

          <EnableRule Id=”Mscrm.VisualizationPaneNotMaximized” />

 

          <EnableRule Id=”Sample.account.grid.OnSelection.EnableRule”/>

 

        </EnableRules>

 

        <DisplayRules>

 

          <DisplayRule Id=”Mscrm.BulkEditPrivilege” />

 

          <DisplayRule Id=”Mscrm.WriteSelectedEntityPermission” />

 

        </DisplayRules>

 

        <Actions>

 

          <JavaScriptFunction FunctionName=”Mscrm.GridRibbonActions.bulkEdit” Library=”/_static/_common/scripts/RibbonActions.js”>

 

            <CrmParameter Value=”SelectedControl” />

 

            <CrmParameter Value=”SelectedControlSelectedItemReferences” />

 

            <CrmParameter Value=”SelectedEntityTypeCode” />

 

          </JavaScriptFunction>

 

        </Actions>

 

      </CommandDefinition>

 

 

 

Step 4:

 

 

Add following <CustomAction> to the <CustomActions> section:

 

 

          <CustomAction Id=”Sample.account.grid.DisableExisting.CustomAction” Location=”Mscrm.HomepageGrid.account.Edit” Sequence=”21″>

 

            <CommandUIDefinition>

 

              <Button Id=”Mscrm.HomepageGrid.account.Edit” Command=”Sample.account.grid.DisableExisting.Command” LabelText=”$Resources:Ribbon.HomepageGrid.MainTab.Management.Edit” Alt=”$Resources:Ribbon.HomepageGrid.MainTab.Management.Edit” ToolTipTitle=”$Resources:Ribbon.HomepageGrid.MainTab.Management.Edit” ToolTipDescription=”$Resources(EntityDisplayName):Ribbon.Tooltip.Edit” TemplateAlias=”o1″ Image16by16=”$webresource:new_/icons/TIcon16x16.png” Image32by32=”$webresource:new_/icons/TIcon32x32.png” />

 

            </CommandUIDefinition>

 

          </CustomAction>

 

 

Here we need to carefully observe what we have done to replace existing “Edit” button with our own Custom Button.

 

<CustomAction Id=”Sample.account.grid.DisableExisting.CustomAction” Location=”Mscrm.HomepageGrid.account.Edit” Sequence=”21″>

 

 

Here I have given  unique id for the <CustomAction> and for the “Location” attribute I have placed “Id” of the OOB “Edit” button only. I haven’t kept “._children”. This makes all the difference…

 

 

<Button Id=”Mscrm.HomepageGrid.account.Edit” Command=”Sample.account.grid.DisableExisting.Command” LabelText=”$Resources:Ribbon.HomepageGrid.MainTab.Management.Edit” Alt=”$Resources:Ribbon.HomepageGrid.MainTab.Management.Edit” ToolTipTitle=”$Resources:Ribbon.HomepageGrid.MainTab.Management.Edit” ToolTipDescription=”$Resources(EntityDisplayName):Ribbon.Tooltip.Edit” TemplateAlias=”o1″ Image16by16=”$webresource:new_/icons/TIcon16x16.png” Image32by32=”$webresource:new_/icons/TIcon32x32.png” />

 

 

Here, I have given OOB “Edit” button “Id” as the “Id” for the new item. Do remember that, “Id” value in the <Button> should be same as “Id” value in the <CustomAction>. In other words the new Ribbon Item should have same “Id” as the OOB item.

 

For the “Command” attribute I am planning to use OOB Command that has been defined for the “Edit” item. I am planning to use OOB features and in addition to that I am planning to have my own <EnableRules>, <DisplayRules> and <Actions> rules. Feel free to use your own Command if you require to.

 

For remaining attributes also I wish to go with OOB except for the Images. Here I want to show images from my web resource.

 

Now, Import the solution with these changes to your system. Below is the result:

When no recod is selected:

When One record is selected:
When multiple records are selected
In this way we can override OOB behaviors and visualizations for OOB ribbon elements. If you want to have more complex queries for the <EnableRule> then we can use <CustomRule> to call a JScript function. Please see my earlier post here: http://howto-mscrm.com/2011/04/how-to-series-6-how-to-use-customrule.html on how to use <CustomRule> with “HomePageGrid”.
Hope it helps everyone. 🙂

Cheers…!!!
Vikranth Pandiri.

How To – Series 4: How to make an Associated View IFrame Mandatory

Sometimes, we came across situations to make an Associated View IFrame to be mandatory. However, it is very easy to implement. There are two approaches. First one is, using Java Script to call a web service and check whether current record has at least one associated record. And the second approach is just check whether an IFrame which is used to display associated records has at least one record in it’s grid. The latter approach is very easy to implement and here we go:
1.       In the onSave event of crmForm, just check how many records the IFrame grid has
2.       If the count is less than one, cancel the Save event and alert the user
3.       Set the focus to the “Add Existing Button” of the crmGrid.
function ValidateIFrame()
{
if (crmForm.all.IFRAME_ MyIFrame.readyState == “complete”)
{
if (document.frames(“IFRAME_ MyIFrame”).document.all[‘crmGrid’].InnerGrid.NumberOfRecords < 1)
{
event.returnValue=false;
alert(“Please Select Records”);
var oaddexist=document.frames(‘IFRAME_ MyIFrame’).document.getElementById(‘<id of the add existing button>’);
if(oaddexist)
{
oaddexist.focus();
}
}
}
}
}
if(crmForm.all.IFRAME_MyIFrame)
{
ValidateIFrame();
}

Hope it helps…

Thanks
Vikranth P.

How To – Series 3: How to bulk Activate/Reactivate Dynamics CRM Records using CRM Update Web Service in Java Script

 Today I wish to share with you the frequently needed functionality “how to bulk Activate/Reactivate records on ISV Toolbar button click”.  This involves following simple steps to be performed.
1.       Creating an ISV button on the crmGrid
2.       Retrieving selected record’s GUIDs
3.       Updating the state of the selected records using CRM Update Service
Lets start with creating a Toolbar button on CRM grid. It is simple and straight forward. Just add following lines of code to the respective entity in the ISV.Config.

1.       Creating an ISV button on the “Lead” entity’s crmGrid
<Entity name=”lead”>
          <ToolBar ValidForCreate=”0″ ValidForUpdate=”1″>
            <Button Icon=”/_imgs/ico_18_debug.gif” JavaScript=”alert(“Your JavaScript code will be here”)”>
              <Titles>
                <Title LCID=”1033″ Text=”Reactivate” />
              </Titles>
              <ToolTips>
                <ToolTip LCID=”1033″ Text=”Reactivate” />
              </ToolTips>
            </Button>
          </ToolBar>
</Entity> />

2.       Retrieving selected record’s GUIDs
var selectedrecords = document.all[‘crmGrid’].InnerGrid.SelectedRecords;
var selectedItems = new Array(selectedrecords.length);
for (var r=0; i < selectedrecords.length; i++)
{
 selectedItems[r] = selectedrecords [r][0];
}
                Selectedrecords[r][0] returns guid of the respected selected records
3.       Updating the state of the selected records using CRM Update Service
In order to change/set state of the “Lead” record we have to use “SetStateLeadRequest” class which has following fields EntityId, LeadState and LeadStatus. We need to pass an instance of this class as a request parameter to Execute() method. Check the possible state and status values for “Lead” entity in msdn documentation here
The possible state and status code for “Lead” entity in our requirement is “Open” and “New/Contacted”. We can also give statuscode as “-1” so that respective statuscode will be taken as required.
Below is the MS CRM Update Web Service Method code to reactivate closed leads
var xml = &apos;&apos; +
 &apos;&lt;?xml version=&apos;1.0&apos; encoding=&apos;utf-8&apos;?&gt;&apos; +
 &apos;&lt;soap:Envelope xmlns:soap=&apos;http://schemas.xmlsoap.org/soap/envelope/&apos;
 xmlns:xsi=&apos;http://www.w3.org/2001/XMLSchema-instance&apos;
 xmlns:xsd=&apos;http://www.w3.org/2001/XMLSchema&apos;&gt;&apos;
 +  GenerateAuthenticationHeader()
  + &apos; &lt;soap:Body&gt;&apos;
  +  &apos; &lt;Execute xmlns=&apos;http://schemas.microsoft.com/crm/2007/WebServices&apos;&gt;&apos; +
 &apos; &lt;Request xsi:type=&apos;SetStateLeadRequest&apos;&gt;&apos; + &apos; &lt;EntityId&gt;&apos;+<selectedItemGUID>+&apos;&lt;/EntityId&gt;&apos; + &apos; &lt;LeadState&gt;Open&lt;/LeadState&gt;&apos; + &apos; &lt;LeadStatus&gt;-1&lt;/LeadStatus&gt;&apos; + &apos; &lt;/Request&gt;&apos; + &apos; &lt;/Execute&gt;&apos; + &apos; &lt;/soap:Body&gt;&apos; + &apos;&lt;/soap:Envelope&gt;&apos; + &apos;&apos;;
 var xmlHttpRequest = new ActiveXObject(&apos;Msxml2.XMLHTTP&apos;);
 xmlHttpRequest.Open(&apos;POST&apos;,&apos;/mscrmservices/2007/CrmService.asmx&apos;, false);
 xmlHttpRequest.setRequestHeader(&apos;SOAPAction&apos;,&apos;http://schemas.microsoft.com/crm/2007/WebServices/Execute&apos;);
 xmlHttpRequest.setRequestHeader(&apos;Content-Type&apos;, &apos;text/xml; charset=utf-8&apos;);
 xmlHttpRequest.setRequestHeader(&apos;Content-Length&apos;, xml.length);
 xmlHttpRequest.send(xml);
 var resultXml = xmlHttpRequest.responseXML;
Here I am setting SetStateLeadRequest’s EntityId to selected record’s GUID, LeadState to Open and LeadStatus to -1. This code snippet will does reactivate the specified GUID Lead record.
Now, finally we need to wire above three steps code together so that selected grid records will be reactived when crm grid toolbar’s button is clicked. Below is the final version of the code which you can directly use it in your ISV.config file. Here I kept CRM Update webservice code snippet inside the for loop of selected grid items so that update web service will be called with each selected record’s GUID.
<Entity name=”lead”>
<Grid>
<MenuBar>
<Buttons>
<Button Icon=”/_imgs/ico_18_debug.gif” JavaScript=”var a = document.all[‘crmGrid’].InnerGrid.SelectedRecords; var selectedItems = new Array(a.length); for (var i=0; i &lt; a.length; i++) { selectedItems[i] = a[i][0]; var xml = &apos;&apos; + &apos;&lt;?xml version=&apos;1.0&apos; encoding=&apos;utf-8&apos;?&gt;&apos; + &apos;&lt;soap:Envelope xmlns:soap=&apos;http://schemas.xmlsoap.org/soap/envelope/&apos; xmlns:xsi=&apos;http://www.w3.org/2001/XMLSchema-instance&apos; xmlns:xsd=&apos;http://www.w3.org/2001/XMLSchema&apos;&gt;&apos; + GenerateAuthenticationHeader() + &apos; &lt;soap:Body&gt;&apos; + &apos; &lt;Execute xmlns=&apos;http://schemas.microsoft.com/crm/2007/WebServices&apos;&gt;&apos; + &apos; &lt;Request xsi:type=&apos;SetStateLeadRequest&apos;&gt;&apos; + &apos; &lt;EntityId&gt;&apos;+selectedItems[i]+&apos;&lt;/EntityId&gt;&apos; + &apos; &lt;LeadState&gt;Open&lt;/LeadState&gt;&apos; + &apos; &lt;LeadStatus&gt;-1&lt;/LeadStatus&gt;&apos; + &apos; &lt;/Request&gt;&apos; + &apos; &lt;/Execute&gt;&apos; + &apos; &lt;/soap:Body&gt;&apos; + &apos;&lt;/soap:Envelope&gt;&apos; + &apos;&apos;; var xmlHttpRequest = new ActiveXObject(&apos;Msxml2.XMLHTTP&apos;); xmlHttpRequest.Open(&apos;POST&apos;,&apos;/mscrmservices/2007/CrmService.asmx&apos;, false); xmlHttpRequest.setRequestHeader(&apos;SOAPAction&apos;,&apos;http://schemas.microsoft.com/crm/2007/WebServices/Execute&apos;); xmlHttpRequest.setRequestHeader(&apos;Content-Type&apos;, &apos;text/xml; charset=utf-8&apos;); xmlHttpRequest.setRequestHeader(&apos;Content-Length&apos;, xml.length); xmlHttpRequest.send(xml); var resultXml = xmlHttpRequest.responseXML;} window.crmGrid.Refresh();”>
<Titles>
<Title LCID=”1033″ Text=”Reactivate” />
</Titles>
<ToolTips>
<ToolTip LCID=”1033″ Text=”Reactivate” />
</ToolTips>
</Button>
</Buttons>
</MenuBar>
</Grid>
</Entity>
Hope it helps you…
Vikranth P

How To – Series 1: How to add/change filter criteria of a Lookup field in Java Script

Hi all… This is my first blog post in How-To Series.

Let’s consider a scenario, where we have three picklist fields on a form and the Lookup filed search criteria is depended on selected picklist values. For an instance, if we have Account Type, Product Type and Call Type as picklists and the requirement is like by the time user clicks on the Lookup filed it should have below as the filter criteria

1. Include only the picklists whose value is selected
2. If none of the picklist is selected then display all active records

Below is the code which needs to be placed in the onLoad of the crmForm. As the fetchxml code needs to be changed as per the user picklist selection, I have declared four variables named param, headparam, tailparam and bodyparam. In which bodyparam content is changing as per the user selection. Finally I am concatenating headparam, bodyparam and tailparam to generate required fetchxml code. I am implementing entire code as a function so that it can be called from the picklist’s onchange events instead copy and pasting entire code each and every place.

crmForm.lookupquery = function xyz() {
var field = crmForm.all.abaxis_lookupid;
    field.lookupbrowse = 1;
    var headparam = “<fetch mapping=’logical’><entity name=’new_myentity’><all-attributes /><filter type=’and’>”;
    var tailparam = “</filter></entity></fetch>”;
    var bodyparam = “”;
    var param = “”;
    if (crmForm.all.new_plproducttype.DataValue != null)
        bodyparam = bodyparam + “<condition attribute=’new_producttype’ operator=’eq’ value='” + crmForm.all.new_plproducttype.DataValue[0].id + ” ‘/>”;
    if (crmForm.all.new_placcounttype.DataValue != null)
        bodyparam = bodyparam + “<condition attribute=’new_accounttype’ operator=’eq’ value='” + crmForm.all.new_placcounttype.DataValue + ” ‘/>”;
    if (crmForm.all.new_plcallfor.DataValue != null)
        bodyparam = bodyparam + “<condition attribute=’new_callfor’ operator=’eq’ value='” + crmForm.all.new_plcallfor.DataValue + ” ‘/>”;
    if (bodyparam == “”)
        bodyparam = “<condition attribute=’statecode’ operator=’eq’ value=’0’/>”;
    param = headparam + bodyparam + tailparam;

    field.AddParam(“search”, param);
}
crmForm.lookupquery();

onChange:
 Add crmForm.lookupquery(); to all the picklist attributes onChange() event so that as soon as a picklist value is changed lookup field filter criteria will also be changed.

Hope it helps you..!!!!

Cheers
VikranthP