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
finalistfinalist 

Basic JavaScript ?: Adding a delay to (window).opener.location.reload()

Hello -
 
I have an S-Control that, for all intents and purposes, opens the existing object (an Opportunity in this case) in Edit mode and then saves it immediately with no changes.  We want to trigger a workflow rule that copies information from roll-up summary fields to the Amount field, but this is only triggered with an edit on the Opp itself, not from the child edit(s).
 
So from a link (and eventually a button), we call the S-Control, which calls Edit/Save on the Opportunity, then we reload the parent and close the child.
 
I'm using opener.location.reload().
 
The trouble is, the Opportunity page frequently refreshes too quickly, in that the database change (apparently) hasn't gone through yet.  A subsequent refresh will display the changes, but what good is that?!
 
Here's the code:
Code:
oppHasBeenSaved = false;

function init() { 
// Open Opportunity Edit page & then save the Opportunity 
    try {
         if (oppHasBeenSaved == false) {
              var url = '{!URLFOR($Action.Opportunity.Edit, Opportunity.Id)}'; 
              window.parent.location = url + "&save=1";
              oppHasBeenSaved = true;
              updateComplete();
              close();
         }
         else {
              notify();
              close();
         }
    } catch(error) {
      alert(error);
    }
} // end function init()

function updateComplete() {
    //alert("inside updateComplete ...");
    opener.location.reload();
    opener.focus();
    close();
}

Is there a way to use window.setTimeout() or some other function to allow that background activity to be completed?  (I suggested an override to the Opportunity Product's Save button, but I was overruled, hence we're doing this from Opportunity.  There's no SOQL, so there's no waiting for the return to come back.)
 
Let me know what you know.
 
Thanks!
Jay-DawgJay-Dawg

I've only been at this a couple months, so I'm rather a newbie, but thought I'd throw an idea your way.

Is it required for your trigger to navigate the browser to the Edit page? What I'm thinking is to edit/save the Opportunity using the API (the "update" method). If that's sufficient to trigger the workflow, then you could use the AJAX Toolkit code to update the Opportunity, and then only after the update returns success you can reload the page?

Of course, if updating via the API is not enough to trigger your workflow, then my suggestion won't work. I don't know the answer to that question!

Just a thought. Good luck!

P.S. To your original question, in my own research I've not found any good way to implement a pause or wait function in Javascript. There are some hack examples out there that basically force the client to repeat a task 10000 times or so, but that is a very ugly way around it. Perhaps you can buy yourself enough time just with an alert dialog that the user will have to dismiss?



Message Edited by Jay-Dawg on 01-14-2008 01:00 PM
sfdcfoxsfdcfox
window.setTimeout can be used to cause a delay. It works like this:
 
setTimeout("doSomethingMore()",1000)
 
This waits 1000 ms (1 second), then calls "doSomethingMore()" which would continue your code.
Jay-DawgJay-Dawg

According to this site:

http://www.devguru.com/Technologies/ecmascript/quickref/win_settimeout.html

 (and my own attempts in a previous project), the setTimeout method does NOT prevent the script from continuing, during the pause! It merely schedules the designated action to occur at a later time.

So in order to get it to effectively pause your code, you need to be able to break your code up into at least two separate functions. One that starts your code and ends with the setTimeout, which in turn invokes the second function containing the remainder of your code.

Depending on where/how you want the pause to occur, you might not be able to make use of setTimeout. Or it might take some finageling.

sfdcfoxsfdcfox
The idea here is that you'd have the reload occur in the setTimeout function, as follows:

Code:
// From original example:

oppHasBeenSaved = false;

function init() {
// Open Opportunity Edit page & then save the Opportunity
try {
if (oppHasBeenSaved == false) {
var url = '{!URLFOR($Action.Opportunity.Edit, Opportunity.Id)}';
window.parent.location = url + "&save=1";
oppHasBeenSaved = true;
setTimeout("updateComplete()",1000);
// You don't use close() here, that would be immediate. Let updateComplete() close().
}
else {
notify();
close();
}
} catch(error) {
alert(error);
}
} // end function init()

function updateComplete() {
//alert("inside updateComplete ...");
opener.location.reload();
opener.focus();
close();
}

 This gives his reload function a 1 second delay. This code appears to be an arbitrary fragment at any rate, since some functions are missing. But hopefully this illustrates inserting a pause.

finalistfinalist
Thanks, everyone! 

I would use this last ^ contribution to update my code, and will probably go that route next time, but (wouldn't you know it?), the client isn't actually going to be using the S-Control anyway.

"It's too much to expect all the Reps to click the button to update their opportunities."

One option that I considered was to modify the 'Save' button on the Opportunity Product page to activate the S-Control, so that no additional button clicks were required; instead we're going to use Roll Up summary fields from the Opportunity Products/Items and report on them directly, rather than use the S-Control to activate a Workflow Rule to move the Amounts to the fields that were being used for Reporting.

It's a more direct route, I s'pose - fewer possible points of failure.

Meanwhile, on another project ...

(just kidding -- I'm not going to try and co-opt my own thread!)  Thanks again!

Oh -- here's the 'entire' S-Control, if anyone were interested in something similar/derivative of same:
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script type="text/javascript" language="javascript" src="/js/functions.js"></script>
<script type="text/javascript" language="javascript" src="/soap/ajax/11.1/connection.js"></script>
<script type="text/javascript" language="javascript" src="/js/dojo/0.4.1/dojo.js"></script>
<script>
// This S-Control is designed to, from an existing Opportunity,
// open the Edit page of the Opportunity and save it, with no changes. The purpose
// of this action is to trigger Workflow rules with a single button click, rather
// than requiring the User to click through to the Edit page and back themselves.

oppHasBeenSaved = false;

function init() {
// Open Opportunity Edit page & then save the Opportunity
try {
if (oppHasBeenSaved == false) {
var url = '{!URLFOR($Action.Opportunity.Edit, Opportunity.Id)}';
window.parent.location = url + "&save=1";
oppHasBeenSaved = true;
updateComplete();
close();
}
else {
notify();
close();
}
} catch(error) {
alert(error);
}
} // end function init()

function updateComplete() {
//alert("inside updateComplete ...");
opener.location.reload();
opener.focus();
close();
}

function notify() {
alert("A problem was encountered during the Opportunity Edit. The Opportunity amounts will not be updated");
}

dojo.addOnLoad(init);

</script>
</head>

<body>
</body>
</html>

 

sumpritsumprit
Hi there,

I need to place the following S-control on the SAVE button for **Opp Edit Page** so that it creates the ALERT message each time the user clicks on the SAVE button.

How can I overwrite the SAVE button on Opportunities?

Thanks
sfdcfoxsfdcfox
Unfortunately, you can't. The Save button isn't available for overriding in this release, unless you override the entire page with a custom S-Control or visualforce component.