Pages

Wednesday, February 27, 2013

Xrm.Utility.openEntityForm no longer working

*** Update 3/5/2013: This issue has now been fixed via a Cloud update ***

Other known issues with UR12 can be tracked here: 
https://community.dynamics.com/crm/b/dynamicscrmsupportblog/archive/2013/01/28/december-2012-update-has-been-released.aspx

******

If you have a CRM Online installation and the Xrm.Utility.openEntityForm jscript function which you *knew* was previously working but apparently is no longer.... well, the good news is that you're not going mad. The bad news is that it is indeed a bug that has been introduced in the current (as of this writing) version of CRM Online. Or as confirmed from Microsoft:


Issue Definition: Xrm.Utility.openEntityForm does not work anymore since Update 5.0.9690.3339 on the CRM Online organization.
I have confirmed that this is an issue with the latest update that has been done with the CRM Online organizations. We are currently working on the code review and should have the fix in place shortly. 


The Microsoft support guy I spoke to indicated that this would likely be fixed within a week although I do not have a definitive date.

For the sake of reference below is the text of the error received when trying to use this form open utility.






Wednesday, January 16, 2013

Cannot sign in to CRM Online: LiveDevice.xml

Ok. I have stumbled on this too many times. Each time I think I'll remember for the next time and then, lo and behold, I spend time scratching my head trying to figure out what the issue is. So it's time I wrote it down - if nothing else for my own sake as a reference post (hopefully I'll remember that I wrote up this post!).

What am I talking about?

Trying to connect to CRM Online. It happens on occasion that I am denied access to CRM Online when trying to connect from a 3rd party application when I'm certain that my credentials are correct. For example, below is what happens when trying to connect using the Visual Ribbon Editor tool.



Usually I spend time thinking that maybe my URL is incorrect. Maybe I should have left off the http/https. Maybe I should use the Organization Unique Name (appearing under Developer Resources in CRM) instead of the "friendly name" in front of the crm.dynamics.com etc. etc.

The solution of course is simply to delete the LiveDevice.xml file from under the Root\Users\<user>\LiveDeviceID folder and then to try and sign in again... Voila!

Perhaps now I'll remember for next time? Let's hope so...


Tuesday, January 15, 2013

Duplicate Field Mapping/Defaulting


I encountered a scenario where whenever a child entity is created from within the context of a parent entity, the mapping automatically creates two references from the parent entity on the child entity.


The reason for this is due to the fact that the parent entity is related in a 1:N relationship to the child entity more than once:


And each of these relationships automatically creates a mapping that resembles the one below. That is both mapping contain a link from the parent entity to each of the foreign keys from the child entity and you are unable to delete these as they are required by the CRM platform.


Moreover any mapping added to one of the relationships is automatically added to the other relationship (and vice versa). I can't figure out if this is absolutely necessary from a technical design perspective or if this is just a design flaw. I suspect the latter because I can't come up with a good reason for this design logic. Or it could just be something specific that managed to sneak into the environment I'm working in.

The major issue is that this results in a confusing design because both fields get defaulted when only one should depending on the navigational context i.e.:
  • When navigating from "Entities Owned" the "Entity" field should be defaulted from the parent entity whereas the "Is Invested In" entity should remain null
  • Conversely, when navigating from "Investors in this Entity" the "Is Invested In" field should be defaulted from the parent entity whereas the "Entity" should remain null



As standard field mapping seems to rule out the ability to differentiate between these two different contexts, the only way to do so would seem to be by passing in custom parameters which is an example of when this technique is absolutely required.

To do so, the form was modified to remove the default "Add New" buttons and replace with custom Add buttons (which as an aside also provides the ability to give much clearer names to the add operation). The Ribbon Workbench Tool ably supports this kind of configuration. Each of these buttons simply calls the Xrm.Utility.openEntityForm to open the same child form button, but passes in parameters to set the lookup fields as required in each case.



Access Main form fields from Nav Area via Jscript

Let's say you need to access form fields via jscript when you have navigated to one of the navigational links on the entity. For example, when the account form is open but you are currently on the "More Addresses" navigation.


A typical scenario for such a requirement is if you have configured a custom button on the sub-grid ribbon that links to a jscript function where you need to pass through some parameters that are set from fields on the main form.

If you try and access the fields using the standard Xrm.Page approach while in the above navigational scenario, your jscript will error out. Like so:

function CustomAction() {

 var parameters = {};
 parameters["snt_customid"] = Xrm.Page.data.entity.getId();
    parameters["snt_customidname"] = Xrm.Page.data.entity.attributes.get("snt_name").getValue();
 
 Xrm.Utility.openEntityForm("snt_custom", null, parameters);

}

The solution is pretty much the same as how page elements are referenced from html web resources linked to a form i.e. using the prefix of "window.parent". Therefore updating the function as follows should do the trick:

function CustomAction() {

 var parameters = {};
 parameters["snt_customid"] = window.parent.Xrm.Page.data.entity.getId();
    parameters["snt_customidname"] = window.parent.Xrm.Page.data.entity.attributes.get("snt_name").getValue();
 
 Xrm.Utility.openEntityForm("snt_custom", null, parameters);

}

Update:

The above design has one flaw and that is if you decide to use a sub-grid to bring in the navigation link into the main body of the form. When you do so, the same sub-grid menu shows up when you click on the sub-grid but there is one essential difference...



In the case of the former, the main form is no longer in view and therefore you cannot access the form elements (Xrm.Page.data) without using the "window.parent" prefix. I you don't use this prefix you will receive a jscript errror.

In the case of the latter the main form is still in view and therefore Xrm.Page.data is accessible. And therefore if you use the "window.parent" prefix you will receive a jscript error.

In order to cater for both scenarios the solution is quite simple - simply use the try/catch exception handling feature. This way if an exception occurs it will go to the alternate access method which will then succeed.

function CustomAction() {

 var parameters = {};
 var id;
 var name;
 try {
  // if called from Nav Link navigation
  id = window.parent.Xrm.Page.data.entity.getId();
  name = window.parent.Xrm.Page.data.entity.attributes.get("snt_name").getValue();
 } catch (e) {
  // if called from Embedded Grid navigation
  id = Xrm.Page.data.entity.getId();
  name = Xrm.Page.data.entity.attributes.get("snt_name").getValue();
 }
 parameters["snt_customid"] = id;
 parameters["snt_customidname"] = name;

 Xrm.Utility.openEntityForm("snt_custom", null, parameters);
}

Wednesday, December 26, 2012

getClientUrl() to replace getServerUrl()

It appears that the javascript getServerUrl() function will become deprecated with the release of Update Rollup 12 for CRM Dynamics 2011 (imminent). As far as I can tell, from that point forward there will be a new function called getClientUrl() that should be used instead.

No doubt the reason for the deprecation is due to the fact that the getServerUrl() function cannot always be relied upon to return the correct server context as described in an earlier post (and therefore the workaround solution described in that post should no longer be necessary).

We'll have to get back to this to confirm once the rollup has been officially released.

Form Query String Parameter Tool

The Dynamics team recently released a new utility called the Form Query String Parameter Tool. Essentially it's a useful little utility that can be used to generate the syntax of a create form URL passing in parameters to default field values when the new form is opened.

Having said that, I believe that in in most cases using the URL parameter passing approach for defaulting values on the create form should not be necessary. The rest of this post will explain this point of view.

First of all, the out of the box "field mapping" approach - whereby field values from the currently open parent entity are mapped to the child entity form being opened - should be used where ever possible. This covers scenarios where the default values are static regardless of the form "context" and the field being mapped is in fact "mappable".

If the default values are dependent on the form "context" (e.g. new accounts where type = "customer" should have different defaults than cases where type = "vendor") or if the field being mapped is not "mappable" then your next best bet is using javascript on the form load event to set the defaults. Using javascript you can set all the appropriate fields as long as you have a field populated on the form in order to make the necessary branching default logic (the form "context" field). The form context field may be set using either standard field mapping, a web service API call (as explain below) or via URL parameters. Once obtained the javascript default logic can take over.

Using the URL parameters approach would therefore only seem to be necessary when you don't have a form "context" field on the form that is being opened. However this is not necessarily the case either since you can also leverage the web service calls (RESTful or SOAP) in order to retrieve the "context" from the parent field in order to perform the necessary branch logic.

Therefore it would seem that using form parameters to set default values would be necessary to only a fairly limited set of scenarios. This would be a scenario where all 3 conditions listed below are true:


  • The fields cannot be defaulted via standard parent/child field mapping
  • The form does not contain a form "context" field on which to base javascript branching logic
  • A standalone form that is not linked to another form from which the "context" can be retrieved using web services


Finally, even in the remaining few scenarios that do require the URL mapping approach, it is really only necessary to pass through a single URL parameter - that will set the context and javascript can subsequently take over for the remaining default logic.

Therefore, when all is said and done, while it's always nice to see new tools being developed to facilitate the customization effort, I do not see myself using this particular one all too frequently.

Perhaps there are scenarios that I'm not considering? If I encounter them I'll be sure to dish.

One scenario encountered is with differentiating between multiple 1:N field maps for the same two entities as described in this post.


Thursday, December 20, 2012

Simplifying Navigation: Add to Favorites

This post is another in the series on Simplifying Navigation - it is somewhat of an "oldie" but definitely a "goodie". And I have also verified that the same issue and workaround exists using Outlook 2013.

In short, the issue is that the CRM area within the Outlook Client is somewhat buried. For example, if you wish to navigate to the Accounts, it will involve at least 3 clicks (if this area was not previously opened):


In addition to that, if you are more than likely to access a particular entity from your CRM data it would be helpful if you could separate it from the rest of the group.

And fortunately you can by simply dragging and dropping the CRM folder to your Outlook "Favorites" folder which will you give single click access to your CRM data. Much better.



As an aside, it appears that in Outlook 2013 the UI has been simplified and the icons for all the folders have been removed... including the CRM icons. Not sure if this is a long term feature or something that will be tweaked in future Office patches (I personally haven't yet decided whether I prefer it this way or not).

The issue that you may encounter is that the aforementioned drag and drop capability might not be working. And if that is the case, you need to enable this feature by running through the steps in this KB article. Or you can just download this file, unzip and double click to deploy it in your environment (this will add a single registry setting called DisabledSolutionsModule under your MSCRMClient key).

Another option that allows for a little more organization of your CRM links is to use the Outlook "shortcuts" option. In order to make this effective the first thing you should do is go to the Navigation Options and move the shortcuts up in the list so it appears in plain sight as shown.




You can then add new shortcuts to the CRM folders of your preference:


And now you can click on the shortcut to navigate to your CRM data: