I was very excited when the CRM team asked me to write a post for this blog since I had just finished putting together a solution for a client that integrated files and folders into a CRM tab. I thought it would be something that a lot of people would find useful – perfect for a large audience like this. A number of CRM developers have developed solutions that integrate SharePoint document stores into CRM. The solution detailed in this article is a twist on that concept that will enable you to integrate Windows Explorer instead of a SharePoint document store in order to view context-sensitive shared folders and files directly within CRM.
While this solution also incorporates a SharePoint webpart to do some of the heavy-lifting, it gives the end user all of the familiar characteristics of Windows Explorer. This includes the ability to drag and drop files, rename items, copy, paste, and delete files or folders, and all of the other wonderful functionality of the context menu available by right-clicking in Windows Explorer.
Let’s start with a screenshot of the final outcome so you can get an idea of how handy this would be. In the example below, the user has all of the power of Windows Explorer right within the CRM record he or she is updating. (Notice that the folder being displayed has the same name as the account.)
Here’s what you’ll need to get this solution to work for you:
- An .aspx page that invokes the SharePoint Page Viewer webpart and receives the parameters passed from your Account form.
- An iframe on your Account form to hold your .aspx page.
- Some javascript in the OnLoad event of the Account form to pass the folder name (stored in the CRM Account record) to your custom .aspx page.
1. First, for the SharePoint page, let’s create a page in SharePoint and add a Page Viewer webpart to it. This is faster and easier than trying to code a custom SharePoint page from scratch and one of the cool things about Page Viewer webparts is that you can use them not only to view other webpages, but also to view folder directories. Point your webpart to the share that contains your account documents. For example:
//servername/share name/client folders/
Test your webpart to make sure it shows your shared folders. At this point it won’t point to a specific client’s folder, just the top folder that contains the client’s folders. You should test that this webpart works for your users as well, making sure the path to the share is accessible to all of the CRM users who will be using it.
Next, we’ll strip away the chrome and extraneous links from the SharePoint page that we don’t need. Right-click the page and choose “View Source” to open the page’s code in Notepad. Save the Notepad file in a folder within the CRM web site’s folders on your CRM server. The usual path is C:/Program Files/Microsoft CRM/CRMWeb/. (It should go without saying, but always make sure you have good backups of your CRM server before messing about in this folder! I like to keep things neat and tidy on the CRM server, so I’ve created a folder in the CRMWeb folder called ‘custom’ to hold all of my custom solutions and saved this page to CRMWeb/custom/fileviewer/default.aspx.)
It might take some trial and error to figure out what is extraneous in this SharePoint-generated page, but the main part we’re after is the code enclosed in div tags that starts with “<div WebPartID=…” and contains an iframe that points to your shared folder. (That’s right, the end product will actually be an iframe within an iframe!)
Be careful removing anything before the opening <body> tag! You can test your progress along the way by opening Internet Explorer and browsing to http://crmserver/custom/fileviewer/ (replacing ‘crmserver’ with your CRM server’s address).
2. Once you have a nice clean custom page that displays only the Page Viewer webpart, you can go to the CRM account form to add a new tab with an iframe. There’s plenty of documentation about how to do that in CRM’s great Help files and on the web, so I won’t go into that here. Name the iframe ‘fileviewer’ and set its source to /custom/fileviewer/default.aspx. Remove the checkmark from “Restrict cross-frame scripting” and format the iframe to expand to all available space. Preview the form. You should see your shared folder in your iframe.
3. Now, here comes the juice! Our custom SharePoint page in the new iframe on the account form isn’t very helpful at this point because if you publish your form now your users will still have to navigate down to the folder specific to the account they are working on. Maybe it saves them a few clicks, but it’s not gonna knock their socks off. So we want to somehow tell the custom SharePoint page what account we’re looking at and have it navigate down to that folder for us. Fortunately, CRM let’s us add Jscript to the account’s OnLoad event that will help us do this!
The trick is that on the account form’s OnLoad event we are going to tell CRM to change the source of the iframe (the one on the CRM form) by appending a query parameter to the URL. Then we’re going to add some javascript to our custom SharePoint page to parse the parameter out of the URL and – ready for this? – change the source of the iframe in the webpart to the desired folder.
If your folders have the same names as your accounts, you can pass the account name to the SharePoint webpart. (Otherwise you can use a custom field on the account form to hold the name of the folder. This has the advantage that if you don’t have folders for all of your accounts you can leave the custom field blank for those accounts and you will still be able to view the top folder in your share.) In this example, however, let’s assume that every account has a folder on the share with the exact same name as the account name in CRM. Add the following script to the OnLoad event of the account form:
var FolderName = crmForm.all.name.DataValue;
{
if (FolderName != null)
{
document.all.IFRAME_fileviewer.url=” /custom/fileviewer/default.aspx?FolderName=” + FolderName;
}
else
{
document.all.IFRAME_fileviewer.url=”about:blank”;
}
}
If you test this out while looking at an account called Adventure Works Cycle, the iframe on our new tab will change to point to http://crm/custom/fileviewer/default.aspx?Adventure Works Cycle. But it still won’t show the folder in question! There’s a little more that’s needed to bring it all together. All that is left at this point is to add some javascript or ASP.NET code to your custom page that parses out the requesting URL and returns the value ‘Adventure Works Cycle’ as a variable called AccountFolder. (There are numerous examples on the web of scripts that can help you handle this part.) Then add the following script to your custom page after the webpart div to change the source of the webpart’s iframe to include the folder name:
<script>
document.all.MSOPageViewerWebPart_WebPartWPQ10.src+=AccountFolder;
</script>
So now the source of the Page Viewer webpart’s iframe is set to //servername/share name/client folders/Adventure Works Cycle. And voila, the user who is looking at the Adventure Works Cycle account in CRM also has immediate access to the account’s folders and files on the server!
Some closing items to keep in mind:
The user can drag and drop, copy, paste, delete, and do whatever else their Active Directory permissions permit with these files, so make sure you have proper permissions set on the ACLs for your shared folders. The view of the folder shown in CRM will match the user’s preferences as set in Windows Explorer, so if they have set every folder view to display in thumbnails or tiles, that is what they will see here. Internet Explorer will give occasional security warnings when you execute a context menu command in the Windows Explorer webpart, but they are relatively unobtrusive and the efficiency gained is worth it!
Lastly, as someone who comes to CRM with a web design background, let me suggest that while you’re customizing your SharePoint page, you might consider referencing CRM’s style sheets to add some background colors, borders and headings to make the webpart look like it belongs in CRM – your users will appreciate your thoughtfulness.