Archive for July, 2014

Rollup 3 for Dynamics CRM 2013 is now available to download, and fixes many of the issues I’ve experienced with CRM 2013.

Here are some of the main bug fixes which I’m happy to see:

Unresolved email sender is not displayed correctly on Email form

Unresolved recipients on an email used to disappear when you load the form (even though they are still physically there). They now display correctly when loading the form.

Users attempting to add multiple records to a N:N relationship in Microsoft Dynamics CRM 2013 will experience the following error dialog even though the associations are completed: Duplicate Record: A record with these values already exists. A duplicate record cannot be created. Select one or more unique values and try again.

In some cases when we associate records through a N:N it would error stating that there were duplicates, even though there were not. The records would still be associated, and the error could be ignored.

Duplicate records are created if Save or Save and Close is pressed multiple times

This one has been around since the Beta days of CRM 2013, despite being ‘fixed’ in rollup 1, it still happened randomly some times. Hopefully this is fixed once and for all now.

Script error occurs when selecting a party type field in a Business Rule action

This was only a problem if you wanted to set the default value of a party list field, such as the ‘Call To’ or ‘Call From’ on a Phone Call. When you select one of these fields from the Action, it would give an ‘Unsupported Type’ error. The only workaround was to use JavaScript instead.

JavaScript methods will not trigger when a business required field is changed to be blank

This was an annoying one, but ultimately didn’t affect functionality, only user experience – since it’s required the form cannot be saved without a value, so as soon as a value is entered the onchange will fire again.

Custom plugin Exception is not thrown in UI as expected

Some times when plugins throw an exception you would only see the exception message in the bottom corner by the save button, but the actual message box would not pop up so it wasn’t always obvious what’s happened.

SDK- preventDefault is not working to stop deactivation from Account record

Another annoying one – if you had custom validation running on save of a record you could bypass the validation by clicking deactivate, which still performs a save. The only way around this was to also have a plugin performing server-side validation.

In CRM 2013, there was a change to allow users who have Impersonation (actonbehalf) privileges to activate and deactivate the workflows. This also allows users with the appropriate permissions to activate and deactivate workflow owned by other users in the UI. When you do this, it creates a new line in the WorkflowBase making the user that published this workflow the owner. If the workflow is set to the scope of a User, this workflow will only fire for the ModifiedBy user (the user that published this.)

One of the new features I recently wrote about – I haven’t come across this issue personally but it’s good to know it’s fixed, as this could cause major headaches.

Exporting Application ribbon contains duplicate values in XML

This is probably the most annoying bug I’ve ever dealt with. I spent a lot of time investigating what I had done wrong (thankfully nothing as it turns out). The issue we faced was around the custom hide action on the global ‘Connect’ button, which would create 2 hide actions in the XML and cause a solution import to fail.

Activity Types change when importing Solutions. As a result a view on the Activity entity that references the custom activity entity stops working. Warning message on the filter: This condition had one or more list values that no longer exist in the system.

If you have custom activity entities and you create a view of activities where the activitytypecode equals the custom entity, the view will be invalid after a deployment as the entity type codes of the activity entity may have changed, meaning the optionset value has also changed. The workaround for this was to either do a join on the actual activity, or to use ‘not in’ on all other activity types. Happy that this is fixed.

Untracking an email you do not own results in the email being deleted from CRM

This one I raised – woohoo! Instead of simply ‘untracking’ the email like it does if you own it, the only option would be to delete the email when owned by someone else. If you don’t have access to delete other users activities, you were unable to untrack it.

Removing / adding any field to the form after enabling the option “Automatically expand to use available space” causes the sub grid to shrink or resize to much smaller in size.

This one’s been around for a while. Whenever ‘auto expand’ is used, it would cause additional blank rows to be inserted after the field/subgrid. Pretty much the only workaround was to not auto expand.

For a complete list of fixes, check out the KB Article.

Previously I’ve been posting about how to recreate CRM functionality using browser bookmarkets. These have included useful functions like opening advanced find, or publishing customizations. In this blog post I’m going to go one step further and show how we can completely disable ALL client side validation on a form so that we can make changes to a form without worrying about field requirement levels, visibility, business rules, or JavaScript.

What I’m about to show is intended for testing purposes only, and should not be used in any production environments – otherwise you might end up with dirty data in your system. So use it cautiously, and use it wisely!

What it does:

  • Makes all required fields not required.
  • Makes all hidden fields visible.
  • Enables all disabled fields.
  • Makes all hidden tabs visible.
  • Makes all hidden sections visible.
  • Expands all collapsed tabs.
  • Clears field notifications on all fields.
  • Prevents JavaScript from firing on save.
  • Allows editing of inactive records.

One click of this button and you instantly have edit access to every field added to your form. This is extremely useful when you have JavaScript or plugins setting or relying on hidden fields on your form, and you need to quickly get in and see or modify those fields.

It’s also useful if you need to change a value on a form without entering in all the required fields – particularly as an admin when you need to fix up 1 or 2 fields on an existing record without filling out the rest of the required fields.

