I have retired this approach in favour of a much neater solution that can be found here.
Salesforce used in conjunction with JavaScript and Ajax can be pretty smashing. I’ve used a number of JavaScript libraries that make you want to high-five yourself when implemented. There can(and probably will) be some frustration while you bend a library and make it fit within the Salesforce framework, although Ron Hess has some pretty sweet examples for you to pore over.
One simple frustration I’ve come across is that of retrieving elements by Id. Salesforce has an intelligent scheme in place which ensures that HTML elements don’t have duplicate Ids and therefore conform to W3C standards. Consider the following VisualForce page
<apex:page id=”thePage”>
<apex:pageBlock id=”theBlock”>
<apex:outputText id=”theText” …/>
</apex:pageBlock>
</apex:page>
The generated element Id for the outputText field would be ‘thePage:theBlock:theText’ and not simply ‘theText’. In terms of web-standard conformity this is great, but for the beginner combining JavaScript and VisualForce this can be a nightmare. Imagine you have an outputText field nested ten levels deep within the page. Were you to hardcode the Id of this element within your JavaScript you have to bear the following in mind,
- Salesforce give elements random Id values if you don’t assign them explicitly. To prevent this you have to assign an Id to each parent element.
- If you change the page tree structure that precedes said element, you have to change the Id referenced in your JavaScript.
Not the most fun you’ve had, and a lot of hard work if you ask me. Luckily there is a simple solution, and it’s easily maintained as well as flexible. All you have to do is assign the element value to a JavaScript variable just after it appears in the page(or at the same level within the page tree). The code would become
<apex:page id=”thePage”>
<apex:pageBlock id=”theBlock”>
<apex:outputText id=”theText” …/>
<script> var theText = document.getElementById(“{!$Component.theText}”); </script>
</apex:pageBlock>
</apex:page>
Baddabing baddaboom! Now you can reference the JavaScript variable ‘theText’ from within you JavaScript code and be happy that all that nonsense about hardcoding the Id value is behind you.
this is good, thanks!!
this is good, thanks!!
this is good, thanks!!
This worked great. May I ask some assistance, please.
… some parts missing …
Thanks, Brian
So does it take anything special to get this to work? I can’t get it to return anything.
For example, I have the following in my form and {!$Component.caseSubType} doesn’t seem to return anything.
Nothing extra special is needed, the example I’ve given is a worked one. Perhaps you can post a bit more code to the discussion boards and PM me a link to the post? My username is wesnolte.
So does it take anything special to get this to work? I can’t get it to return anything.
For example, I have the following in my form and {!$Component.caseSubType} doesn’t seem to return anything.
Nothing extra special is needed, the example I’ve given is a worked one. Perhaps you can post a bit more code to the discussion boards and PM me a link to the post? My username is wesnolte.
Thank you for this but it does not seem to work for me. Here is the code i am using and the alert is not being displayed.
var zip = document.getElementById(“{!$Component.zipcode}”);
alert(‘zip:’+zip);
is your declaration of the variable ‘zip’ at the same level in the DOM tree as the visualforce element with Id ‘zipcode’? Note that ‘zipcode’ is also case-sensitive.
Yes it is within the same pageBlocksection.
var zip = document.getElementById(“{!$Component.zipcode}”);
alert(‘zip:’+zip);
WordPress strips some stuff out. Can you post your full code here: http://pastebin.com/. And link to it please.
is your declaration of the variable ‘zip’ at the same level in the DOM tree as the visualforce element with Id ‘zipcode’? Note that ‘zipcode’ is also case-sensitive.
Yes it is within the same pageBlocksection.
var zip = document.getElementById(“{!$Component.zipcode}”);
alert(‘zip:’+zip);
is your declaration of the variable ‘zip’ at the same level in the DOM tree as the visualforce element with Id ‘zipcode’? Note that ‘zipcode’ is also case-sensitive.
Yes it is within the same pageBlocksection.
var zip = document.getElementById(“{!$Component.zipcode}”);
alert(‘zip:’+zip);
WordPress strips some stuff out. Can you post your full code here: http://pastebin.com/. And link to it please.
http://pastebin.com/H3fUdCJF
That is the link. Thank you for the prompt response.
I made some changes at the same link. Haven’t tested though, let me know if it works.
http://pastebin.com/H3fUdCJF
That is the link. Thank you for the prompt response.
I made some changes at the same link. Haven’t tested though, let me know if it works.
I do not see the updated code. Could you please send the link to it ?
Sure it’s here: http://pastebin.com/AGr5QRuU
I do not see the updated code. Could you please send the link to it ?
Sure it’s here: http://pastebin.com/AGr5QRuU
I do not see the updated code. Could you please send the link to it ?
Here is what is displayed in the alert –
zip:[object HTMLSpanElement]
Which is correct. You are returning the entire element, if you want the value you’ll need to use zip.text or zip.value (depend which type of element is rendered, but it seems to be a span-element).
Thanks alot!
It worked by using zip.textContent.
Here is what is displayed in the alert –
zip:[object HTMLSpanElement]
Which is correct. You are returning the entire element, if you want the value you’ll need to use zip.text or zip.value (depend which type of element is rendered, but it seems to be a span-element).
Which is correct. You are returning the entire element, if you want the value you’ll need to use zip.text or zip.value (depend which type of element is rendered, but it seems to be a span-element).
Thanks alot!
It worked by using zip.textContent.
Hi,
I have a problem while retrieving elements by id. I am able to retrieve one element and append to url and send it to next page. But while doing the same for second element , i am able to capture the value using getelement by id and can append it to URL too. But , i am unable to use the url appended second value in second page.
Is there any limitation in VF or JS that only single element should be transmitted or anything?
Nope, this is doable. If you post something to the discussion boards and tweet me (twitter.com/weesildotn) the url to the post I’ll check it out. Be sure to post the relevant code.
Hi,
I have a problem while retrieving elements by id. I am able to retrieve one element and append to url and send it to next page. But while doing the same for second element , i am able to capture the value using getelement by id and can append it to URL too. But , i am unable to use the url appended second value in second page.
Is there any limitation in VF or JS that only single element should be transmitted or anything?
Hello,
I have a problem with my javascript and visualforce page concerning visualforce component Ids itself when the page is called using a URL parameter.
Please see my post on http://pastebin.com/hSjBxXXi and if you could provide me with a solution or suggest a website for reference.
Thanks in advance.
Having a quick look I’d guess that your DOM model changes if you have an Id parm, so your hardcoding of the Ids in the JS call no longer work. I’ve added in some variable declarations that should point you in the right direction. http://pastebin.com/5D9NDt3a
Thanks for your prompt reply.Your solution works :D. In the part u modified, i wanted some explanation on
I understood the variable declaration and its use. However, the placement of the variable declaration can be before (membersTable) or after (frmMembers) the id assignment in visualforce?
Secondly the membersTable + ‘:’ means referencing ids from the membersTable to the appropriate component where the javascript function is called?
Once again thanks a lot. Ur solution help us greatly.
Hello,
I have a problem with my javascript and visualforce page concerning visualforce component Ids itself when the page is called using a URL parameter.
Please see my post on http://pastebin.com/hSjBxXXi and if you could provide me with a solution or suggest a website for reference.
Thanks in advance.
Having a quick look I’d guess that your DOM model changes if you have an Id parm, so your hardcoding of the Ids in the JS call no longer work. I’ve added in some variable declarations that should point you in the right direction. http://pastebin.com/5D9NDt3a
Thanks for your prompt reply.Your solution works :D. In the part u modified, i wanted some explanation on
I understood the variable declaration and its use. However, the placement of the variable declaration can be before (membersTable) or after (frmMembers) the id assignment in visualforce?
Secondly the membersTable + ‘:’ means referencing ids from the membersTable to the appropriate component where the javascript function is called?
Once again thanks a lot. Ur solution help us greatly.
The JS variable declaration has to be at the same level in the DOM tree as the element it references. So it can be before or after as long as this rule applies.
And for the second question (if I understand correctly), yes 🙂
Just wanted to confirm if i understood correctly. Thanks once again Wes.
Hello,
I have a problem with my javascript and visualforce page concerning visualforce component Ids itself when the page is called using a URL parameter.
Please see my post on http://pastebin.com/hSjBxXXi and if you could provide me with a solution or suggest a website for reference.
Thanks in advance.
Having a quick look I’d guess that your DOM model changes if you have an Id parm, so your hardcoding of the Ids in the JS call no longer work. I’ve added in some variable declarations that should point you in the right direction. http://pastebin.com/5D9NDt3a
The JS variable declaration has to be at the same level in the DOM tree as the element it references. So it can be before or after as long as this rule applies.
And for the second question (if I understand correctly), yes 🙂
I can get this to work, BUT I am having one niche issue. Because Salesforce uses so many tables to render their pages, the scripts after a field in a pageBlockSection end up being in tables. In IE6, running a script in a table causes quirks. Namely, it makes Google Maps go awry (see http://blog.evandavey.com/2008/08/how-to-fix-problems-with-google-mapsinternet-explorer-grey-background-etc.html)
I tried putting the scripts at the end of the page, but the $Component values were not filled in.
Ideas other than not using pagBlockSections?
I can get this to work, BUT I am having one niche issue. Because Salesforce uses so many tables to render their pages, the scripts after a field in a pageBlockSection end up being in tables. In IE6, running a script in a table causes quirks. Namely, it makes Google Maps go awry (see http://blog.evandavey.com/2008/08/how-to-fix-problems-with-google-mapsinternet-explorer-grey-background-etc.html)
I tried putting the scripts at the end of the page, but the $Component values were not filled in.
Ideas other than not using pagBlockSections?
As it turns out, that wasn’t my issue. I was running script at the bottom of the page, but modified it to run “onload” using an event listener and all is good.
This was purely a Google Maps issue, so disregard.
Hi Wes, I searched on the internet and found your great post. I have some questions and wonder if you can help me with it. I have posted it on salesforce community forum.
http://boards.developerforce.com/t5/Visualforce-Development/need-some-help-sample-code-to-retrieve-parent-object-fields/td-p/209078
Please read the part starting from:” to be more specific,…”
Thanks very much for your time and help in advance!
Hi Wes, I searched on the internet and found your great post. I have some questions and wonder if you can help me with it. I have posted it on salesforce community forum.
http://boards.developerforce.com/t5/Visualforce-Development/need-some-help-sample-code-to-retrieve-parent-object-fields/td-p/209078
Please read the part starting from:” to be more specific,…”
Thanks very much for your time and help in advance!
Hi Wes, I searched on the internet and found your great post. I have some questions and wonder if you can help me with it. I have posted it on salesforce community forum.
http://boards.developerforce.com/t5/Visualforce-Development/need-some-help-sample-code-to-retrieve-parent-object-fields/td-p/209078
Please read the part starting from:” to be more specific,…”
Thanks very much for your time and help in advance!
The markup would be much simpler to just wrap the input with a span that has a certain id or class and your done. No inline javascript.
Using jQuery, you could then just say:
$el = $(‘input’, mySelector );
…and you’re done.
That is very true! In some cases it would break salesforce’s styling but in most cases this would work. At the top of this post I’ve noted that this approach is old and I no longer use it, there’s a better way that I’ve shown here: http://th3silverlining.com/2011/06/24/salesforce-a-better-way-to-work-with-visualforce-component-ids-and-javascript/
The markup would be much simpler to just wrap the input with a span that has a certain id or class and your done. No inline javascript.
Using jQuery, you could then just say:
$el = $(‘input’, mySelector );
…and you’re done.
That is very true! In some cases it would break salesforce’s styling but in most cases this would work. At the top of this post I’ve noted that this approach is old and I no longer use it, there’s a better way that I’ve shown here: http://th3silverlining.com/2011/06/24/salesforce-a-better-way-to-work-with-visualforce-component-ids-and-javascript/
The markup would be much simpler to just wrap the input with a span that has a certain id or class and your done. No inline javascript.
Using jQuery, you could then just say:
$el = $(‘input’, mySelector );
…and you’re done.
Very good Idea!!!