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
MarkL.ax269MarkL.ax269 

URLFOR, list buttons, and view return URLs

This seems simple, but it's got me stopped cold. I've got a list button designed to be used in a list view (not a related list). It allows the user to select a number of opportunities and then mass-edit them in a controlled manner. My problems started when trying to return the user to the list view on complete. Here's what I want to do:

  1. User opens the list view, selects a number of opportunities, and clicks the Update button
  2. A new page is opened within the iframe - "existing window with sidebar"
  3. User updates field values
  4. User clicks Save
  5. Opportunities are updated and the user is returned to the list view
Here are the problems I've had:
  1. If I use the "existing window with sidebar" on the button and launch my scontrol, the display to the user works fine.  Except there's no clean way I can find to return the user to the list view.  $Request doesn't work because there is no retURL passed.
  2. So I tried OnClick Javascript and URLFOR.  I can get my source URL for the view then, but apparently URLFOR expects Object.Field as parameters and won't accept javascript variables, strings, anything else.
  3. Ok, old-fashioned way.  Still using OnClick Javascript, I called the scontrol using the servlet.integration method and passed in my parameters.  This works great and I can return the user to the list view.  However I cannot force the scontrol to open within the original frame!  It replaces the entire window every time no matter what combination of parent.frames.location, window.location, etc.
Any suggestions?  My current OnClick javascript is below.
Code:
var arrOppIds = {!GETRECORDIDS($ObjectType.Opportunity)};
var callScontrol = "/servlet/servlet.Integration—lid=01N600000008uzZ&ic=1&retURL=" + window.location + "&oppIds=" + arrOppIds.join('-');
parent.frames.location.replace(callScontrol);

 

Ron HessRon Hess
i think you need

window.parent.location.href

rather than window.location , which is an object.

then you should have retURL when you get into your scontrol.
MarkL.ax269MarkL.ax269
Thanks Ron. Actually the return URL works fine in both ways, window.location or using the href property. My problem is how do I launch the scontrol and remain in the frame, complete with tabs and sidebar? Launching it like I've shown effectively replaces the entire salesforce UI. But I want to keep the sidebar and tabs so the user "remains in the box" so to speak. Using the button setup "same window with sidebar" accomplishes this, but there's no way to pass a return URL that way.
Ron HessRon Hess
when you launch the scontrol do you set the window.location or the window.parent.location?
MarkL.ax269MarkL.ax269
I don't explicitly set the window.location - not sure I can do that once the scontrol is launched, can I? When I click the view button, it runs the onclick javascript above to get the retURL and the list of selected opportunities.  It passes those as parameters to this scontrol, launching it and replacing the entire window UI (which is what I'm trying to avoid).

Code:
function setupPage() {
    retURL = '{!$Request.retURL}';
    strOppIds = '{!$Request.oppIds}';
         
    var arrOppIds = strOppIds.split('-');
    if (arrOppIds[0] == "") {
 alert("Please select at least one row");
 parent.frames.location.replace(retURL);
    } else {
 var strOppIds = "('" + arrOppIds.join("','") + "')";
     try {
  var result = sforce.connection.query("select o.Id, o.Name, o.StageName, o.CloseDate, o.Amount, o.Probability, o.AccountId, o.Account.Name from Opportunity o where o.Id IN " + strOppIds);
  displayOpps(result);
    } catch(error) {
  callFailed(error);
     }
    }
}
Code:
function displayOpps(result) {
    //prepare the table
    var oppIds = [];
    var tableout = "<table/>";
    if (result.size > 0) {
 //build the table header
 tableout = "<table width='100%' class=list border='0' cellspacing='0' cellpadding='0'><tr class=headerRow height=20>";
 //tableout += "<th nowrap'><input id='allopp' name='allopp' onclick=javascript:selectAllOrNone(" + result.size + ",'opp') type='checkbox' title='Toggle All Rows' value=''/></th>";
 tableout += "<th nowrap'>Name</th>";
 tableout += "<th nowrap'>Account</th>";
 tableout += "<th nowrap'>Close Date</th>";
 tableout += "<th nowrap'>Stage</th>";
 tableout += "<th nowrap'>Probability</th>";
 tableout += "<th nowrap'>Amount</th></tr>";
    
 var index = 0;
 var oit = new sforce.QueryResultIterator(result);
 while (oit.hasNext()) {
  var opp = oit.next();
  oppIds.push(opp.Id);
  tableout += "<tr onmouseover=hiOn(this) onmouseout=hiOff(this)>";
  tableout += "<td><input id='oppname" + index + "' name='oppname" + index + "' type='text'></td>";
  tableout += "<td><a href='/" + opp.AccountId + "' target=_parent>" + opp.Account.Name + "</a></td>";
  tableout += "<td><input id='oppclosedate" + index + "' name='oppclosedate" + index + "' type='text'></td>";
  tableout += "<td><select id='oppstage" + index + "' name='oppstage" + index + "' onchange='setMultiProbability(this.value," + index + ")'><option value='Budget'>Budget</option><option value='Needs Analysis'>Needs Analysis</option><option value='Proposal'>Proposal</option><option value='Negotiation & Review'>Negotiation & Review</option><option value='Closed Won'>Closed Won</option></select></td>";
  tableout += "<td><input id='probability" + index + "' name='probability" + index + "' type='text'></td>";
  tableout += "<td>" + opp.Amount + "</td>";
  tableout += "<td><input type='hidden' id='opp" + index + "' name='opp" + index + "' value='" + opp.Id +  "'/></td>";
  tableout += "<td><input type='hidden' id='oppacct" + index + "' name='oppacct" + index + "' value='" + opp.AccountId +  "'/></td></tr>";
  index++;
 }
    
 tableout += "</table>";
 document.getElementById("opplist").innerHTML = tableout;
 setDefaults(result);
    } else {
 alert("No Opportunities were found meeting this criteria.");
    }
}

 

 

