5633 Views // 0 Comments // Not Rated

Getting Accurate JavaScript Scrolling Information In SharePoint

If I were a SharePoint psychiatrist, (which indeed I may very well be...) I would have a list of panaceas tantamount to what a therapist might actually tell a real patient. For example:

To a patient:

  • "You have a lot to live for!"
  • "She wasn't the right girl..."
  • "Yes, I can prescribe something for that rash..."

To a SharePoint developer:

  • "Remember, it's just an ASP.NET 0 web app hosted in IIS!  It's just HTML!"
  • "That's only supported in MOSS..."
  • "Yes, I can tell you what 'unknown error' means..."

The reason SharePoint is sometimes seen as a hostile environment to work with is because a lot of things just don't work, or perhaps more accurately, don't work the way you'd expect them to. But people quickly forget that the nature of this beast is two-sided; the things that cause certain functionality to not work are in turn making many other things trivial to implement.

It's a trade-off, like everything is.

But instead, people try things the one way they know how, then *** when that doesn't work. So this article is going to be about a bit of an attitude adjustment, and doing what it takes to do something right. JavaScript, AJAX, and SharePoint are just the supporting characters here.

First, the problem: I redid our company's time sheet system as a SharePoint solution. The front-end is an AJAX-y animating user control hosted as a SmartPart. The back end is all Linq to SQL. The workflow is handled by WF. Everything lives in SharePoint, and future releases will have Quick Books integration.

Now I've written a lot about SharePoint and AJAX, so this was nothing new for me. But after our first round of testing, there was a bug about a draggable div not dragging correctly. I was able to drill down into this problem and find that it only occurred when the page was scrolled. My mouse event handler code was supposed to account for this. Here's what that JavaScript looks like:

Code Listing 1

  1. document.onmousemove = CaptureMouse;
  2. ...
  3. function CaptureMouse()
  4. {
  5. //initialization
  6. var div = $get('divId');
  7. ...
  8. //set drag location
  9. div.style.top = Number(event.clientY) + Number(document.documentElement.scrollTop);
  10. div.style.left = Number(event.clientX) + Number(document.documentElement.scrollLeft);
  11. ...
  12. }

Notice the use of document.documentElmenet in lines 9 and 10. This is what you use to get the number of pixels the page is scrolled in either direction in IE7. Since this is an internal app, I know that all my users will be using IE7, so no cross-browser consideration was necessary.

However, it didn't work; both values just returned 0. I tried my user control on a normal page (not SharePoint) and it behaved just fine. "Oh well," I thought. "It's an internal app; they can just scroll to work around it." Yep: I was about to write this off as something that just didn't quite work in SharePoint.

But that just didn't sit right with me. There has to be a reason why!

So after frolicking around the server for a while, I stumbled onto the default master page (default.master in C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\GLOBAL). Always intrigued by SharePoint-inized HTML, I opened it up. The first thing I noticed is what led me to the answer: there was no DocType at the top of the file! I immediately opened up a page in the portal (thinking that the DocType line might be generated on-the-fly or something), did a "View Source" and indeed, no DocType!

So I went back to the master page, and copy-and-pasted in a DocType from whatever Visual Studio generates for a new ASPX page. Next I tried the page again, and guess what? The draggable div now worked in SharePoint when the page was scrolled! However, using a DocType (I tried several different versions and DTD's) CRUSHED the formatting of the page. The colors, gradients, and images were all screwy in IE7.

So what does this mean? Well that SharePoint's HTML is not really confirming to any DocType standards. To me, this seemed very IE6-ish, so, referring to the code above, I switched my "document.documentElement" calls to use to older "document.body" that works in IE6. And guess what? That did the trick for SharePoint in IE7!

Now this wasn't the case for all the JavaScript; some confirmed to the browser version as advertised. But my point here isn't to get into all of this technical detail. All I want to say is that SharePoint is a robust application platform, but it's also a unique one. And like all environments, there is supported functionality that works trivially, and there's fringe functionality, however pervasive in standard environments, (like straight ASP.NET) needs some effort to get working.

Have fun!

3 Tags

No Files

No Thoughts

Your Thoughts?

You need to login with Twitter to share a Thought on this post.