Wednesday, July 11, 2007

Overcoming Challenges in Modifying and Adding Page Content with JavaScript

If you've been wishing that more web parts gave you the option to apply XSLT styles, then the methods presented in this post may just be your ticket to the customization that you're seeking!It's not the same thing, but with some clever JavaScript coding, you can achieve similar results.

I'm a frequent user of Zap Reader—the popular, and free, web based speed reading program. There were already plugins for several blogs (WordPress, Blogger, and TypePad), but nothing for SharePoint blogs. I thought it would be nice to add a button to each blog post that allowed readers to quickly load the text into Zap Reader so they could speed read it.

Conventional wisdom would have said that this needed to be written in Visual Studio and then installed as a feature that could be activated or deactivated for each blog site. Some of the existing Zap Reader tools were already written in JavaScript, so I figured why not leverage this existing code base and write something that any Power User could easily add to their blog without having to go through all the IT Department red tape to get something extra installed. (I don't necessarily think all that red tape is a bad thing, I just figure why go through it if you don't have to.)

I started with the existing code for the Greasemonkey script that adds a "Zap Read This" button to each post in BlogLines—it worked essentially the way that I wanted this one to work: the page would load; the script would then rewrite each blog post on the page to include a "Zap Read This" button. It sounded good in concept, but I encountered a couple hurdles along the way. I'm hoping to save other JavaScript developers some trouble by documenting in this post how I overcame them. Note that many Greasemonkey scripts can be modified to work within a Content Editor web part to give all your users extra functionality on that page, regardless of the browser they are using. You may want to spend some time browsing to get some inspiration, and code.

The DIVs for the blog posts don't have unique names.

Because I needed to extract the innerHTML for each post, modify it, and then write it back, I needed some way to consistently reference it. All the post DIVs did have the same "ms-PostBody" CSS class, however. To help with this, I found a nice JavaScript function called getElementsByClassName() by Jonathan Snook and Robert Nyman. Calling this function placed all the DIV objects with the "ms-PostBody" class in an array where I could work with them.

I couldn't add new FORM tags on the page.

If you've tried to add any code to a content editor web part that contained FORM tags, you got an error telling you, "FORM tags are not supported in the HTML specified in either the Content property or the Content Link property." At first I thought that would be no big deal since I was adding my tags dynamically using JavaScript to update the innerHTML of another DIV. When I tried this though, I got an "unknown runtime error" in the browser when my JavaScript ran.

I discovered that IE7 validates code that is written using the innerHTML property before it writes it, and if it is invalid markup, it will give you the "unknown runtime error". The reason that I was getting it was that almost the entire page was already wrapped in FORM tags (this is needed for all the cool out-of-the-box JavaScript functionality in SharePoint 2007) and you can't have one HTML form nested inside another one. That made sense. Since I couldn't add my form at each button, I decided to just utilize the existing form tags and have my script modify them when the button was clicked, and then change them back when the script was finished running.

You will find the code for the "Zap Read This" Button for SharePoint Blogs on the Zap Reader Tools page. The code is well documented to explain why I did some things the way I did. To use it, simply copy the code and paste it into a Content Editor web part on both the default.aspx and Lists/Posts/Post.aspx pages of your SharePoint Blog. You may want to customize the placement or look of the button, but this was written to give you just the basic functionality.

Let me know in the comments what you think!


No comments: