+ Start a Discussion
Edward GeeEdward Gee 

How do I return to the calling page from a custom S-Control?

Hi all,

I've built a custom HTML S-Control that is launched from a custom button with Display Type="Detail Page Button" and Behavior="Display in existing window with sidebar".  What is the recommended way to return the user back to the calling page that launched my HTML S-Control?  Should I be grabbing the query parm "eid"  from the URL and construct a relative URL with that object id or is there a better way of doing this?

- Ed
I always do this.

oppId = "{!Opportunity.Id}";
parent.frames.location.replace("/" + oppId);

There are others depending on the situation, as sometimes you can end up with the tabs doubled. But this works for most situations.
Edward GeeEdward Gee
Thanks for your reply Mark.  But what if my S-Control can be navigated from any object?  Say I embed the button in the Account, Contact and Opportunity objects.  How do I know which of those objects to return to?

- Ed
Then you would use the $Request field instead. I don't have the syntax handy but if you search online help for "global variables" you'll find it.
Edward GeeEdward Gee
I read the $Request global object doc but don't quite understand the usage, as it applies to my situation.  Are you saying the $Request global object provides me access to the query parms of the current URL string?  I tried manually adding the merge field to my S-Control to reference the eid of the URL string but Eclipse doesn't allow me to save my S-Control (Error: Field Request.eid does not exist.  Check spelling. : HtmlWrapper).

The $Request example shows passing parms from another object to an S-Control with the INCLUDE function. It then makes use of those parms by accessing them through the $Request global object.  In my situation, I'm using a button to launch my S-Control from, let's say, the Account object or another custom object created using salesforce.  I don't see how I would pass the query parms from that button to my S-Control.

- Ed
Ron HessRon Hess
the $Request object is important because it often contains the "return address" that the page came from.

in your SControl print out the value of $Request.retUrl, and see if that makes sense.  keep this value and use it to navigateTo() if the user  hits 'Cancel' or go back from your control.

Edward GeeEdward Gee
Thanks Ron for the pointer.  So I assume I have to modify the "Content Source" property on my Custom Button that launches my S-Control to "URL" or "OnClick Javascript" so I can pass in the retUrl rather than relying on the eid query parm being passed to me automatically if I set the "Content Source" property to "Custom S-Control"?  Just trying to understand what the best practice is for this situation.

- Ed
Ron HessRon Hess
not sure which is best, you have to try both to see which works better, i think the retUrl is added from most navigation so it should be there but you'll have to test in your situation.  
Edward GeeEdward Gee
From some quick testing, the retURL parm is available most of the times when navigating from standard buttons and through the related lists.  However, it seems if you define a button that launches an S-Control, the generated URL does not provide a retURL... odd.... wonder why that is.  So unless there's a magical key that allows me to turn that on, I think I'll have to wrap my call to launch my S-Control with the retURL parm being passed.

- Ed
Edward GeeEdward Gee
Interesting... we've modified the standard buttons and links for a Call with overrides (View, Edit, New) to point to my S-Control. The "View" link in the related list does not generate a URL with the retURL in it.  The "Edit" and the "New" seems to work fine.  Might this be a bug?

Also, I tried modifying my button to launch onclick Javascript to launch my S-Control with the retURL passed in which works but I was hoping my S-Control would be displayed within the current window with the sidebar and tabs but I lost them both.  Is there a way to do that from onclick Javascript?
Hi Ed,

Welcome to the board!  :-)

The URLs that we generate with URLFOR() and $Action mimic the standard salesforce URLs.  In my quick testing, the standard salesforce "View" link does not include a retURL, even when you click from a related list (e.g., viewing a contact from the contact related list on account).  Which objects did you see including the retURL for the View from a related list?  Maybe there is something amiss. 

You are able to set the retURL using the [inputs] argument in URLFOR(), which it sounds like you might already be doing.  I recommend using URLFOR() to generate what you need in the retURL, so that your code is more maintainable.

Best Practice

