August 18, 2011

Referencing Components in JavaScript — When $Component Comes Up Blank

Today's most is more of a heads up, just to maybe help people who encounter a problem I've come across more than a few times during my Visualforce escapades. As you probably know, if you want to reference a Visualforce apex element from JavaScript you have to use the $Component notation:

<!-- Markup --> 
 <apex:inputField id="MyInputField" value='{!SomeControllerMember}'/> 
... 
// JavaScript 
var myElement = document.getElementById('{!$Component.MyInputField}');

On many an occasion I've found this to simply not work for me, when I view the source of the generated page the ID will be missing, i.e. my script will read document.getElementById(''). This has been quite a source of considerable frustration at times and the documentation here doesn't really hint at the solution; what it does do is have a link to Best Practices for Accessing Component IDs, and therein lies the magical answer.

I urge you to go and read this page, but here is the vital part:

The $Component global variable simplifies references and reduces some of the dependency on the overall page structure. For example, to access a data table with id="tableID" contained in a page block with id="blockID", use the following expression: $Component.blockID.tableID.

That's really all there is to it, you must drill down through the IDs of all the containers, mystery solved.