Tag Archives: Dynamics crm

How – To Series 16: UR 12 – Downside of Auto Save feature

Update: This issue is fixed now with MS CRM 2013 Org Level Setting. Following is the update:
https://connect.microsoft.com/dynamicssuggestions/feedback/details/777281/ur-12-auto-save-feature-causing-workflows-plugins-to-be-triggered-multiple-timesHi all,
UR 12 has introduced a nice feature called “Auto Save” which will save the CRM Records(only Process Driven UIs) in the background automatically when it get updated by the user in UI.

When a field value changed by user, in the bottom right corner a label as “Unsaved Changes” gets displayed:

After few seconds(15-20 sec), forms gets saved automatically:

From usability point of view, it’s a very nice feature… then what’s going wrong??

When I came to know about this feature, few things came to my mind:

Scenario1: Lets say I have registered a workflow or a plugin on “onChange” of a field called “fax” in “account” entity. User has entered some value(1234) in the “fax” field and went on to fill other fields. After few seconds(lets say 20 sec) form gets saved automatically in the background. Incase if user feels he entered some wrong value in “fax” field so he/she modified the field again.

Prior to UR12 or with Classic Forms: User saves the form manually. Even though user modifies the same field twice, field value gets saved to the database once(in one transaction). And the workflow which is registerd will fire once and completes it’s tasks.

with UR12 Process Driven Froms: As user modifies the same field twice(one before the auto save and one after the background save), field value gets saved to the database twice(in two transactions). And the workflow which is registerd will fire twice…..

Scenario2: Lets say I have registered a workflow or a plugin on “onChange” of fields called “fax” and “email” in “account” entity. User has entered some value(1234) in the “fax” field. After few seconds(lets say 20 sec) form gets saved automatically in the background. Then user modifies the “email” field. After few seconds form gets saved in the background

Prior to UR12 or with Classic Forms: User saves the form manually. workflow will be triggered only once.

with UR12 Process Driven Froms: As user modifies two fields (one before the auto save and one after the background save), two field values gets saved to the database in two different transactions. And the workflow which is registerd will fire twice…..

To verfiy that, I have registered a workflow on “fax” and “email” field. Added a step to attach notes with fax and email field vlaues:

Result after Scenario 1:

Workflow instances:

Created Notes:

Created Notes when fax got updated to 1234

Created Notes when fax got updated to 1234567

In the same manner, for the second scenario too workflow got triggered twice…

Is it the expected behavior??? or Is it a design glitch??? or something am I missing??? So, if we gonna use Process Driven forms then what should be the considerations for extending the entity behavior??

Fingers Crossed….!!! 🙂

Share me your thoughts…!!!

How To – Series 6: How To Use “CustomRule” to Enable/Disable HomePageGrid Buttons- CRM 2011

 

In the earlier post here we have seen how to use <ValueRule> to retrieve a field value from the CRM form and Enable/Disable Custom Button based on that value. What if we want to do the same thing with “HomePageGrid” also like based on a particular value from the selected record in the Grid, Enable/Disable a Custom Button? Can we use <ValueRule> for the same?? The answer is big “No…!!!” Instead, we can use <CustomRule> wherein we can call a JavaScript function to do the required stuff.
For this post also, I am doing required stuff for “HomePageGrid” on top of the following SDK walkthrough: Walkthrough: Add a Custom Button to an Existing Group for a Specific Entity . Below is the result of SDK sample for Account Home Page Grid:
Custom button “Hello Ribbon” will be enabled when only one Account record is selected. Following is the code snippet for that:
<EnableRule Id=”Sample.account.grid.OneSelected.EnableRule”>
  <SelectionCountRule AppliesTo=”SelectedEntity” Maximum=”1″ Minimum=”1″ />
</EnableRule>
Now, let’s consider a scenario where we want to enable the “Hello Ribbon” button when only one Account record is selected and the selected record should have “Fax” value. We will see what are all the steps we need to follow to accomplish this.
Step 1: Retrieve the selected Item’s GUID value
Step2: Use the resultant GUID value to retrieve “Fax” field value using “REST” or “SOAP” calls
Step 1:
Inorder to retrieve selected item’s GUID value, we can use the following:
<CrmParameter Value=”SelectedControlSelectedItemCount” />
<CrmParameter Value=”FirstSelectedItemId” />
The first one returns an array of GUIDs for the selected items and the latter one returns GUID of the first item in the selected items.
<CrmParameter Value=”SelectedControlAllItemCount” />
Using this one we can get a count of selected items.
Step 2:
Use <CustomRule> to call java script function by passing the selected GUID value and it’s count. Following is the code snippet to do that:
            <EnableRule Id=”Sample.account.grid.SelectedRowValueCheck.EnableRule”>
              <CustomRule FunctionName=”IsExist” Library=”$webresource:new_CheckFieldValue.js”>
                <CrmParameter Value=” SelectedControlSelectedItemCount” />
                <CrmParameter Value=”FirstSelectedItemId” />
              </CustomRule>
            </EnableRule>
