Monday, February 25, 2008

Javascript getElementByRegexId Function

One of the most frustrating aspects of working with ASP.NET is the way it rewrites the id's for all the controls on the page.  When you want to access that control via javascript, you're screwed.  Sure you could have ASP.NET render the control's ClientID, like...

javascript:alert('<%= txtName.ClientID %>');

But, IMO, this is highly unattractive.  It also breaks the separation of content, design, and function by requiring javascript to be on the page.

We are all pretty reliant on the getElementById function.  It's a shame that there isn't a 'getElementByPartialId' function.  I can not find a way to get javascript's default functions to return my "txtName" control when it is rendered as the "ctl00_GridView1_WhoApprovedThisNamingConvention?_ctl05_txtName" control.  ASP messes with the "name" attribute as well.  It just uses dollar signs instead of underscores. 

Note to Microsoft:  Next time you revamp ASP.NET.  Create a new attribute on your base web control object called "aspid" and hack away.  Just leave "id" alone.

Knowing that Javascript is incredibly powerful and versatile, I put together a little function to help out.  You just pass in the id that you know and what kind of control you expect to be rendered.  Passing in "*" for the tag name should work as well, it just won't be quite as fast.

function getElementByRegexId(id, tagName)
{
    var rx = new RegExp("^.*" + id + "$");
    var controls = document.getElementsByTagName(tagName);
    var result;
    for(var i = 0; i < controls.length; i++)
    {
        if(rx.test(controls[i].id))
        {
            result = controls[i];
            break;
        }
    }
    return result;
}

I've gone through this exercise before, but I can't remember where.  Can anyone think of a cooler way to accomplish this? 

No comments: