Introduction
This article will look at the framework I've developed for making life easier when working with heavy JavaScript client scripts and server side INamingContainer
in slightly older ASP.NET rendering frameworks.
Background
When a server control renders to the client within a container which implements INamingContainer
, this modifies the ID of the control. A textbox with an ID of 'txtUsername
' will often end up with an ID which is a $ notation representation of the control's location is the page hierarchy. E.g., ctl_001$ctl_content1$txtUsername
.
To get this ID requires the use of a server-side include to request it from the server. This imposes limits such as stopping scripts from being embedded.
With the following code, this is no longer an issue.
Using the Code
The following is the item framework code:
var ctlHolder = function(id, ctl) {
this.ID = id;
this.Ctl = ctl;
}
var ctlDef = function() {
this.Items = new Array();
this.Add = function(item) { this.Items[this.Items.length] = item; };
this.Get = function(id) {
for (var obj in this.Items)
if (this.Items[obj].ID == id)
return this.Items[obj].Ctl;
return null;
}
this.EndID = function(id) {
var index = id.lastIndexOf('$');
if (index == -1)
index = id.lastIndexOf('_');
if (index == -1)
return id;
else
return id.substring(index + 1);
}
}
var ctl = new ctlDef();
function catalogItems(items) {
if (items == null) items = document.getElementsByTagName('html');
for (var obj in items) {
var item = items[obj];
if (item.id)
ctl.Add(new ctlHolder(ctl.EndID(item.id), item));
if (item.childNodes)
catalogItems(item.childNodes);
}
}
To use this framework when the page loads, you need to call the "catalogItems
" function. This can be achieved by adding the following attribute to the body
node of the HTML document.
onload="catalogItems(null);"
Once cataloged, you can now replace your longer document.getElementById
calls with:
Old: document.getElementById('ctl_001$ctl_content1$txtUsername')
New: ctl.Get('txtUsername')
Points of Interest
I found this script to be very quick. One large page in my current project loads at 300K+ for which this method cycles through all nodes and catalogs within 0.1 seconds.
The $ notation naming convention is no longer enforced in the most recent frameworks like MVC.