Sunday, June 1, 2008

this: i.e. frustration

Pardon my play on words.

Internet Exploiter continues to frustrate me.  In this installment, I've been arguing with the "this" keyword for longer than I ever dreamed I could suffer.

The W3C standard for "this" as it applies to error trapping is that it references the object that trapped the event -- the one with the event handle applied.  So if I attach an onclick event to a table row element, and that event invokes a function that pops up an alert dialog containing "this.id", I would expect to see an alert box with the id tag of the table row.

Of course, this works flawlessly in Firefox, as one would rightfully assume.

However, in IE, we see: "undefined"

Why?

Because IE apparently assigns "this" the value of the topmost element, which in this case would be "window."  So if I set the window.id to "something," I do in fact see the window.id value of "something" in my alert box when I click my table row with the onclick event handler attached.

This, as you might expect, isn't the most useful feature in the world.  In fact, it's one of the most inane of Microsoft's convoluted implementation of javascript I've seen to date.

The workaround for this is the most un-sexy bit of code I've seen in a long while.  Here it is, for your giggling pleasure:

var onClick = function(e) {
    if (!e) e = event;
    var src = e.target || e.srcElement;
    while(src.nodeName != 'TABLE') {
        if(src.nodeName == 'TR') {
            alert(src.id);
        }
        src = src.parentNode;
    }
};

Now, the point here is to trap the source object that triggered the event, so long as it matches the object type we're truly interested in -- in this case, the table row.  So we have to iterate up through all the elements in the tree to get to the table row, then -- finally -- grab it's id tag.

We can then send this to a custom "addEvent()" method that will append this function to the onclick event as we populate the table, a la:

addEvent(objectTableRow, onClick);

The addEvent() method is outside the scope of this blog, and honestly, there are thousands of pages dealing with this all over the web, so I'm not going to cover it here.  My particular problem above isn't as popular, which is why I chose to complain about it.

It's a long way to go to get to something as simple as a "this.id" but at least it's possible, and, fortunately for us, works in both IE and Firefox.