Ron HessRon Hess
Mark, i think i understand what you are trying to do, i don't see any need to go to a two scontrol solution or use onclick, so correct me if i'm missing something.  This appears to work, does not do any save:


Code:
<html>
<head>
   <script type="text/javascript" src="/js/functions.js"></script>
   <script src="/soap/ajax/8.0/connection.js"></script>
<script>
var retURL; 
function onLoad() {
 retURL = "{!$Request.retURL}";
 var arrOppIds = {!GETRECORDIDS($ObjectType.Opportunity)};
  
 if (arrOppIds[0] == "") {
  alert("Please select at least one row");
  parent.frames.location.replace(retURL);
 } else {
     var strOppIds = "('" + arrOppIds.join("','") + "')";
 try {
  var result = sforce.connection.query("select o.Id, o.Name, o.StageName, o.CloseDate, o.Amount, o.Probability, o.AccountId, o.Account.Name from Opportunity o where o.Id IN " + strOppIds);
   displayOpps(result);
  } catch(error) {
   alert(error);
  }
   }
}
function jumpback() { 
 window.parent.location.href = retURL;
}

function displayOpps(result) {
    //prepare the table
    var oppIds = [];
    var tableout = "<table/>";
    if (result.size > 0) {
 //build the table header
 tableout = "<table width='100%' class=list border='0' cellspacing='0' cellpadding='0'><tr class=headerRow height=20>";
 //tableout += "<th nowrap'><input id='allopp' name='allopp' onclick=javascript&colon;selectAllOrNone(" + result.size + ",'opp') type='checkbox' title='Toggle All Rows' value=''/></th>";
 tableout += "<th nowrap'>Name</th>";
 tableout += "<th nowrap'>Account</th>";
 tableout += "<th nowrap'>Close Date</th>";
 tableout += "<th nowrap'>Stage</th>";
 tableout += "<th nowrap'>Probability</th>";
 tableout += "<th nowrap'>Amount</th></tr>";
    
 var index = 0;
 var oit = new sforce.QueryResultIterator(result);
 while (oit.hasNext()) {
  var opp = oit.next();
  oppIds.push(opp.Id);
  tableout += "<tr onmouseover=hiOn(this) onmouseout=hiOff(this)>";
  tableout += "<td><input id='oppname" + index + "' name='oppname" + index + "' type='text'></td>";
  tableout += "<td><a href='/" + opp.AccountId + "' target=_parent>" + opp.Account.Name + "</a></td>";
  tableout += "<td><input id='oppclosedate" + index + "' name='oppclosedate" + index + "' type='text'></td>";
  tableout += "<td><select id='oppstage" + index + "' name='oppstage" + index + "' onchange='setMultiProbability(this.value," + index + ")'><option value='Budget'>Budget</option><option value='Needs Analysis'>Needs Analysis</option><option value='Proposal'>Proposal</option><option value='Negotiation & Review'>Negotiation & Review</option><option value='Closed Won'>Closed Won</option></select></td>";
  tableout += "<td><input id='probability" + index + "' name='probability" + index + "' type='text'></td>";
  tableout += "<td>" + opp.Amount + "</td>";
  tableout += "<td><input type='hidden' id='opp" + index + "' name='opp" + index + "' value='" + opp.Id +  "'/></td>";
  tableout += "<td><input type='hidden' id='oppacct" + index + "' name='oppacct" + index + "' value='" + opp.AccountId +  "'/></td></tr>";
  index++;
 }
    
 tableout += "</table>";
 document.getElementById("opplist").innerHTML = tableout;

    } else {
 alert("No Opportunities were found meeting this criteria.");
    }
}
</script>
</head>


<body onload="onLoad();">
<div id="opplist"></div>
<input type="button" onclick="jumpback();" value=" all done ">
</body>
</html>

 

MarkL.ax269MarkL.ax269
Now why in the !#@##!# does that work when I couldn't get the return URL to work before? I swear I tried getting the $Request that way, but that version is long gone. Thanks, it works great!

Mark
Ron HessRon Hess
Cool, by the way are you coming to Dreamforce 2007 !

I look forward to meeting as many of the developers as possible at this super-cool event !
MarkL.ax269MarkL.ax269
I've been 4 years in a row, but will miss it this year. Big integration going live 10/1 and it wouldn't be good to go awol just before! But I'm sending two of our staff out and I know they are looking forward to it.

Mark
gptheprincegptheprince

Hi Mark

I was reading your post about this topic particular functionality:

  1. User opens the list view, selects a number of opportunities, and clicks the Update button
  2. A new page is opened within the iframe - "existing window with sidebar"
  3. User updates field values
  4. User clicks Save
  5. Opportunities are updated and the user is returned to the list view

I am a volunteer for a non profit who is implementing Salesforce. I would like to create the exact same functionality but I have no idea how to get

to 2 and 3.

Could you help me with this? Do you have an S-control that could help me?

Basically what I am trying to do is:

1 - select a list of contacts

2 - click "Assign to event"

3 - open a new window where user can select the Event

4 - Save

5 - go back to the list, or even to contacts, I do not really care at this point

If you can help me, I will really appreciate

Thanks in advance

Giorgio

SteveO1993SteveO1993

Hey Giorgio, I was just wondering if you happened to receive a solution or perhaps know where to look for one, regarding your question.  I am looking into a project of a very similar nature. 

Thanks,
Steve
gptheprincegptheprince

Unfortunately not. I ultimately used the Campaign concept to solve this particular issue