Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have a multi-step object load process that uses web callouts to populate detail records for a newly created master object.

I've been able to create a Visualforce page and a controller extension to handle the loading, by making one callout, encoding the result (X records loaded) in a query string parameter, and then having the page reload (to trigger the next step).

I use the action attribute of the apex:page tag to kick off the load process. Unfortunately, that means the page doesn't render during the callout which can take a few seconds.

I'm looking for a way I can do the following:

1) Display the rendered page (so I can have a message, "Loading FooBars...").

2) Have a method called automatically (I've considered using JavaScript to call the method, possibly via an onload callback).

3) Possibly redirect to the same page, with a different query string.

On item #3, I could probably get away with just updating part of the screen (maybe in an apex:actionStatus) and then triggering the next method via JavaScript, but I'll eventually want to redirect to the standard Detail view for the master object after all steps complete.

Is there a clean way to accomplish this?

share|improve this question
    
You can have your onload JS function in which you can show your loading image etc. Then call apex:actionfunction that will call the webservice in the backend. Also this will have rerender attribute populated to re-render the page. And finally in the apexfunction you will have oncomplete attribute (another JS function) that will hide the loading –  Bachovski Jan 30 '13 at 1:55
add comment

1 Answer 1

up vote 1 down vote accepted

Here's what I've been able to work out so far. On my VisualForce page, I have a bunch of apex:actionFunction entries for each step of the process:

  <apex:form >
    <apex:actionFunction name="step1" status="step1_status" rerender="step1_status"
      action="{!step1Method}" oncomplete="step2();"/>
    <apex:actionFunction name="step2" status="step2_status" rerender="step2_status"
      action="{!step2Method}" oncomplete="step3();"/>
    <apex:actionFunction name="step3" status="step3_status" rerender="step3_status"
      action="{!step3Method}" oncomplete="finalRedirect();"/>
  </apex:form>

Then I include multiple apex:actionStatus elements on the page:

  <apex:actionStatus id="stepX_status" startText="loading..." stopText="{!stepX_status}"/>

And end the page with JavaScript:

  <script>
    step1();
    function finalRedirect()
    {
        window.location = "{!URLFOR($Action.SomeObject__c.View, SomeObject__c.Id)}";
    }
  </script>

In my controller extension:

public String step1_status { get; private set; }
public String step2_status { get; private set; }
public String step3_status { get; private set; }

public SomeObjectExtension( ApexPages.StandardController stdController)
{
    step1_status = '';
    step2_status = '';
    step3_status = '';
}

// each step has its own method
public void stepXMethod()
{
    // do stuff that might take a few seconds

    // update stopText of actionStatus on web page
    stepX_status = 'Status to display on web page';
}

And it's working smoothly now. The <script> at the end of the page kicks off the process. Each actionFunction is asynchronous, but upon completion of one step, it automatically starts the next step with the oncomplete property. When the last step completes, it sets window.location to redirect the browser to the detail page for the object.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.