Best practice for your scenario "Calling My Awesome sControl from Custom Buttons on Multiple Detail Pages" is:

 - When defining the Custom Button, set the Type to "Detail Page Button", Content Source to "URL",and the Behavior to "Display in Existing Window with Sidebar".  Then use URLFOR() to build the URL that renders your sControl.  In each instance of the Custom Button, you know your context -- the Account, Contact or Opportunity object.  Set a query parameter called retURL in the URL by using the [inputs] argument.  You could also set a query parameter to pass yourself a text string to say where it came from (Account, Contact, or Opportunity) -- let's call that parm EdsParm.
 - In your Awesome sControl, reference the query parms with {!$Request.parmname} (see example below).
 - Note that the second argument in URLFOR() can be set to the ID field when referencing sControls, not just when referencing standard actions.  Note that in this example I set it to Account.Id.  That will set the eid query parameter,and the sControl context for you if you need that (that's how I am able to get the Account Name merge field in the sControl below).  Set it to null if you don't need it.


A custom button on the Account detail page would have this content:

{!URLFOR($SControl.AboutRecruiting, Account.Id, [EdsParm="Account", retURL=URLFOR($Action.Account.View, Account.Id)])}

In your Awesome sControl, reference the query parms like this:

Ed Gee's info
EdsParm: {!$Request.EdsParm}
retURL: {!$Request.retURL}
eid: {!$Request.eid}
Account Name: {!Account.Name}


I recently posted a samples doc called "Embedded Mash-Ups: Getting Started Samples".  The examples are mild compared to what the folks on this board are actually doing in real life, but they serve as simple illustrations of the new techniques introduced in Winter '07 with Custom Buttons and Links, URLFOR(), $Action, etc.  Check out this feature page on successforce.com for the link to the PDF:
http://blogs.salesforce.com/features/2006/12/embedded_mashup.htmlThe Conditional Override for Editing Leads example shows setting the retURL in a URLFOR() call.

The samples doc does not have an example of $Request, but I think there is one in the online help doc.  $Request is a useful way to pull the value of a query string from the URL when you are inside your sControl.  Using URLFOR(), with $SControl, with the [inputs] argument you can pass parameters into your sControl, and pick them up with {!$Request.whateveryourparamternameis}.  I am curious about why the Eclipse editor didn't like {!$Request.eid}.  It should not be looking at that as a field, it is a global variable (because of the {!$...} syntax).  Did you try that in the sControl Editor in Setup?  Maybe that is an Eclipse plugin enhancement request.

 - Mary Scotton, Product Manager, Apex Platform
Edward GeeEdward Gee
Thanks Mary for the tips!!!  :smileyvery-happy:


I tried a variety of things since but here are the latest stumbling blocks.

When I had tried specifying my SControl via global variable, I received an error when saving the URL Content Source.  I tried this following your example:
{!URLFOR($SControl.Call_Report,  Account.Id , [retURL=URLFOR($Action.Account.View, Account.Id)])}

but received the same error:
Error: Field Scontrol.JavaArchive does not exist. Check spelling.

However, the same reference seems to work when I place it in the OnClick Javascript editor:
self.frames.location.replace("{!URLFOR($SControl.Call_Report,  Account.Id , [retURL=URLFOR($Action.Account.View, Account.Id)])}");

But that way generates a window with my S-Control with no tabs or sidebar.  It would be ideal if I can get this to work for the URL Content Source.


As for "View" links that contain the retURL, navigate to the Leads object and create some Open Activities.  When you hover over the Subject, you'll notice the retURL has been appended to the URL.


As for the Eclipse thing, it was pilot error.  I had a typo which I corrected.

- Ed
Edward GeeEdward Gee
Interesting... so my S-Control contained a reference to the phrase "Scontrol.JavaArchive".  Even though it was commented out using Javascript semantics, the "compiler" that saved my button definition (content source=URL) complained about it.  However, if the content source is set to onclick Javascript, it didn't exhibit that behavior.  It'll be interesting to understand why it does this "scan" of my S-Control in this particular situation.

I've noticed a similar "compiler" error before in the Eclipse environment when I tried to save an S-Control containing an invalid global object reference even though it is included in a comment section in my Javascript code.

Just some interesting tidbits to take note of.

Thanks all.