Saturday, December 31, 2005

How to add a better “Send Document Link By Mail” menu item to document libraries

Post update: my good friends in KWizCom have developed a menu editor for sharepoint. This makes implementing and deploying this article a piece of cake! Description: In his article Extending SharePoint 2003 Context Menus, Mark Bower explains how to add a “send link by email” menu item to SharePoint document libraries drop down menus. However, Bower uses a regular mailto link as the mechanism to create the mail item. This method has the advantage that it will work on most browsers and mail applications without any special configurations, but also the disadvantage that if the link has a space in it (for example http://server/document%20library/file%20name.doc) the link will be broken in the email (http://server/document library/file name.doc) which is not a good behavior.

An alternative approach is to use outlook activeX control to create the message and the link, thereby preserving the full link. The disadvantage of this method is that it requires Microsoft Outlook (any version, but not outlook express) and that it requires that the browser allows running activeX controls on the site (register the site as a safe site on the clients). Although it has drawbacks, it is my belief that most SharePoint users have outlook, and it is a recommended best practice to register the company internal portal as safe anyway. With this in mind, attached is my recommended version of code to accomplish the task.

Sample Code: *Before changing the ows.js file, please back it up. The following code is to be inserted into the ows.js file of the SharePoint machine (either WSS only or SPS machine). This causes all document libraries to have the new menu item. The code sample needs to be inserted into the AddDocLibMenuItems function. The exact location can change – depending on where you want the menu item to be. It should be after the line that starts with “var currentItemEscapedFileUrl”.

//Add the "send mail" link strDisplayText = "Send Link By Email"; strImagePath = ""; // parse the URL out of the itemTable var URL = ""; var index = itemTable.innerHTML.indexOf("href="); if (index > 0) { var str = itemTable.innerHTML.substr(index + 6); index = str.indexOf('"'); if (index > 0) { URL = str.substr(0, index); URL = URL.replace(" "," "); } } if (URL != "") { //The following is the original action – using the “mailto” //strAction = 'window.navigate("mailto:%20?subject=Take a look at this document...&body=' + URL + '")'; //Add the action to open outlook and a new message with a set subject and a link to the document strAction = "try{var olApp;olApp = new ActiveXObject('outlook.application');var oItem = olApp.CreateItem(0);oItem.Subject = 'Take a look at this document';oItem.HTMLBody = '" + URL + "';oItem.display(true);}catch(e){alert('Couldnt use the outlook object. Please make sure the current sharepoint site is trusted by your browser and activeX are allowed to run');}"; // Add menu item CAMOpt(m, strDisplayText, strAction, strImagePath); // add a separator to the menu CAMSep(m); }

Sample Code 2: *Before changing the ows.js file, please back it up. If you are unsure how and where to insert the code above, just copy the code below to replace the AddDocLibMenuItems function in your ows.js file. This will be simpler if you are unsure what to do.

function AddDocLibMenuItems(m, ctx) { if (typeof(Custom_AddDocLibMenuItems) != "undefined") { if (Custom_AddDocLibMenuItems(m, ctx)) return; } var RootFolder = GetRootFolder(ctx); setupMenuContext(ctx); if (currentItemFileUrl == null) currentItemFileUrl = itemTable.ServerUrl; if (currentItemFSObjType == null) currentItemFSObjType = itemTable.FSObjType; var currentItemEscapedFileUrl = escapeProperly( unescapeProperly(currentItemFileUrl)); strDisplayText = "Send Link By Email"; strImagePath = ""; // parse the URL out of the itemTable var URL = ""; var index = itemTable.innerHTML.indexOf("href="); if (index > 0) { var str = itemTable.innerHTML.substr(index + 6); index = str.indexOf('"'); if (index > 0) { URL = str.substr(0, index); URL = URL.replace(" "," "); } } if (URL != "") { ////strAction = 'window.navigate("mailto:%20?subject=Take a look at this document...&body=' + URL + '")'; strAction = "try{var olApp;olApp = new ActiveXObject('outlook.application');var oItem = olApp.CreateItem(0);oItem.Subject = 'Take a look at this document';oItem.HTMLBody = '" + URL + "';oItem.display(true);}catch(e){alert('Couldnt use the outlook object. Please make sure the current sharepoint site is trusted by your browser and activeX are allowed to run');}"; // Add menu item CAMOpt(m, strDisplayText, strAction, strImagePath); // add a separator to the menu CAMSep(m); } if (currentItemFSObjType != 1) { strDisplayText = L_ViewProperties_Text; strAction = "STSNavigate('" + ctx.displayFormUrl+"?ID="+ currentItemID + "&Source=" + GetSource() + RootFolder + "')"; strImagePath = ""; CAMOpt(m, strDisplayText, strAction, strImagePath); } strDisplayText = L_EditProperties_Text; strAction = "STSNavigate('" + ctx.editFormUrl+"?ID="+ currentItemID + "&Source=" + GetSource() + RootFolder + "')"; strImagePath = ctx.imagesPath + "edititem.gif"; CAMOpt(m, strDisplayText, strAction, strImagePath); if (currentItemFSObjType != 1) { if (ctx.isWebEditorPreview == 0) { if (ctx.listTemplate == LISTTEMPLATE_IMAGE_LIBRARY && itemTable.IsImage == "1") { strDisplayText = L_EditInOIS_Text; strAction = "EditSingleImage('" + currentItemID + "')"; strImagePath = ctx.imagesPath + "oisweb.gif"; CAMOpt(m, strDisplayText, strAction, strImagePath); } else { setDocType(); if (currentItemAppName != "" && currentItemOpenControl != "") { strDisplayText = StBuildParam(L_EditIn_Text, currentItemAppName); strAction = "editDocumentWithProgID2('" + currentItemFileUrl + "', '" + currentItemProgId + "', '" + currentItemOpenControl + "')"; strImagePath = ctx.imagesPath + currentItemIcon; CAMOpt(m, strDisplayText, strAction, strImagePath); } } } } strDisplayText = L_DeleteDocItem_Text; strAction = "DeleteDocLibItem('" + ctx.HttpPath + "&Cmd=Delete&List=" + ctx.listName + "&ID=" + currentItemID + "&owsfileref=" + currentItemEscapedFileUrl + "&NextUsing=" + GetSource() + "')"; strImagePath = ctx.imagesPath + "delitem.gif"; CAMOpt(m, strDisplayText, strAction, strImagePath); if (ctx.isModerated == true) { strDisplayText = L_ModerateItem_Text; strAction = "STSNavigate('" + ctx.editFormUrl+"?ID="+ currentItemID + "&ChangeApproval=TRUE&Source=" + GetSource() + RootFolder + "')"; strImagePath = ""; CAMOpt(m, strDisplayText, strAction, strImagePath); } if (currentItemFSObjType != 1 && ctx.listTemplate == LISTTEMPLATE_IMAGE_LIBRARY) { strAction = "DownloadOriginalImage(" + currentItemID + ")"; strImagePath = ctx.imagesPath + "download.gif"; strDisplayText = L_DownloadOriginal_Text; CAMOpt(m, strDisplayText, strAction, strImagePath); } if (currentItemFSObjType != 1) { CAMSep(m); AddCheckinCheckoutMenuItem(m, ctx, currentItemEscapedFileUrl); AddVersionsMenuItem(m, ctx, currentItemEscapedFileUrl); CAMSep(m); if (ctx.PortalUrl != null) { strDisplayText = L_AddToMyLinks_Text; strAction = "Portal_Tasks('PinToMyPage')"; ; strImagePath = ""; CAMOpt(m, strDisplayText, strAction, strImagePath); strDisplayText = L_AddToCategory_Text; strAction = "Portal_Tasks('Categorize')"; ; strImagePath = ""; CAMOpt(m, strDisplayText, strAction, strImagePath); CAMSep(m); } } strDisplayText = L_Subscribe_Text; strAction = "NavigateToSubNewAspx('" + ctx.HttpRoot + "', 'List=" + ctx.listName + "&ID=" + currentItemID + "')"; strImagePath = ""; CAMOpt(m, strDisplayText, strAction, strImagePath); if (currentItemFSObjType != 1) { strDisplayText = L_Discuss_Text; strAction = "STSNavigate('" + ctx.HttpPath + "&Cmd=COMMFRMS&URL="; if (ctx.isWebEditorPreview == 0) strAction += currentItemEscapedFileUrl; strAction += "')"; strImagePath = ctx.imagesPath + "icdisc.gif"; CAMOpt(m, strDisplayText, strAction, strImagePath); if (ctx.listTemplate != LISTTEMPLATE_IMAGE_LIBRARY) AddWorkspaceMenuItem(m, ctx); } // add a separator to the menu CAMSep(m); }

Acknowledgments:My thanks to Mark Bower and\or to Alan Smithee who published the original document in Microsoft’s site.

No comments: