2

Reading through a topic - Best Practices for Accessing Component IDs, I learned that:

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.

What does this actually mean? Why can't I just use grandparentId.parentId.itemId in Javascript instead of referencing the id using $Component.grandparentId.parentId.itemId.

7

It's very nicely described in the documentation that you linked what it does and how it works. It's for simplicity to reference components throughout the hierarchy, without the need of explicitly providing an ID for every single component and writing ridiculous selectors. Have a look at the following examples to see the benefit:

<apex:page id="page">
    <apex:form id="form">
        <apex:pageBlock id="pageBlock">
            <apex:pageBlockSection id="section">
                <apex:outputPanel id="panel1">
                    <apex:outputPanel id="panel2">
                        <apex:outputPanel id="panel3">
                            <div>some content</div>
                            <script>
                                // document.getElementById('page:form:pageBlock:section:panel1:panel2:panel3')
                                // vs
                                // document.getElementById('{!$Component.panel3}')
                            </script>
                        </apex:outputPanel>
                    </apex:outputPanel>
                </apex:outputPanel>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Also in cases where an element doesn't have a specific ID, VisualForce automatically assigns one in the shape of j_id#. So there is no way to know the exact ID of an element. That's where $Component comes handy again. Even if you find the exact ID with the DOM inspector in your browser, any changes in the hierarchy will make that ID invalid. If you use $Component, you wouldn't need to change anything:

<apex:page>
    <apex:form>
        <apex:pageBlock>
            <apex:pageBlockSection>
                <apex:outputPanel>
                    <apex:outputPanel>
                        <apex:outputPanel id="myPanel">
                            <div>some content</div>
                            <script>
                                // document.getElementById('j_id0:j_id1:j_id2:j_id3:j_id4:j_id5:myPanel')
                                // vs
                                // document.getElementById('{!$Component.panel3}')
                            </script>
                        </apex:outputPanel>
                    </apex:outputPanel>
                </apex:outputPanel>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>
1
  • This is awesome!
    – Arnold
    Dec 12 '17 at 13:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.