Wednesday, August 24, 2011

CRM 2011 Document Management Settings

In my previous post I provided an overview of the CRM/SharePoint integration capability. For a good reference of the detailed steps that are involved with setting the basic integration up, you should refer to this walk through.

In this post, I want to focus on the primary configuration options that are available.When configuring the SharePoint integration in CRM, you have the option to define both of the following (as part of one time set up):

Level of integration

Here you can define for which CRM entities the integration will be set up. For example, you can set it up so that accounts, opportunity and contacts have a link to CRM. As shown in the screenshot below, when I store documentation for the SolarTech account, the documents are stored in the SolarTech account library in SharePoint. If I defined it to also tie in at the contact level, then we would similarly see that documentation can be stored for the Joe Bloggs contact, and would corresponding appear under the Joe Bloggs contact in SharePoint. And so on.

 “Centricity” of storage

The "centricity" can either be centered around account or contact. If you wanted to configure this option, then in a b2b world, you would most likely want to base it off "account"; whereas in a b2c world, it would be based off of "contact". We'll assume b2b for the remainder of this discussion.

Using the account and contact mentioned above as an example and assuming Joe Bloggs is a contact for the SolarTech account. I can either set it up so that whenever I store documentation it will follow the account path or the individual path

At the account level nothing changes, but at the contact level, if I store a document for Joe Blogg, using the account path, the document will be stored in a SharePoint location that looks like:
..\account\SolarTech\contact\Joe Bloggs\Doc2.doc
..\account\SolarTech\contact\Joe Bloggs\Doc3.doc
..\account\SolarTech\contact\Ed Rogers\Doc4.doc

Conversely, if I store a document using the individual path, the document will be stored in a SharePoint location that looks like:

..\contact\Joe Bloggs\Doc2.doc
..\contact\Joe Bloggs\Doc3.doc
..\contact\Ed Rogers\Doc4.doc

In summary, the former approach centralizes the path around the parent account whereas the latter has no correlation to the parent whatsoever. The same would be true for any other entity related to an account (e.g. quotes, opportunities etc.)

In my next posts I will be reviewing the pros and cons of these configuration options that you will want to take into account before making your design decision.

Next: CRM 2011 Document Management Settings: Based on Entity Pros/Cons

CRM 2011/SharePoint Integration Overview

One of the most compelling features for upgrading to CRM 2011 is the tight "out of the box" integration that CRM has with SharePoint 2010. While it was possible to integrate CRM with SharePoint in previous versions, that involved developing a custom solution. Whereas in CRM 2011 the built in integration capabilities offers a nice, clean way of integrating these two applications and provides a great alternative for document management directly through the CRM user interface.

To some extent this integration is the one of the "holy grail" enhancements that we have been eagerly awaiting... for a very long time. The problem has generally been that while CRM has the ability to store documentation in attachments, it is by no means a "document management solution". And trying to leverage CRM as a document management solution is trying to fit a square peg into a round hole. On the flip side, we have this other great technology solution called SharePoint which among multiple other capabilities is a very strong platform for content and document management. So in 4.0 while there were various creative ways of handling the document management conundrum within CRM, they were just that - workarounds...

CRM 2011 is only part of the requirement for this integration solution. You will of course need to have or upgrade to SharePoint 2010 in order to be able to leverage this out of the box capability. SharePoint Foundation 2010 is available freely with the purchase of Windows Server 2008 which should make this option very feasible. Of course, if for whatever reason your organization does not want to use SharePoint 2010 or is not ready to upgrade to that environment, you will need to fall back to one of the creative solutions.

It should also be mentioned that the CRM/SharePoint out of the box integration only offers integration between CRM entities and SharePoint libraries in it's current incarnation. Meaning - it does not currently offer integration between a CRM entity and a SharePoint site. The good thing about integrating at the library level versus the site level is that it does tend to keep things nice and simple. But I can understand that there may be some situations where it would be preferable to connect at the site level and if that's your requirement... well, for now, you're fresh out of luck. At least using the out of the box option that is... As the CRM and SharePoint are in my opinion strategically aligned solutions, I would expect to see the level of this integration to deepen in future versions/upgrades of these products and wouldn't at all be surprised to see an integration at the SharePoint site level at some point. But that is purely based on my subjective view of the world. Time will tell if that prediction pans out.

While the integration between these two solutions is out of the box, there are various options in terms of configuring how this integration can be set up. I will outline these options in follow up posts and suggest some best practice considerations for configuring them.

Next: CRM 2011 Document Management Settings

CRM 4.0 Explorer View

