You need to sign in to do that
Don't have an account?
alexannic
S-control page loads only after the whole script is finished!
Hello,
I have written some S-control scripts using AJAX toolkit, and some of them take some time to complete. It would be nice to show some text while parts of the scripts are running so that the user has some feedback on what's happening.
Currently, the S-control appears in a popup window and is blank until the whole script is finished. My code is as follows:
Code:
Code:
Many thanks.
I have written some S-control scripts using AJAX toolkit, and some of them take some time to complete. It would be nice to show some text while parts of the scripts are running so that the user has some feedback on what's happening.
Currently, the S-control appears in a popup window and is blank until the whole script is finished. My code is as follows:
Code:
function initPage() { document.getElementById('divErrorMsg').innerHTML = "starting..."; //Get Salesforce connection based on users current session id sforceClient.registerInitCallback(setupPage); sforceClient.init("{!API_Session_ID}", "{!API_Partner_Server_URL_70}", true);then setupPage function executes...and finally the HTML appears:
Code:
<body onload="initPage();"> <center> <DIV id="divErrorMsg"></DIV> </center> </body> </html>Is there any way I can update the div element during the execution of the script?
Many thanks.
Can anyone provide any assistance?
How can I refresh a div element in the page?
Thanks.
So if you want to "show a message" to provide a good user experience, you must allow the browser to "catch it's breath"
This can be done with setTimeout()
So in your example you would do something like this
the 50 msec is enough ( usualy ) for the browser to paint the DIV innerHTML and then the second initPage2 gets called and real work begins.
you can play with the timout to match your needs.
Thank you for your answer.
I have tried the setTimeout() function but with no luck. My S-Control will popup an HTML form with 15 textboxes, allowing the user to enter many product codes and quantities into an Opportunity at once. This is my code:
Code:
At the press of Submit button, the ExecuteSave function is called. For every code found in the textboxes, its Product2ID is retrieved with the GetPriceBookID function. I have a line (in bold) where I update the divProgress element with the current product code.
I suppose that since I'm using AJAX the screen will be refreshed! What happens is that the button freezes when pressed and after a while when the script is finished I see only the last code.
Isn't AJAX supposed to allow asynchronous calls? Shouldn' then the screen be updated every time the innerHTML function is called?
Many thanks for your time.
Alex
Here's the doc (for some reason, the function prototype doesn't have the async flag, but the parameters list does):
query
Performs a query operation
Parameters:
soql
- The sforce object query language that constitutes a selection.callback
- A pointer to a function to be called once the http request has returned.async
- A flag to indicate that the call should be made asynchronously or not. A value of true will cause the method to return immediately and once a response is recieved, the callback function will be invoked and passed the results of the call.And here's some code I'm using. It calls asynchronously, and the message appears while you wait:
function CreateAccountAndContact() {
// display a message next to the button
var msg = document.getElementById("message");
msg.innerHTML = "Creating account. DO NOT CLICK AGAIN.";
// create a new account
var acc = new Sforce.Dynabean("Account");
acc.set("Name",accountname);
acc.set("BillingStreet", document.getElementById ('00N30000001Hfh4').value);
acc.set("BillingCity", document.getElementById ('00N30000001Hfgb').value);
acc.set("BillingState", document.getElementById ('00N30000001Hffw').value);
acc.set("BillingCountry", document.getElementById ('00N30000001Hffs').value);
acc.set("BillingPostalCode", document.getElementById ('00N30000001Hfgl').value);
acc.set("RecordTypeId", '01230000000DJPAAA4');
sforceClient.Create([acc], step2, true);
}
var accid="";
function step2(saveResult) {
// create the contact
accid=saveResult[0].id;
var contact = new Sforce.Dynabean("Contact");
contact.set("AccountId", accid );
contact.set("FirstName", con1fname);
contact.set("LastName", con1lname);
contact.set("Phone", document.getElementById('c1phone').value);
contact.set("HomePhone", homephone);
sforceClient.Create([contact], step3, true);
}
function step3(saveResult) {
// open the new account record
parent.frames.location.replace("/"+accid);
}
My code actually has many more "steps" -- each in another function. Each toolkit call sets up the callback to the next. It gets tricky, though, because your local variables disappear between calls. If you want to do a bunch of steps with the same account, make sure your variables (like accid above) are declared with global scope (outside any function) so they will be available to all the functions.
Crazy stuff. My s-controls are working a lot better this way, and they appear to be much more responsive.
Evan Callahan
NPower Seattle
Your code shows exactly the effect I want to achieve however it has the following limitation:
I have a form where the user enters 15 product codes that are to be entered in an Opportunity.
My code loops through these 15 product codes and each time searches for their product2ID value.
At the end, all those ProductIDs are entered in OpportunityLine objects and saved.
In other words...
Code:
The problem:
The loop ends before the asynchronous calls return the results, and the save function attempts to save an empty dynabean.
The code works if the process can be split into distinct steps, but what can you do in a loop situation? You certainly can't write 15 identical steps, one for each code??
Once again I appreciate the help!
Alex
Message Edited by alexannic on 10-14-2006 10:34 AM
var PCodes = new Array();
//put the codes into this array here
sforceClient.Retrieve("Id", "Product2", PCodes, GetProductIDs, true);
function GetProductIDs(arrayOfIDsFromProduct2) {
// process all resulting codes here
}
Alternatively, you can query asychronously in a loop. Your first call sets up the loop, then your result function gets called for the first record and in turn calls itself for the next record:
var ProductsToAdd = 0; // must be declared outside any function