Wednesday, January 04, 2006

SharePoint in a Stand Alone Server Gives Error On Being offline

Problem Description:

Well, this is an old one, but I always forget about it when I encounter it. When you use a stand alone SharePoint server (for example in a virtual machine like Microsoft VPC or VMware) to develop or test something, not all of the features work. For example:

  • DataSheet view will not update rows in a list or document library and will show you an error stating it is offline. "Cannot connect to the server at this time. Changes to your data cannot be saved."
  • Office task pane that is supposed to show you "document updates" and "Shared workspace", is also telling you you are offline. "You are currently working offline. Check your network connection and then click get updates."

Cause:

The reason for this behavior is that the office objects that connects office to sharepoint are checking the network status and they see that you don't have a network (since you are on a standalone server).

Solution:

Well, one way would be to setup another machine and connect the two, or maybe set up a loopback adapter.

But the easy way to solve this is to just stop the network sensing mechanism and fooling office! Here is how you do it:

  1. Close all office applications and internet explorer windows.
  2. Click Start>Run
  3. write in the text box "net stop sens" and press enter.

that's it! Now the datasheet view will update items and office-sharepoint integration will work smoothly!

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.