Ever faced the dilemma of knowing where to store/find your documentation? For more advanced document management features, we would recommend a Sharepoint integration methodology (in CRM 2011 it is a no brainer to use the SharePoint integration as that comes out of the box, but if for some reason you do not have SharePoint 2010 - SharePoint Foundation is free so there really should be no reason - you can follow this approach in CRM 2011 too although it will need some adaptation). But for those who have simple needs or have a smaller budget for solving such problems, the Explorer view provides a very simple straight forward solution to this problem. The screenshot below illustrates this concept. Users can navigate and update documentation right from CRM just as they would with Windows Explorer (identical user experience).

The following will step through configuration of the option (you can download referenced files from here):

ASPX Configuration

Create a shared folder root on one of the servers (e.g. \\<server>\CRMFiles). Make sure you grant the necessary access permissions. It is recommended that the root share location be a folder without spaces in the name.

Create a subfolder called "Test" under the root folder:

Open default.aspx and make the following changes (pay close attention to the number and placement of the “\” character):
  • On line 20 update the “src” tag to point to the correct share location (src=\\<server>\CRMFiles\)
  • On line 21 update the “ddf_src” tag to point to the correct share location (ddf_src="\\\server\CRMFiles">)
Copy the modified file from above to the \crmweb\ISV\Sentri\Explorer location on the CRM server:

Test the above by trying to connecting to your test folder:
If you do not get an explorer view returned similar to the above, you have made a mistake in the deployment steps – please review the steps until you get a successful explorer view returned.

CRM Entity Configuration

On the CRM entity where you wish to configure the Explorer to appear you will need to make the following changes.

Add an IFrame to the form with a name of IFRAME_DOCS (note this name can be anything but it must match the jscript code – see later in this document).  The recommended settings are shown in the screenshots below.

Open onload.js and make the following changes:
  • On line 5 update the logic for setting the folder name as necessary (see configuration section for more about this)
  • On line 6 update the share location (var netshare = "\\\\server\\CRMFiles\\";)
  • On line 7 ensure the url points to the correct path (should be if you followed the deployment instructions above)
Copy the onload.js into the form load event – you will need to ensure that the “fileshare()” function is called from somewhere in the onload jscript.


In above implementation, there will need to be folder names under the share root matching the account name (assuming the jscript in  loaded in the account form). This of course can be modified as necessary to suit implementation requirements.

Thursday, August 11, 2011

Reassigning personal views for disabled CRM users

The ability to share personal views in CRM with other users in CRM is a powerful tool. It allows for a central admin users to create or assist other users with creating views and thereafter they can be assigned to individual users or to a group of users. When sharing these views the user has the ability to limit the permissions on the shared views. For example, you may want to share a view but prevent the users who this view has been shared with from deleting the view. That can make sense especially in cases where the shared view is shared amongst a group of users and you do not want to give any individual user the arbitrary opportunity to accidentally or intentionally delete that view and inadvertently have that action ripple across the organization.

This all works very nicely... until the power user who has assigned all his/her views to other users leaves the organization and you want to manipulate these shared views in cases where that manipulation (write, delete, share to others) has been limited. One obvious solution is to have the IT admin temporarily update the AD credentials for this user so you can log into CRM as this user and re-assign the views to a new power user.

But the above action is not always an option. And fortunately there is another better option. Enter the Microsoft CRM 4.0 Administration Console. This console has a number of useful functions including tools for managing security roles but we are just going to focus on the ability to copy personal views for the specific scenario mentioned in this write up.

Below are the steps to copy the personal views:

  • Download the console from codeplex
  • Launch and enter the credentials and select the "Manage Views" utility

  • In the ensuing form, first select "Get Users/Clear Cache". You can click just click Ok to select all users in the organization or you can filter by Business Unit

  • Then perform the following steps to assign views from one user to another user
    • In View Types ensure only "Main Application View (MAV)" view and "- Filter Active Views" are selected
    • Right Column: Select the user you wish to assign from
    • Middle Column: Select the view or views you wish to assign (use Ctrl and Shift for multi-select)
    • Right Column: Select the user or users you wish to assign the views to (use Ctrl and Shift for multi-select)
    • Click "Activate Views for Selected Users" and Confirm

Thursday, August 4, 2011

CRM 2011 Double Click Event

In a former post I provided a function for adding "onclick" events using jscript. You may however ask: "What about double click events?". Well if you did, the answer is a slight variation of the function provided for the "onclick" event. That is:

