Wednesday, June 2, 2010

Fix the SharePoint's discussion board deleting bug

Recently, I ran into a very strange SharePoint Discussion Board bug: if you delete the discussion topic (the thread root message), SharePoint will tell 'Cannot complete this action. Please try again'. However, the topic did get deleted in spite of the error message.

Digging deeper into this, I found out that:
- the bug happens only if the discussion board resides on the sub-site, or the site collection under 'sites' folder. It does not happens on the root site of the root site collection.
- it happens only when you click on a discussion topic to view the thread (Flat or Threaded view) -> then click the root message's 'View Properties' button -> then click 'Delete Item' toolbar button.
- it does not happen if you choose to delete the topic from the context menu; or if you enter 'Properties' screen from 'View Item' context menu.
- it happens only when deleting the discussion root topic. Deleting the relies does not cause trouble.

Checking the URL carefully, I figured out the reason: the problem is because after deleting, it tries to redirect to the thread view (as specified by the 'Source' query string parameter). However, as the topic has been deleted, there's no place to go back. It is a redirecting problem, not a deleting problem.

The solution:
Although at first it seems to be a problem of my specific site, it is a WSS 3.0 bug. As of WSS 3.0 SP2 (or MOSS 2007 SP2), there is no hot fix for that. I did not yet know if this bug exists in the just-released SharePoint 2010. As there seems to be no existing solution on the Internet, I developed a simple JavaScript solution.

Add the following JavaScript snippet into discussion board's DispForm.aspx (if you don't know how to do this, see my post http://thith.blogspot.com/2010/06/how-to-add-javascript-to-sharepoint.html).

<script type="text/javascript">
_spBodyOnLoadFunctionNames.push("ChangeAction");
function ChangeAction() {
  // Topics have titles, replies do not
  if (!HasField("Title")) {
    return;
  }
  var theForm = document.forms['aspnetForm'];
  if (!theForm) {
    theForm = document.aspnetForm;
  }
  
  var oldAction = theForm.action;
  var args = oldAction.split('&');
  if (args.length > 0) {
      theForm.action = args[0];
  }
}
function HasField(internalName) {
  var elements = document.getElementsByName('SPBookmark_' + internalName);
  return (elements.length > 0);
}
</script>

The purpose is simple: if it is a discussion root, cleanup the URL. SharePoint will redirect to the list's default view (often AllItems.aspx) if it does not find the 'Source' query string parameter.

The script assume that 'ID' is the first query string parameter. It works on our environments. If you want a solution which does not depend on the order of the query string parameters, maybe you could try to parse the query string.

2 comments:

Barracota said...

Thank you so much! This fixed exactly what I needed!

Anonymous said...

Thanks!:)
Godbless