Custom Xrm Script and Business Rules on the same Field in Dynamics CRM 2013

With the advent of Microsoft CRM 2013 in came business rules, a wonderful feature of the new CRM version. However with new implementations, there would be always some new confusions creeping up. Well in many training sessions on CRM 2013, i keep getting the question – “Will my onchange handlers and business rules work at the same time on the same field?”.

The best way to get the answer is to try out only. So let’s do a small test which i myself faced in one of my implementations. I was faced with a scenario where I had to to do whole lot of stuffs on change of field including clearing out certain other field values. All of them but clearing stuff was possible with business rules. So had to write a custom onchange event handler for the field. And yes both the business rules and my custom code triggered. Let’s see this with a simple example.

In the contact entity, for the email field I have a simple business rule which make the email field mandatory as soon as First Name field is entered/ changed by the user. Also for experimental purpose, I will register on on-change of First Name, to show a alert. Check for the screenshots below.

Screen 14

Screen 16

 

 

Now when I changed the First Name for a new Contact, first of all my custom jScript code fired. When I closed the alert by clicking OK, the Email field was set to Business Required by the Business Rule.

Screen 17

Screen 18

However remember the following MSDN Documentation – “When you set a field value by using a business rule, any OnChange event handlers for that
field will not run. This is to reduce the potential for a circular reference, which could lead to an infinite loop. ”

So when you are designing business rules and customer onchange handlers for your implementations, please do take all this into consideration.

Hope this helps!

Control CRM 2013 Business Process Next Stage and Previous Stage flow using JScript.

Recently in our project we needed to restrict the business process flow from one stage to another depending on certain conditions. The problem was that OOB CRM 2013 does allow you to plugin your custom client side code when the “Next Stage” or the “Previous Stage” icons are clicked. You can obviously register Plugins and Workflows on the business process stage change but you cannot stop the change of stages using the same. Let’s see how we can achieve this.

Below is the screenshot of an example business process flow for opportunity entity. Let’s explore what CRM does here. I have opened Chrome Developer tools and trying to explore the HTML for business process flow. I have selected the ‘Next Stage’ button.

screen 9

The id of the div is “stageAdvanceActionContainer”.

So what we need to do is override the click event with our custom function and then if our condition meets we would call the OOB event handler. The code below does the same.

function  registerBusinessProcessEvents()