Here, “FunctionName” refers to Java Script method and “Library” refers to Java Script web resource. And the <CrmParameter> defined will pass it’s returned Value to the <CustomRule>’s function as parameters.
Let’s go define “IsExist” method in “new_CheckFiledValue.js” web resource as follows:
function IsExist(rowscount, firstselectedid) {
    if (rowscount == 1) {
        var ValueExist = ReturnValue(firstselectedid);
        return ValueExist;
    }
    else {
        return false;
    }
}
Observe the “IsExist” function’s prototype. It has two parameters. The first one “rowscount” refers to first <CrmParameter> and the second one referes to second <CrmParameter>. In the definition, I am calling a method “ReturnValue” with “firstselectedid” as the parameter when “rowscount” is 1. If not, returning “false”. In the “ReturnValue” method I am planning to retrieve “Fax” field value based on the GUID from the “firstselectedid” parameter using REST based web service call.
function ReturnValue(firstselectedid) {
    var context = Xrm.Page.context;
    var serverUrl = context.getServerUrl();
    var ODATA_ENDPOINT = “/XRMServices/2011/OrganizationData.svc”;
    var ODATA_Filter = “/AccountSet?$select=Fax&$filter=AccountId/Id eq (guid'” + firstselectedid + “‘)”;
    var jsonEntity = window.JSON.stringify(CRMObject);
    $.ajax({ type: “GET”,
        contentType: “application/json; charset=utf-8”,
        datatype: “json”,
        url: serverUrl + ODATA_ENDPOINT + ODATA_Filter,
        beforeSend: function (XMLHttpRequest) {
             XMLHttpRequest.setRequestHeader(“Accept”, “application/json”);
        },
        success: function (data, textStatus, XmlHttpRequest) {
            var faxValue = data[“d”];
            if (faxValue != null)
                return true;
            else
                return false;
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            return false;
        }
    });
}
This function returns “True” if “Fax” field has value else “False”.
PS: We need to refer “JQuery” and “JSON” libraries in our Java Script web resource to use REST end points. However, I am still struggling to find out how to refer “JQuery” and “JSON” libraries in our Java script web resource as we are not calling the functions as part of any event. Right now, I am working on an “Online” deployment. If it is On-Premise environment, we could easily call “JQuery” and “JSON” libraries as external files the same way we used to do in CRM 4.0. Anyways, I will come back here once I find a solution.
Hope it helps in giving a basic idea on how to use <CustomRule> and how to Enable or Disable HomePageGrid’s Button based on a condition.

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 2: How to make Phone Number field as CTI integrable or make IFrame look alike Label on Crm Form

There are situations, where you want to display an IFrame which looks like label on crm form. These type of implementations sometimes targets to have CTI integrations with them. Here I want to share with you one of the approaches to implement that. Below is the screenshot of what actually I want to get finally:
Here I am displaying Business phone of the contact in an IFrame which looks like a label on the form.
1.       Create an HTML page with style properties set to as follows:
<html>
<body style=”background-color: #eaf3ff; font-size:0.7em; font-family:Tahoma, Verdana, Arial; font-style:normal”>
</body>
</html>
Here, I am setting background color of the HTML page to be default CRM form’s color(i.e. #eaf3ff), font size to 0.7em(em is preferable than px for IE) and font family to be CRM form’s default i.e Tahoma, Verdana, Arial. So that, our HTML form which will become source for the IFrame will look alike as Crm Fom.
2.       Deploy above HTML page to ISV folder(ISVContactSampleAppBusinessPhone.html).
3.       Create a Section in the crmForm with formatting properties as:
i.                    Layout:  Fixed-width Column
ii.                   Column Format: Two columns(1:1)
So that we can make our IFrame to occupy only one column in the crm form instead entire row.
4.       Create an IFrame and name it as IFRAME_MyBusinessPhone with the following properties
i.                     URL: ISVContactSampleAppBusinessPhone.html
ii.                   Label it as MyBusinessPhone and check it to display label on the form
iii.                  Select Number of rows as “1” and uncheck “Automatically expand to use available space” so that IFrame occupies only one row.
iv.                 Select scrolling as “Never” and uncheck to “Display Border”.
v.                   Add this IFrame to earlier created section.
5.       Go to form onLoad event and add following code:
if(crmForm.all.telephone1.DataValue!=null)
{
document.getElementById(‘IFRAME_MyBusinessPhone_d’).innerHTML='<div style=”margin-top:2px; margin-left:2px”>’+crmForm.all.telephone1.DataValue+'</div>’;
}
else
{
document.getElementById(‘IFRAME_ MyBusinessPhone _d’).innerHTML='<div style=”margin-top:2px; margin-left:2px”></div>’;
}
Here I am giving div style margin as 2px so that it will be in align with IFrame’s label.
Finally, a simple IFrame and a HTML page with few properties set to will make a Magic….!!!!!!

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