1,644 articles and 12,017 comments as of Sunday, July 25th, 2010

Thursday, October 22, 2009

Assigning dynamic ids to HTML and Script elements – Client Side!

Einar Otto StangvikGuest Author: Einar Otto Stangvik
Will Code for Nuts

This question popped up on Twitter yesterday:

How do you usually handle duplicate IDs for html elements and scripts in SharePoint Web Parts, scripts and controls?

Which is a natural concern, with all the different web parts and scripts that’s being injected SharePoint portals these days. To end Monday off (in my neck of the woods anyway), I thought I’d make a quick post on what I do in my projects.

Script naming convention

For scripts, I have a few guidelines. First of all, my scripts follow a naming convention based on my organization handle, library concern, project name and so forth. Looking back to my previous couple of posts, e.g. the Script Loader (http://www.codefornuts.com/2009/10/pieces-of-my-core-javascript-library.html), this name would be grep.scriptloader – as that’s a core piece of script for me. For a script specific to a web part, I’d name it similar to the webpart, e.g. grep.webparts.navigationcontrol.

As for the actual script definitions, two matters apply: is it a class, or a single instance?

For single instances, such as the Script Loader above, I declare it like this:

if (!window.grep) window.grep = {};
if (!grep.someSingleInstanceClass)
{
grep.someSingleInstanceClass=
{
instanceVar: "baz",
foo: function() {},
bar: function() {}
}
}  

So basically I check if it’s already been assigned, and if it hasn’t, I assign it to a global variable. The above code would then be accessed such as

grep.someSingleInstanceClass.foo();  

For multi instance classes, I follow regular javascript oo syntax, with the same has-it-been-defined-clause, such as:

if (!window.grep) window.grep = {};
if (!grep.someClass)
{
grep.someClass = function(ctorVariable)
{
this.someVar = ctorVariable;
this.DoWhatever();
}
grep.someClass.prototype.DoWhatever = function()
{
// ...
}
grep.someClass.prototype.AnotherFunction  = function(input)
{
// ...
}
}  

Then access that such as

var foo = new grep.someClass("some value for the ctor");
foo.AnotherFunction(42);  

HTML element lookups, and dynamic ids

For elements, I use another trick. Since giving the elements a specific id can easily crash with other web parts of the same kind, or even other web parts / controls, I tend to avoid using ids as much as possible, and rather rely on class lookups (where the class has been named similar to the web part). For such lookups to be possible, however, they must be based somewhere – you can’t just search for all instances of ‘css class foo’ in all of the body tag.

Imagine the following scenario:

This element will be added several times, by other instances of the same web part

The script convention noted further up would make sure that the class’ code will only be added once, and we feed that the id of the div, so that the class can make css class based jQuery (or similar) lookups to find the elements it needs within the frame. But what’s the id of the div? Assigning a static id to it would crash with other instances of the same web part, and using a class would be just as hopeless.

That’s where the trick applies, and the following is a fully functional example:


    
I want a dynamic ID!

The trick works by looking up the script block’s element in the html dom. This element is the last added element, as the script block executes, even if it’s not at the bottom of the page. Based on this script element, it searches its previous siblings for the first match of a given tag type, then assigns a new id.

You could do a lot better with the actual dynamic id than the millisecond postfix shown here, such as an incrementing (or even random) number which is added to a string, then checking if that already exists (in which case we increment / re-random and try again). I leave that to your imagination, though.

As for the example further up, the frame could be identified and put into action such as:

 

And that would enable us to avoid any and all name crashes for our component.

Einar Otto StangvikGuest Author: Einar Otto Stangvik
Will Code for Nuts

Einar is a SharePoint architect and avid developer based in Oslo, Norway. Once a deep diving C++ programmer, and previous Microsoft MVP for that, he’s now mostly turned to the world of .NET and web frontends, with primary focus on C#, WCF, Silverlight and JavaScript.

View all entries in this series: EinarOttoStangvik - Will Code for Nuts»
 

Please Join the Discussion

One Response to “Assigning dynamic ids to HTML and Script elements – Client Side!”

Trackbacks

Check out what others are saying about this post...
  1. Steve Ballmer on SharePoint Business; Upbeat Launch for Windows 7; Gartner Talks Cloud Security…

    Top News Stories A Forrester Interview with Steve Ballmer About the SharePoint Business (ZDNet) I had…




Notify me of comments to this article:


Speak and you will be heard.

We check comments hourly.
If you want a pic to show with your comment, go get a gravatar!