65.9K
CodeProject is changing. Read more.
Home

Item Framework for Handling INamingContainer

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.67/5 (2 votes)

May 18, 2010

CPOL

1 min read

viewsIcon

10017

Item Framework for handling INamingContainer.

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.