SharePoint WebPart Page Dragging/Dropping Problem
I was getting an error today while working on my company’s custom SharePoint theme on the webpart pages when in edit mode. In IE, you can move the webparts round between the different regions on the page by dragging the webpart headers around. To facilitate this, at some point along the line SharePoint calculates the real offset of the element using the MSOLayout_GetRealOffset javascript function.
For some reason, this function was failing and so the dragging and dropping was not working. To find the real offset, the MSOLayout_GetRealOffset function recursively travels up the DOM tree through each successive element’s offsetParent from the given element until either the given end element or the body element. Here’s the function:
function MSOLayout_GetRealOffset(StartingObject,OffsetType, EndParent)
{
var realValue=0;
if(!EndParent) EndParent=document.body;
for (var currentObject=StartingObject; currentObject !=EndParent && currentObject !=document.body; currentObject=currentObject.offsetParent)
{
realValue+=eval(‘currentObject.offset’+OffsetType)
}
return realValue;
}
As you can see, the end condition for the for loop is when it hits the end element or the body. In my case, there was no given end element, so the default body element was being used. The problem, I found out, was that the body element was getting skipped. When it got to the form element, the next offsetParent would be the html element, so the for loop would not end correctly and eventually currentObject would be null and the eval statement would fail. Eventually, I tracked the problem down to the form element being relatively positioned in our custom CSS. This, somehow, was causing the next offsetParent for the form to NOT be the body tag (even though the form element is a child of the body tag) and instead the html tag.
To solve the problem, I am overriding MSOLayout_GetRealOffset in Javascript with a slightly modified version:
MSOLayout_GetRealOffset = function (StartingObject, OffsetType, EndParent)
{
var realValue = 0;if(!EndParent) EndParent = document.body;
for (var currentObject = StartingObject;
currentObject !=EndParent && currentObject != document.body && currentObject != null;
currentObject = currentObject.offsetParent)
{
realValue+=eval(‘currentObject.offset’+OffsetType)
}return realValue;
};
The only difference is the check for currentObject being null.