I’ve set up a form as an example below.

You can see we have most fields disabled. What you can’t see are the hidden fields and sections. Also when we try to save the form, our CRM Admin has added some “secure” JavaScript to prevent us from saving the form:

One click of our magic ‘God Mode’ button, and voila!

As you can see, literally every field is now unlocked, and not required. We can also see the ‘Company’ field in the second column which was previously hidden, the entire ‘Hidden’ tab is now visible, and we can edit any of the values (with the exception of Status, Created On, and Created By which can be changed but do not save to the database). We can also now save the form and bypass that pesky on save validation, and even clear the value of required fields.

Further down what you can’t see in the screenshot is that our Details tab has now been expanded as well. This means if we need to find a field we can Ctrl + F and quickly find what we’re looking for even if it was in a collapsed tab.

One other unexpected feature of this button is that we can also open an inactive record, turn on God Mode, and then change any of the ‘disabled’ fields. We can then simply navigate away from the record and the changes will be saved to the inactive record! (Only works with autosave enabled, or if you have rollup 1 or lower, and doesn’t work on activity entities).

Any user can set up this button for their own personal use, and it can be used with any CRM 2013 system, on any modern entity, and you don’t need any additional CRM security roles/privileges. To configure the bookmarklet, simply create a new bookmark, then edit the properties and set the URL to the following script:

javascript:var form=$("iframe").filter(function(){return $(this).css("visibility")=="visible"})[0].contentWindow;try{form.Mscrm.InlineEditDataService.get_dataService().validateAndFireSaveEvents=function(){return new Mscrm.SaveResponse(5,"")}}catch(e){}var attrs=form.Xrm.Page.data.entity.attributes.get();for(var i in attrs){attrs[i].setRequiredLevel("none")}var contrs=form.Xrm.Page.ui.controls.get();for(var i in contrs){try{contrs[i].setVisible(true);contrs[i].setDisabled(false);contrs[i].clearNotification()}catch(e){}}var tabs=form.Xrm.Page.ui.tabs.get();for(var i in tabs){tabs[i].setVisible(true);tabs[i].setDisplayState("expanded");var sects=tabs[i].sections.get();for(var i in sects){sects[i].setVisible(true)}}

 

If you’re a CRM admin/developer reading this, you probably want to think about what validation you’re doing on the client side and consider moving anything critically important into server side validation.

In Dynamics CRM 2013, when auto save is enabled, any changes to a record will be saved automatically when you close the record. In some cases we need to change data on a record to test functionality, and so we don’t always want those changes to be saved.

I’ve created a browser bookmarklet which will disable auto save for the record you have open, so that if you ever need to enter some test data into a record, you can simply click the bookmark which will prevent the system from automatically saving the form every 30 seconds, and also when you close the record or navigate away.

What the script does is it attaches an onsave event which checks the save mode, and cancels the save event for anything other than a physical ‘Save’, which can only be triggered by the little save icon in the bottom right corner (or my save bookmarklet). Any other type of save, including auto save and save and close, will be prevented. When you close the record or navigate away with unsaved changes, you will be prompted that there are unsaved changes just like it would if auto save was disabled for the organisation.

As you can see above, I’ve clicked the ‘Disable Auto Save’ bookmarklet, then made some changes to the Account Name, and when we navigate away we’re prompted that changes have not been saved. We can then simply click ‘Ok’ to close the form without saving the changes. The next time we open the record, or when we open any other record, auto save will be enabled again until. This allows us to turn off auto save only when required.

The script to use for this bookmark is as follows:

javascript: var frame = $("iframe").filter(function () { return ($(this).css('visibility') == 'visible') }); frame[0].contentWindow.Xrm.Page.data.entity.addOnSave(function(context){ if (context.getEventArgs().getSaveMode() != 1) { context.getEventArgs().preventDefault(); } });

In Dynamics CRM 2013 Customizers and Admins no longer have the ‘Customize’ tab on records anymore, which I often found useful for when we need to quickly get in and customize an entity, and then once done come back to the record and publish customizations.

To make things a little easier again, I’ve added these buttons back as browser bookmarklets. This will allow us to quickly and easily launch into the default solution, and automatically navigate us to the entity we’re on. We can also use this from other areas of the system, including views and dashboards, allowing us to jump straight into the customizations area without having to navigate through settings and losing our place in CRM.

I’ve also added a Publish button which can be used from anywhere in the system, including inside a solution and on a form. This will publish all customizations, and will be useful in times where there is no publish button available, for example when you edit a form and ‘Save & Close’ – you can now simply click the Publish bookmarklet to publish those changes instead of having to reopen the form or solution to publish.

The scripts to use for both of these bookmarks are as follows:

Customize:

javascript: var frame = $("iframe").filter(function () { return ($(this).css('visibility') == 'visible') }); var form = frame[0].contentWindow; try { var etc = form.Xrm.Page.context.getQueryStringParameters().etc; } catch(e) {} form.Mscrm.RibbonActions.openEntityEditor(etc);

 

Publish:

