Prototype has numerous gems including the lovely $ utility function. I needed to write some custom client side javascript in a small ASP.net app and was looking forward to using this functionality. However, if you use master pages or custom controls, you're hosed when it comes to client side element ids. As Aaron and Jacob mentioned in Scott Hanselman's most recent podcast, ASP.Net will generate lovely element ids like ctl00_main_txtContactPerson, and that's only with a simple master page and content form. When you throw custom controls into the mix, you end up with ctl100_main_grid1_row1_ctl100_txtContactPerson. Makes even the simplest client side javascript a pain. I tried to find a similar $ function that was compatible with ASP.Net but didn't have any luck. So, I wrote my own little utility function to do the trick.
function $n(element)
{
if (arguments.length > 1) {
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
elements.push($n(arguments[i]));
return elements;
}
if (typeof element == 'string') {
var el = document.getElementById(element);
if( el )
return el;
}
else
return element;
var regExp = new RegExp('_' + element + '$');
var formsLength = document.forms.length;
for( var i=0; i<formsLength; i++ ) {
var form = document.forms[i];
var elementsLength = form.elements.length;
for( var j=0; j<elementsLength; j++ ) {
element = form.elements[j];
if( element.id && element.id.match(regExp) )
return element;
}
}
return null;
}
$n is identical to $ in design and purpose. You pass it the name of the asp.net id of the element you are looking for and it searches through your html doc trying to match any element with an id that ends with '_<asp.net id>'. I realize this isn't fool proof and will fail in the case where you have a txtName on a page and a txtName in a nested user control. This function will stand on its own (Prototype is not required). If you want full integration with Prototype, simply replace return element/el with return Element.extend(element/el). Tested with FF2 and IE6.