To refer to a Visualforce component in JavaScript or another Web-enabled language, you must specify a value for the id attribute for that component. A DOM ID is constructed from a combination of the id attribute of the component and the id attributes of all components that contain the element.
Use the $Component global variable to simplify referencing the DOM ID that is generated for a Visualforce component, and reduce some of the dependency on the overall page structure. To reference a specific Visualforce component’s DOM ID, add a component path specifier to $Component, using dot notation to separate each level in the component hierarchy of the page. For example, use $Component.itemId to reference a component at the same level in the Visualforce component hierarchy, or use $Component.grandparentId.parentId.itemId to specify a more complete component path.
There is no backtracking, so if the ID you’re trying to match requires a traversal up and then back down, it won’t match.
<apex:page > <style> .clicker { border: 1px solid #999; cursor: pointer; margin: .5em; padding: 1em; width: 10em; text-align: center; } </style> <apex:form id="theForm"> <apex:pageBlock id="thePageBlock" title="Targeting IDs with $Component"> <apex:pageBlockSection id="theSection"> <apex:pageBlockSectionItem id="theSectionItem"> All the alerts refer to this component. <p>The full DOM ID resembles something like this:<br/> j_id0:theForm:thePageBlock:theSection:theSectionItem</p> </apex:pageBlockSectionItem> <!-- Works because this outputPanel has a parent in common with "theSectionItem" component --> <apex:outputPanel layout="block" styleClass="clicker" onclick="alert('{!$Component.theSectionItem}');"> First click here </apex:outputPanel> </apex:pageBlockSection> <apex:pageBlockButtons id="theButtons" location="bottom"> <!-- Works because this outputPanel has a grandparent ("theSection") in common with "theSectionItem" --> <apex:outputPanel layout="block" styleClass="clicker" onclick="alert('{!$Component.theSection.theSectionItem}');"> Second click here </apex:outputPanel> <!-- Works because this outputPanel has a distant ancestor ("theForm") in common with "theSectionItem" --> <apex:outputPanel layout="block" styleClass="clicker" onclick="alert(' {!$Component.theForm.thePageBlock.theSection.theSectionItem}');"> Third click here </apex:outputPanel> </apex:pageBlockButtons> </apex:pageBlock> <!-- Works because this outputPanel is a sibling to "thePageBlock", and specifies the complete ID path from that sibling --> <apex:outputPanel layout="block" styleClass="clicker" onclick="alert('{!$Component.thePageBlock.theSection.theSectionItem}');"> Fourth click here </apex:outputPanel> <hr/> <!-- Won't work because this outputPanel doesn't provide a path that includes a sibling or common ancestor --> <apex:outputPanel layout="block" styleClass="clicker" onclick="alert('{!$Component.theSection.theSectionItem}');"> This won't work </apex:outputPanel> <!-- Won't work because this outputPanel doesn't provide a path that includes a sibling or common ancestor --> <apex:outputPanel layout="block" styleClass="clicker" onclick="alert('{!$Component.theSectionItem}');"> Won't work either </apex:outputPanel> </apex:form> </apex:page>
Within each hierarchy segment in a page, the component id must be unique. However, Salesforce recommends you use an id that is unique on the page for every component you need to reference, and any components above it in the component hierarchy that are needed to reference it.
For example, suppose you had two data tables in a single page. If both data tables are contained in the same page block, they must have unique id attributes. If each is contained in a separate page block, it’s possible to give them the same component id. If you do so, however, the only way to reference a specific data table is to assign an id to every component and then reference the data table component using the complete hierarchy, rather than letting Visualforce do it automatically. If the page hierarchy ever changes, your program will no longer work.
Some components, such as tables and lists, support iteration over a collection of records. After you assign an ID for these types of components, the system assigns a unique “compound ID” to each iteration of the component based on the initial ID.
<apex:page standardController="Account" recordSetVar="accounts" id="thePage"> <apex:dataTable value="{!accounts}" var="account" id="theTable"> <apex:column id="firstColumn"> <apex:outputText value="{!account.name}"/> </apex:column> <apex:column id="secondColumn"> <apex:outputText value="{!account.owner.name}"/> </apex:column> </apex:dataTable> </apex:page>
<table id="thePage:theTable" border="0" cellpadding="0" cellspacing="0"> <colgroup span="2"/> <tbody> <tr class=""> <td id="thePage:theTable:0:firstColumn"> <span id="thePage:theTable:0:accountName">Burlington Textiles</span> </td> <td id="thePage:theTable:0:secondColumn"> <span id="thePage:theTable:0:accountOwner">Vforce Developer</span> </td> </tr> <tr class=""> <td id="thePage:theTable:1:firstColumn"> <span id="thePage:theTable:1:accountName">Dickenson</span> </td> <td id="thePage:theTable:1:secondColumn"> <span id="thePage:theTable:1:accountOwner">Vforce Developer</span> </td> </tr> </table>
To refer to all entries in a column, you have to iterate across the table rows, referring to each <td> element that has an ID following the format of the column.
The same type of ID generation is done for elements within the table cells. For example, the account name in the first row is generated as a span with the ID thePage:theTable:0:accountName. Notice that ID does not include the value of the ID for the column it’s in.