{

var originalNextStageHandler = $(“#stageAdvanceActionContainer”).data(“events”)[“click”][0].handler;

 

// unbind the original next event handler

$(“#stageAdvanceActionContainer”).unbind(“click”);

 

$(“#stageAdvanceActionContainer”).click(function (e) {

// perform your custom logic here. If you want to move to the next stage just call the code below.

 

$.proxy(originalNextStageHandler, $(“#stageAdvanceActionContainer”))(e);

 

}

 

}

All you need to do is call the registerBusinessProcessEvents  function during the onload of the form.

Similarly the ID for the previous click handler is “stageBackActionContainer”. And you can handle it in the same manner as above.

 

Please note that is an unsupported customization and might not work if Microsoft decides to change the id of the div elements or the rendering model in future rollups.

 

Hope this helps!

CRM 2013 Solution Import Error – An item with the same key has already been added

In CRM 2013, while importing of solution, we faced the error “An item with the same key has already been added”.

A little bit of searching and we found this very good article which describes how to resolve the error – http://nishantrana.wordpress.com/2014/04/15/an-item-with-the-same-key-has-already-been-added-error-while-importing-solution-in-crm-2013/

However as the link suggests, it was not possible for us to delete the field since we had some data where the field was populated in the target environment. Hence we had to take the alternate route.

We unzipped the customizations and looked for the field in the customizations.xml file.

For e.g. in the screen shot below, we could see the field with physical name “new_IsOpportunityCustomer”. However when we went into the customizations of the target environment the name was “new_isopportunitycustomer”. Clearly there was a difference in casing which led to the below error.

screen 8

To resolve this we changed the physical name in the customizations.xml from “new_IsOpportunityCustomer” to “new_isopportunitycustomer” and re-imported the solution and everything worked fine.

Hope this helps!

 

Found More than one RibbonDiff Entity Error- CRM 2013 Solution Import

In CRM 2013, while importing of solution, we faced the above in the Entity Ribbon of the Account Entity.

To resolve the same, we unzipped the customization file that we were importing and then opened the customizations.xml file in a xml editor and checked for the RibbonDiff part for the account entity.

We found duplicate entries in the HideCustomAction. See the screenshot below.

screen 7

 

We just removed the duplicate entries and the re-imported the solution and it worked again

Hope this helps!

Default Potential Customer lookup to show only accounts/ Contacts in CRM 2013 Business Process Flows

In the opportunity entity, we have a field “Potential Customer” which is of type “Customer” and it can be both account or contact entity. However sometimes we might need to customize the same to show only contacts or accounts.

For this in the form load of the opportunity entity, just add the two lines of code shown below.

$(“#customerid”).attr(“lookuptypes”, “1”);

$(“#customerid”).find(“img”).attr(“lookuptypes”, “1”);

However in CRM 2013 if we are using business process flows and we include the Potential Customer in the business process flow, the above line of code wouldn’t do the job for you. For that just add the two lines of code shown below.

$(“#header_process_customerid”).attr(“lookuptypes”, “1”);

$(“#header_process_customerid”).find(“img”).attr(“lookuptypes”, “1”);

 

Hope this helps!

DisableViewPicker not working in CRM 2013

In CRM we are often faced with the requirement of disabling the view picker of a lookup view.

Say we a have a lookup field called customerid on the form of another entity  and on click of the lookup, we need to disable the view selector of the lookup view window.

In Crm 2011 this could be achieved with the following code

$(“#customerid”).attr(“disableviewpicker”, “1”)

However in CRM 2013, you might find the  code above not working as expected. To do the same in CRM 2013, the trick is not find the image of the particular lookup field and  apply the code to the image tag.

$(“#customerid”).find(“img”).attr(“disableviewpicker”, “1”)

Hope this helps!

Change global optionset mapping for a Entity optionset in Microsoft Dynamics CRM without dropping and recreating the field

Recently I came across a situation where my local optionset was pointing to one global optionset and then I needed to point to another global optionset. In CRM to do this, you would have to drop the field and recreate field. But the problem is if you have a running system which is being actively used, you may not be at the luxury of dropping and recreating the fields. Let’s see how we can overcome this situation.

Before continuing, please note that the below procedures is not recommended by Microsoft and interacting directly with CRM Organization database might cause CRM to work incorrectly and following the recommended way is what you should look for.  I would strongly recommend taking a back-up of your customizations and organization database.

 

I have field “Test Local optionset”  for the contact entity which points to the global optionset “Global Optionset 1”.  Check for the screenshot below. Screen5

But say we need it to map to another Global optionset called “Global Optionset 2”. To do the same, open the CRM Organization database and run the below SQL query on the database.

DECLARE @OptionsetId UniqueIdentifier

SET @OptionsetId = (Select OptionSetId from OptionSet where Name = ‘new_globaloptionset2’)

Update Attribute SET OptionSetId = @OptionsetId WHERE LogicalName = ‘new_testlocaloptionset’ and EntityId = (SELECT top 1 EntityId From Entity where LogicalName = ‘contact’)

After this query is executed, when CRM is re-opened we could see that our Local Optionset set is now pointing to the “Global optionset 2” instead of “Global Optionset 1”

screen6

 

Now there is a question as to what should be with the existing data for the field.  For that a simple console batch to update the previous values with the new values using text matching condition would resolve the problem. This can be easily achieved with CRM SDK Code. Hope this helps! Happy coding.