function RegisterOnDoubleClickEvent(attr, fn) {
    var e = document.getElementById(attr);
    var f = "var doubleclick=function() { " +
              fn + "(); " +
                  " };";


    // Attach to double click event 
    e.attachEvent("ondblclick", doubleclick, false);

Thereafter all you need to do to register an OnDoubleClick event is to pass the following function call:

RegisterOnDoubleClickEvent("attribname", "functionname");

CRM 2011 Contact Image alternative approach

In light of my former post about options for embedding a contact image (or for that matter embedding any other type of image into a CRM form), I thought I'd highlight another, perhaps better, approach.

The former approach is a more centralized/controlled way of adding images and it dictates that the image file being added adhere to a certain given format (e.g. in order to point to the Bob Jones image when opening the Bob Jones form, I need to ensure that I have a "BobJones.gif" file on the server or perhaps "" or some other derivation from the contact record so that I can link to the file when the form loads). Therefore adding images using this approach would presumably be given to an administrator user rather than being "democratized".

The other approach is to utilize the SilverLight control that can be found in codeplex. Kudos is also obviously due to the creator of this little add on.

Using this utility, any user can add an image to the contact form and the image is simply stored as an image in the Notes of the contact. A more decentralized approach and indeed a very slick alternative!

CRM 2011 Check if URL/file exists

We had a requirement to display a contact image along with the contact record in CRM. There are ample examples of how to go about doing this by either using a file on the server or a web resource. The following is a jscript snippet of how to go about adding an image referencing a file on the server (in this case the file should be placed in a ContactPics folder under the ISV folder. This could very easily be adapted to point to an image added as a web resource which is probably a better approach for CRM 2011.

function ContactPic(filename) {
    var picIframe = Xrm.Page.getControl("IFRAME_Pic");
    var src = picIframe.getSrc();
    var url = server + "/isv/ContactPics/" + filename;

The result should be something like this:

But what happens if the file does not exist neither as a web resource nor as a file on the server? In that case, it would be preferable to present a "No Image" default image or perhaps to hide the image altogether rather than showing a broken link. The challenge though is how do you detect that the link is broken in order to do so? Jscript does not allow you to interact with files on the server (due to security considerations) so performing a simple "file exists" check is not as simple as it might first seem.

The solution that I found to this issue was to detect a 404 error via a http request of the URL. As follows:

function UrlExists(url) {
    var http = new XMLHttpRequest();"HEAD", url, false);
    return http.status != 404;

And now the ContactPic function can be updated to first test the URL and if it is broken to replace it with a default NoPic.gif image.

function ContactPic(filename) {
    var picIframe = Xrm.Page.getControl("IFRAME_Pic");
    var src = picIframe.getSrc();
    var url = server + "/isv/ContactPics/" + filename;
    if (!(UrlExists(url)))
        url = server + "/isv/ContactPics/NoPic.gif";

Tuesday, August 2, 2011

CRM 2011 Ribbon Buttons: Use Case scenario

My two previous posts summarized how to go about adding a custom ribbon to a CRM 2011 form. I thought I'd round the topic out by providing a scenario of how these concepts might be applied.

For the sake of this example, let's say that you want to have two buttons on your contact ribbon. One to perform some "Add" logic to add a contact to some list and a second to perform "Remove" logic to remove the contact from the list. The requirements would therefore be as follows:

  • The Add button should execute the "Add" custom function
  • The Remove button should execute the "Remove" custom function
  • The "Add" button should only be enabled when the contact is not already in the list (we could also hide the button but visually it might be more appealing to disable rather than hide the button)
  • The "Remove" button should only be enabled when the contact is already in the list
  • After clicking "Add" to add the contact list, the "Add" button should be immediately disabled and the "Remove" button should be enabled. And vice versa.
  • Both the Add and Remove button should only be displayed on the contact update form and not the contact existing form

In order to achieve the above you would apply the concepts mentioned in the previous 2 posts. Namely:

  1. Add 2 ribbon buttons - One for the Add function and one for the Remove function
  2. The "Add" button should call a custom jscript function that will execute some jscript logic to add the contact to a list
  3. The "Remove" button should call a custom jscript function that will execute some jscript logic to remove the contact from the list
  4. Add EnableRule sections for each button to control when these buttons are enabled/disabled
  5. The "Add" EnableRule section should call a custom jscript function that will perform some logic to determine whether the contact is in the list. It if is it will return false (i.e. disable "add" button as it is already in the list) otherwise it will return true (i.e. enable "add" button as it has not yet been added to the list)
  6. The "Remove" EnableRule section should similarly call a custom jscript function. In fact, in our example as the logic for displaying the "Remove" button is the complete inverse of display the "Add" button (i.e. when "Add" is enabled "Remove" should be disabled and vice versa), we can reference the same custom function as for the "Add" EnableRule and just invert the result (InvertResult="true").
  7. Add a "Xrm.Page.ui.refreshRibbon();" command to the end of custom functions that are responsible for adding/removing the contact from the list. This will ensure that the display rule is executed after the action has been performed which will result in the "Add" and "Remove" buttons being enabled/disabled as necessary.
  8. Add DisplayRule sections for each button to control when these buttons are displayed on the form
  9. In both cases, the DisplayRule section should just have a "<FormStateRule State="Existing"/>" entry which will instruct the buttons to only show on the Update form.

And that should be it!

CRM 2011 EnableRules and DisplayRules

My former post provided a visual overview of adding a button to a CRM 2011 form ribbon. We will now take this one step further by exploring the EnableRules and DisplayRules options. Simply stated these rules control the  enabled/disabled and show/hide behavior of the custom ribbon. This is important because the button may not be always relevant on the form being edited and this provides you with an ability to manage this.

Please refer to the screenshot below.

  1. EnableRules/DisableRules - These should be added to the CommandDefinition section of the customization file. There must also be a corresponding entry in the RulesDefinition section of the customization file.
  2. CommandDefinition EnableRule Id - Add an id here that uniquely identifies the rule that you are adding
  3. CommandDefinition DisplayRule Id - Add an id here that uniquely identifies the display rule that you are adding 
  4. RuleDefinitions EnableRule Id - This should match the EnableRule Id added in step #2.
  5. RuleDefinitions EnableRule CustomRule - This once again references a custom jscript function that will determine whether to enable or disable the button. I chose to reference the "default" contact library but this could be any jscript library.
  6. RuleDefinitions DisplayRule Id - This should match the DisplayRule Id added in step #3. 
  7. RuleDefinitions DisplayRule FormStateRule - This tells the form that the button should only be displayed on "Existing" forms i.e. the update as opposed to the create form.
  8. Function CustomEnableRule - The function in the example above must be created in the relevant jscript library and should match the FunctionName from the CustomRule section
If there were more "involved" considerations for the DisplayRule, we could of course have also created a custom jscript function to allow for greater manipulation of this rule. Refer to the CRM SDK for more configuration options.

Adding a Form Ribbon Button in CRM 2011

In CRM 4.0 it is possible to add a button to the body of a CRM form and there were many good reasons to do so. While this is still possible in CRM 2011, I would argue that it's no longer relevant with the introduction of the ribbon interface which allows a lot more granular control over the behavior and function than was available using ISV.config in CRM 4.0.

There are a number of good articles that walk through the technical process of adding a ribbon button that you can refer to. The following is a high level visual representation of adding a button that executes a custom action that should hopefully bring this all together succinctly. This article assumes you have read through some of the other literature that describes how you go about exporting, identifying, and editing the entity customization file that you wish to add a button to.

Please refer to the screenshot below.

The following are some of the more important sections of the edits that need to be made:

  1. CustomAction Id - Add an id here that uniquely identifies the custom action you are adding
  2. CustomAction Location - Identifies the ribbon to update. If you are updating an account, it will start with Mscrm.Form.account, if you are updating a lead it will start with Mscrm.Form.lead etc.
  3. CustomAction Sequence - Identifies where in the ribbon it will appear
  4. Button Id - Add an id here that uniquely identifies the button you are adding
  5. Button Command - Add a command name
  6. LabelText/Tooltips - Any descriptive text
  7. TemplateAlias - Defines how the button appears although I haven't delved very deep into this one yet. Default to "01". 
  8. Images - Reference 16 and 32 icons that you should add as a web resource to your environment (optional)
  9. CommandDefinition Id - This should match the Button Command referenced in step #5. 
  10. Command Definition Actions - This section defines the action to take when clicking the button. There are various actions that can be taken. The first example is commented and simply would take the user to a web page when clicked. The second example is a reference to a custom jscript function defined in the form jscript. I chose to reference the "default" contact library but this could be any jscript library.
  11. Function HelloWorld - The function in the second example above must be created in the relevant jscript library and should match the FunctionName from the CommandDefinition section
  12. Xrm.Page.ui.refreshRibbon - This is a command that you can optionally add to jscript. Some times after you click a ribbon button, you will want to disable that button or perhaps enable another button on the ribbon. By callling this command at the end of your jscript function, you instruct the ribbon to refresh and re-execute any of the Enable and Display rules to control the appearance of your button which I discuss in my next post.

That's it. Now when you click the ribbon button, you will receive a "Hello World" alert prompt.

That's a brief introduction to the topic. Refer to the CRM SDK for more configuration options.