Thursday, July 05, 2007

Adding JavaScript to a Content Editor Web Part to Run onLoad

Adding JavaScript to a page inside a Content Editor web part can be a great way to perform on-the-fly customizations to your SharePoint sites. This worked great in WSS v2 and SPS 2003. We started noticing that some of those scripts didn’t seem to work in WSS v3 and MOSS 2007, however, and it wasn’t because the names of objects and elements had changed.

For example, here is a JavaScript snippet that we had used to hide the “NEW!” icon on a page in WSS v2.

Note: In all code examples below, replace the square brackets around the SCRIPT tags with angle brackets. If I included the angle brackets, the browser tried to execute the code. :o(

[script language="JavaScript"]
var fields,i;
fields = document.getElementsByTagName('IMG');
for( i = 0; i < fields.length; i ++ ) {
var imgsrc = fields[i].getAttribute('SRC');
if(imgsrc.indexOf("new.gif") != -1) {
fields[i].style.visibility = "hidden";
}
}
[/script]

When we added this to a Content Editor web part in a WSS v3 page, nothing seemed to happen. I added code to make it run on the onLoad event, and that didn’t work either. I did a little experimentation and discovered that if I added a short delay, even a delay of 1/1000 of a second, it worked fine. I placed the core code within a function and then called it with the setTimeout() method.


[script language="JavaScript"]
setTimeout(HideNewIcons,1);
function HideNewIcons(){
var fields,i;
fields = document.getElementsByTagName('IMG');
for( i = 0; i < fields.length; i ++ ) {
var imgsrc = fields[i].getAttribute('SRC');
if(imgsrc.indexOf("new.gif") != -1) {
fields[i].style.visibility = "hidden";
}
}
}
[/script]

The problem occurs because most WSS v3 pages use a master page that contains the “body” element, and the page content code loads after the master page code. I didn’t know it at the time, but recently discovered (thanks to this article on the Microsoft SharePoint Products and Technologies Team Blog) that the SharePoint developers had given us a way to work around that issue—it’s the _spBodyOnLoadFunctionNames array. We can use JavaScript’s “push” method to load items into this array where they will run when the body’s onLoad event fires .

Here is what the JavaScript looks like with the setTimeout replaced with a line that pushes the function name “HideNewIcons” into the _spBodyOnLoadFunctionNames array.


[script language="JavaScript"]
_spBodyOnLoadFunctionNames.push("HideNewIcons");
function HideNewIcons(){
var fields,i;
fields = document.getElementsByTagName('IMG');
for( i = 0; i < fields.length; i ++ ) {
var imgsrc = fields[i].getAttribute('SRC');
if(imgsrc.indexOf("new.gif") != -1) {
fields[i].style.visibility = "hidden";
}
}
}
[/script]

If you’ve been having trouble getting some of your legacy JavaScript scripts to run from within Content Editor web parts in WSS v3 or MOSS 2007 pages, give this technique a try, and let me know if it works for you.

14 comments:

Anonymous said...

I think your first main paragraph of the text rather than the intro should say WSS 2.0 rather than WSS 3.0.

Could you re-check?

Mike Walsh

Ricky Spears said...

Mike - Good catch! I've fixed that to say, "here is a JavaScript snippet that we had used to hide the 'NEW!' icon on a page in WSS v2."

Anonymous said...

I've been trying to get code to execute by using _spBodyOnLoadFunctionNames.push("FUNCTION_NAME", but it doesn't seem to work. THe code is not gettting hit. I think I have the above statement in the wrong location. Do I have to add it within the context editor tags? If so, where? Could your show some sample code? Becuase when I try to add it within those tags, Sharepoint Designer closes with an error. Any help would be appreciated!!

Sally Alshazly said...

Hey Ricky, I'm having problems keeping the JS in pages in SharePoint. For some reason SharePoint keeps removing the JS. Any idea how to go around that?

Ricky Spears said...

Sally - My first guess is that your JavaScript uses a FORM. SharePoint will remove it if it does.

Anonymous said...

Hey I tried using the _spBodyOnLoadFunctionNames.push("function");
command - but moss 2007 still seems to remove the code.

Ricky Spears said...

Anonymous - It sounds like you are putting some custom code in your function that SharePoint doesn't like. Try using this method with a simpole function that just contains something simple, such as an ALERT. You'll see it does work. If SharePoint is removing your code, you'll just need to take our bits and pieces and work my trial and error to see what is causing the problems. Good luck!

Anonymous said...

Hi Ricky, I am having problems trying to add MIT's Simile Timeline widget(http://simile.mit.edu/timeline/) to my sharepoint site v3. Any suggestions?

Karen I said...

Ricky--this worked like a charm. Thanks a million!!

eli said...

Hi Ricky Im hoping you still might be checking this post. i am not sure what i am doing wrong and hope you can help. I am trying to show the value of a query string on the page (not a pop ) but im not sure what im missing. It seems to just not work in SPS/Wss. it just displays the onload code in the web part. this is the code i put into the content editor

[script language="JavaScript"]
_spBodyOnLoadFunctionNames.push("displayItem");
function displayItem(key){
if(queryString(key)=='false')
{
result.innerHTML="you didn't enter a ?name=value querystring item.";
}else{
result.innerHTML+=queryString(key)+"
";
}
}
[/script]
onload="displayItem('RootFolder'); displayItem('Folder');"

Ricky Spears said...

Eli - I think you have some problems in your JavaScript--you'll need to fix that on your own. I can help you with getting it to run when it's supposed to though.

You don't need to add the onload piece at all. It's displaying the code in the web part because it's outside the SCRIPT tags. To call the function twice and pass the two keys as you have indicated, just change the line that pushes it onto the _spBodyOnLoadFuncitonNames() Array to reflect that, like so:

_spBodyOnLoadFunctionNames.push("displayItem('RootFolder')");
_spBodyOnLoadFunctionNames.push("displayItem('Folder')");

Good luck!

polgara said...

Thanks a million!

I was having trouble with my Web Part for hours. I used your trick and it worked :)

Anonymous said...

Great article. I'm using it to do a global replace on some text that I don't want to show up on the page (specifically, in a list that is grouped by a category, I don't want to see the category name). It works perfect...except that it takes a second or two to apply, so the user sees the text for a second, then it goes away. Any way that you know of to fire this off before the page is painted? Thanks.

Anonymous said...

YOU R A LIFE SAVER.

Cant appreciate your tip more!

Thanks a lot....