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
Mike ArthurMike Arthur 

On a Visualforce page, how do I wait for database update to complete before continuing?

I'm sure this must be a common requirement but I haven't been able to find what I need.

I have a Visualforce page with a standard controller.  The user updates one field on that page then clicks a button to update the record and then display a different visualforce page with a custom controller which uses the value that has just been updated.

How can I ensure that the first update has completed before the new page is displayed?

I originally had two buttons, one to 'Update' and one to display new page.  However, I fear impatient users will continue before the update has completed, so want to combine into one and bake in the control.  I have used a Javascript function to pass parameters and display the second page.

Thanks,
Mike.
Best Answer chosen by Mike Arthur
Swayam@SalesforceGuySwayam@SalesforceGuy
Hi Mike,

Value you are passing to windows.open url are the old, it will never get the new value, What you do, is change list bit lost of ManageQWList VF instead of getting there parameter you can get new site id, use new site to get all the value in controller,

This page code will look like, also just over ride the save method using extension
 
<apex:page standardController="Quote" extension="ExtQuote">
 <apex:form id="form">
    <script>
     function SetUpWorks()
     {
	 var siteName       = document.getElementById("{!$Component.form.pageBlock.pageBlockSection.site}").value;
	 
         if({!ISBLANK(Quote.QW_Site__c)}) {
            alert("You must select a site before setting up the Works");
         } else {
            CallApexSave();
			
            window.open("/apex/ManageQWList?parentId={!JSENCODE(Quote.Id)}&QWSiteId="+siteName+","_blank");
         }
     }
	 
	
    </script>
    <apex:actionFunction name="CallApexSave" action="{!save}" />
    <apex:pageBlock title="Select site where works are to be carried out:" id="pageBlock">
        <apex:pageMessages/>
        <apex:pageBlockSection id="pageBlockSection">
          <apex:inputField value="{!Quote.QW_Site__c}" id="site"/>
//        <apex:commandButton action="{!quicksave}" value="Update" />
        </apex:pageBlockSection>
    <apex:pageBlockButtons location="bottom">
        <apex:commandButton onclick="SetUpWorks();" value="Add Works for this Site" />
    </apex:pageBlockButtons>
    </apex:pageBlock>
 </apex:form>
</apex:page>

Hope this helps,

--
Thanks,
Swayam Chouksey
@salesforceguy

All Answers

William TranWilliam Tran
Mike,

Unless you explicitly wrote Asynchronous code (like using @future), you should not have a problem.

That is, the save/update will occur/complete before you are taken to the next page.

As a common practice, if your question is answered, please choose 1 best answer.
But you can give every answer a thumb up if that answer is helpful to you.

Thanks

 
Swayam@SalesforceGuySwayam@SalesforceGuy
Hi Mike,

I agree with william but to make it more informative you can use this 
 
<apex:commandButton title="Update" value="Save" action="{!Save}" status="counterStatus"  rerender="counterStatus" />

<apex:actionStatus > <img url="/apexpages/devmode/img/saveStatus.gif" /> </apex:actionStatus>

Hope this help,

--
Thanks,
Swayam
@salesforceguy
Mike ArthurMike Arthur
Thanks @william @salesforceguy -

That's what I figured, it should be synchronous, but it's not.  Maybe because I'm doing it in Javascript?

Here's my page - When I select a new site (an Account lookup) and click 'Add Works for this Site' the next page is displayed but the site name is the original one, not the updated one.

I wondered if the update was completing but the old site value was being passed to the next page so I added a 'rerender' but no difference.  When I continue to the next page and enter a record it is created with the old site name :-(
<apex:page standardController="Quote">
 <apex:form >
    <script>
     function SetUpWorks()
     {
         if({!ISBLANK(Quote.QW_Site__c)}) {
            alert("You must select a site before setting up the Works");
         } else {
            CallApexSave();
            window.open("/apex/ManageQWList?parentId={!JSENCODE(Quote.Id)}&QWSiteId={!JSENCODE(Quote.QW_Site_ID__c)}&QWSiteName={!JSENCODE(Quote.QW_Site__r.Name)}","_blank");
         }
     }
    </script>
    <apex:actionFunction name="CallApexSave" action="{!save}" rerender="site"/>
    <apex:pageBlock title="Select site where works are to be carried out:">
        <apex:pageMessages/>
        <apex:pageBlockSection>
          <apex:inputField value="{!Quote.QW_Site__c}" id="site"/>
//        <apex:commandButton action="{!quicksave}" value="Update" />
        </apex:pageBlockSection>
    <apex:pageBlockButtons location="bottom">
        <apex:commandButton onclick="SetUpWorks();" value="Add Works for this Site" />
    </apex:pageBlockButtons>
    </apex:pageBlock>
 </apex:form>
</apex:page>

Appreciate your help!
 
Swayam@SalesforceGuySwayam@SalesforceGuy
Hi Mike,

Value you are passing to windows.open url are the old, it will never get the new value, What you do, is change list bit lost of ManageQWList VF instead of getting there parameter you can get new site id, use new site to get all the value in controller,

This page code will look like, also just over ride the save method using extension
 
<apex:page standardController="Quote" extension="ExtQuote">
 <apex:form id="form">
    <script>
     function SetUpWorks()
     {
	 var siteName       = document.getElementById("{!$Component.form.pageBlock.pageBlockSection.site}").value;
	 
         if({!ISBLANK(Quote.QW_Site__c)}) {
            alert("You must select a site before setting up the Works");
         } else {
            CallApexSave();
			
            window.open("/apex/ManageQWList?parentId={!JSENCODE(Quote.Id)}&QWSiteId="+siteName+","_blank");
         }
     }
	 
	
    </script>
    <apex:actionFunction name="CallApexSave" action="{!save}" />
    <apex:pageBlock title="Select site where works are to be carried out:" id="pageBlock">
        <apex:pageMessages/>
        <apex:pageBlockSection id="pageBlockSection">
          <apex:inputField value="{!Quote.QW_Site__c}" id="site"/>
//        <apex:commandButton action="{!quicksave}" value="Update" />
        </apex:pageBlockSection>
    <apex:pageBlockButtons location="bottom">
        <apex:commandButton onclick="SetUpWorks();" value="Add Works for this Site" />
    </apex:pageBlockButtons>
    </apex:pageBlock>
 </apex:form>
</apex:page>

Hope this helps,

--
Thanks,
Swayam Chouksey
@salesforceguy
This was selected as the best answer
Jason CarriganJason Carrigan

Have you considered doing the same functionality in a controller extension? You could still use the standard controller if desired, and override the save method to return a PageReference redirecting to the desired visualforce page. See this post: https://developer.salesforce.com/forums/?id=906F00000009F17IAE

That would be the more Apexy way to do it.
Mike ArthurMike Arthur
Thanks Swayam,

I'm pretty new to Javascript so that's a big help.  It now passes the updated site (Account) name to the next page.
Unfortunately, I can't get the updated Id of the site to be passed.  I tried adding it as a hidden field and rerendering after the save but the original Id is being passed to the second page.

I was trying to avoid building a controller extension as I then have to build a test class too, but maybe that's the way to go.

Any suggestions?
Mike ArthurMike Arthur
Ok, it's working :-)

Problem was that using the JS route, the name of the account was being passed so I created a custom formula field to get the id.  It was the value of the formula field that I was trying to use to pass the Id and that doesn't appear to get updated.

With the controller extension route, the id is passed as the value for the Account field.  Using that instead of the formula field, the updated value gets passed, as everyone above says would be the case!

Thanks to all and remember not to use formula fields to pass values!