javascript: var frame = $("iframe").filter(function () { return ($(this).css('visibility') == 'visible') }); frame[0].contentWindow.Mscrm.FormEditor.PublishAll();

In a previous blog post of mine I explained how to add Advanced Find onto the Form Command Bar in CRM 2013, since the list view no longer stays open while on forms like they did in 2011, it can be difficult getting to advanced find sometimes.

In this blog post I will be taking the code from that blog post and converting the button into a browser bookmarklet so that we can launch advanced find from anywhere in CRM, including forms, views, dashboards, and solutions.

Just like the command bar button, this bookmarklet will automatically open advanced find to the entity you’re on if coming from a form or view, otherwise it will display the first entity by default.

The script for the bookmark is as follows:

javascript: var frame = $("iframe").filter(function () { return ($(this).css('visibility') == 'visible') }); var form = frame[0].contentWindow; var u = form.Mscrm.CrmUri.create("/main.aspx"); u.get_query()["pagetype"] = "advancedfind"; try { var etc = form.Xrm.Page.context.getQueryStringParameters().etc; } catch (e) { } if (etc) { u.get_query()["extraqs"] = "EntityCode=" + etc; } form.openStdWin(u, "_blank", 900, 600); void (0);

 

As you can see, from a contact form the Advanced Find bookmarklet opens a new window with advanced find defaulted to Contacts.

Now you don’t have to think about where you need to be to launch advanced find, as long as you’re inside CRM when you click the button it should take you right where you need to go!

Dynamics CRM 2013 for some reason has decided to remove the Copy a Link button from forms, and instead only shows the Email a Link button. The button still exists on views, however I often find myself on a form wanting to get the URL of the record so I can do something with it. Since the record URL is no longer available in the address bar, the only option is to pop the record and then copy the ID, or use Email a Link and copy it out of the email (doesn’t work if you’re on a server with no email client).

Since custom bookmarklets seem to be trending right now, I decided to make my life a little bit easier by creating a custom bookmarklet to copy the record URL. Since the button still actually exists, and is just hidden in the new UI, it was easy enough to open up the Ribbon Workbench and examine the function being called from the button. It was then just a matter of testing it out to see what parameters the function actually requires (which turns out it doesn’t need any). And finally just combining that with the JavaScript to get the active forms iframe, as found by Jared Johnson in his blog post on creating custom bookmarklets.

To add this custom bookmarklet, create a new bookmark called ‘Copy a Link’, and set the URL to use the following script:

javascript:$("iframe").filter(function () { return ($(this).css('visibility') == 'visible') })[0].contentWindow.Mscrm.CommandBarActions.sendFormShortcut();

 

When we click the button, the CRM function will fire to copy the record URL, and we can see the link pasted into Notepad exactly how CRM 2011 would. This button will only work on an open record, and not on a list view for example (although the CRM command bar button still exists on views). It will also be available and will work on any CRM 2013 environment you log into, so there’s no need to install any additional solutions or add-ins.

Stay tuned for more bookmarklets coming soon!

In a previous blog post by Jared Johnson, he showed how to create some custom browser bookmarks/favourites to help make some common tasks easier in 2013. These included easily copying the ID of a record, and quickly refreshing the data on the form if it has changed by a workflow etc. He also explained how to get the current active iframe so that we can access all of the forms Xrm.Page functions.

In my next few blog posts I’m going to explore some of the other possibilities available to us with custom bookmarkets, starting with how to restore the Save, Save & Close, and Save & New buttons so that they’re always available to us.

So often I find myself pointing into the top left corner to save my changes, and then remember that I need to go into the opposite corner, or just navigate away. I idea of these bookmarklets is that my new custom bookmarks will sit at the start of my bookmarks bar, so that when I go reaching for that save button, I just have to go a little further to get it. Another added benefit is that we can bring back the Save & New button, which has been removed entirely from CRM 2013, making it difficult to create multiple related records from a parent while maintaining the mappings.

To add these 3 custom bookmarklets, simply create some new bookmarks, and set the URL’s to use the following scripts:

Save:

javascript:$("iframe").filter(function () { return ($(this).css('visibility') == 'visible') })[0].contentWindow.Xrm.Page.data.entity.save();

 

Save & Close:

javascript:$("iframe").filter(function () { return ($(this).css('visibility') == 'visible') })[0].contentWindow.Xrm.Page.data.entity.save('saveandclose');

 

Save & New:

javascript:$("iframe").filter(function () { return ($(this).css('visibility') == 'visible') })[0].contentWindow.Xrm.Page.data.entity.save('saveandnew');

 

Whenever we are on a record now, whether it’s new or existing, we can use these buttons. The buttons will of course show up whether you’re on a form or not, however it also means you can use these buttons in any CRM 2013 system; so for someone like me, who needs to use several CRM environments at once, this definitely comes in handy.

Since we have access to all the functions of Xrm.Page, the possibilities really are endless as to what we can do with these bookmarklets. In my next few blog posts I’ll go through some other useful buttons we can add to build up our own custom command bar.