function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
ptepperptepper 

Context-sensitive Bug in Accessing Components with their IDs?

This is a simplified version of some code I'm testing:


Code:
<apex:page id="thePage">
<apex:pageBlock title="Title" id="mainBlock">
<apex:form id="theForm">
<p><a href='#' onclick='domtest()'>Test Link 1</a></p>
<p><a href='#' onclick="alert('{!$component.mySection.description}')">Test Link 2</a></p>
<apex:pageBlockSection title="My Section" id="mySection">
<apex:inputTextarea id="description" />
</apex:pageBlockSection>
</apex:form>
</apex:pageBlock>
<script>
function domtest(){
alert('{!$component.mySection.description}');
}
</script>

</apex:page>

When you click on 'Test Link 2' the alert works fine, and displays the id of the element (thePage:mainBlock:theForm:mySection:description). But when you click 'Test Link 1', which executes the domtest() function, it just comes up blank/empty. Shouldn't the calling the Javascript function domtest() should do exactly the same thing, since it's exactly the same code as in the onclick attribute?

In Ron Hess's blog example, he uses a visualforce component reference in a script block:
http://wiki.apexdevnet.com/index.php/Building_a_Blogging_Application_Using_Visualforce

He does place the script block after the visualforce code, so I thought order might have something to do with it. I started with the script block right after the apex:page tag, and I've tried moving the script block around the page and it doesn't change anything.

I don't understand why the exact same code would work when in the onclick attribute but not when called through a function defined in a script block. Seems like a (pretty serious) bug to me. I got to this test because I haven't been able to reference any elements by Id successfully from a script block, which makes writing functions pretty useless.

Any help would be great.

-paul
ptepperptepper
Oddly enough, the order does affect how it executes. I tried another version and it works:

Code:
<apex:page id="thePage">
<apex:pageBlock title="Title" id="mainBlock">
    <apex:form id="theForm">
    <script>
        function domtest(){
            alert('{!$component.mySection.description}');
        }
    </script>
        <p><a href='#' onclick='domtest()'>Test Link 1</a></p>
        <p><a href='#' onclick="alert('{!$component.mySection.description}')">Test Link 2</a></p>
        <apex:pageBlockSection title="My Section" id="mySection">              
            <apex:inputTextarea id="description" />
        </apex:pageBlockSection>
    </apex:form>
</apex:pageBlock>


</apex:page>

Still seems like a bug, or at least an oddity that should be mentioned in the documentation.
 

jwetzlerjwetzler
We are actually working on updating the doc with more examples on this right now.  $Component is definitely context aware.  Your first example should work if you use $Component.mainblock.mysection.description.

There are a few partially complete responses on these forums about $Component usage, but look for more thorough doc in the near future.
ptepperptepper
Jill,

Thanks for the reply. I had to add 'theForm' in there but it worked with $Component.mainBlock.theForm.mySection.description when the script block is right after the apex:page tag (the highest up it can be). I've looked through the $component references on the forums but didn't see anything about the references changing depending on their context in the hierarchy, so that might be good to add to the docs in the future.

I've been trying to use these Component IDs to select elements with jQuery, and I've found that doing it the standard way in jQuery, using # to indicate an id, doesn't seem to work. For example:

$("#{!$Component.mainBlock.theForm.mySection.description}").toggle()

This does generate the right javascript code though, as far as I can tell. However, something like this, using the XPath style selector, does seem to work most of the time:

$("textarea[@id={!$component.thePage.mainBlock.theForm.mySection.description}").toggle();

These should do the same thing, but they don't.

-paul


Message Edited by ptepper on 07-18-2008 01:08 PM