1

So Im trying to use javascript in a Visualforce page to show/hide elements on click so I dont have to deal with selective rendering. To do this I have to pass the ID of the I want hidden/shown on click/change/etc. Now this works fine for most things for example I want to hide a whole pageblock I pass call the function I created as so:

  showHide('{!$Component.entireform.blockOne}');

simple enough. But then if I try to do the same with an element that is more specific it becomes much more complicated:

showHide(('{!$Component.entireform.thirdSection.thirdSectionItem.thirdSectionGrid.panel2.input2}'))

this statement references an item thats nested in the main pageblock, that has a pageblocksection in it, that has a pageblocksectionitem, that has a panelgrid, that has an outputpanel, in which lies our textbox.

As you can see this is ENTIRELY too complicated. Sure I should probably take a second look at my page structure and see if its all necessary, and rethink my naming conventions, but surely this will arise at some point. This leads to horribly unreadable code, lots of room for error, and no modularity as when someone changes any element in that hierarchy that ID is no longer valid. Is there a better way to pass that ID that Im just missing?

3
  • Most of the time the code turns out cleaner if you use CSS classes (that don't typically have any styles defined) as markers and base your logic on those. Modern browsers match those very quickly and something like jQuery makes for clean syntax. Its an alternative to consider. – Keith C Jul 17 '14 at 19:18
  • You mean like using styleClass ="foo" on components? Because it seems like quite a few don't have that capability. Its also preferable for me not to have to use jQuery. – user2070057 Jul 17 '14 at 19:23
  • Yes the value of the Visualforce styleClass attribute ends up as a HTML element class attribute; I've generally found that the mechanism is available where I need it to be. On jQuery, all I can say is that the results are usually better with it than without it. – Keith C Jul 17 '14 at 23:01
3

Depending on where you are using the $Component global variable you may not need to use the complete item path.

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.

A $Component path specifier is matched against the component hierarchy:

  • At the current level of the component hierarchy where $Component is used; and then

  • At each successive higher level in the component hierarchy, until a match is found, or the top-level of the component hierarchy is reached.

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.

From Best Practices for Accessing Component IDs

So you could use Javascript at each level to either define a variable with the DOM ID or directly run the required javascript. E.g.

<apex:inputText value="{!fooBar}" id="input2" label="Foo"/>
<!-- This script is at the same level as input2, so id doesn't need the
     component hierarchy path to get the correct DOM ID -->
<script>
    var input2DomId = '{!$Component.input2}';
    // or
    showHide('{!$Component.input2}');
</script>
1
  • Sorry for the late reply I hadnt been working on this project but I just tried this and it worked perfectly. I could of swore I tried that combination but apparently not. Thanks a lot! – user2070057 Jul 24 '14 at 19: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.