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
schulttjschulttj 

Data loss with overlapping ajax actions

I have a VF page that contains multiple ajax actions.  If a user invokes a second Ajax update before the first has returned, whatever system state was changed in the first action is lost, even though it displays on the screen correctly. 

 

The code below demonstrates the issue.  Type anything into the first input box, then tab out.  Immediately type something in the second box, then tab out.  An ajax update will show the data entered next to each box correctly.  But when the button is clicked, the first update disappears, and the data it manipulated is no longer available.

 

We've instructed our client that they simply need to wait for one field refresh to complete before another is initiated, but this is making them dissatisfied with VisualForce as a platform.  Are there any alternatives?  Is this the intended behavior for ajax in VF? 

 

<apex:page controller="AjaxRefreshController"> <apex:form > <apex:messages /> <p><apex:inputText value="{!a}"> <apex:actionSupport action="{!actionRefreshA}" event="onblur" rerender="aLabel" /> </apex:inputText> <apex:outputLabel value="{!aLabel}" id="aLabel" /></p> <p><apex:inputText value="{!b}"> <apex:actionSupport action="{!actionRefreshB}" event="onblur" rerender="bLabel" /> </apex:inputText> <apex:outputLabel value="{!bLabel}" id="bLabel" /></p> <apex:commandButton action="{!verifyAExists}" value="Does Label A Exist?" /> </apex:form> </apex:page>

 

public class AjaxRefreshController { public String a {get;set;} public String b {get;set;} public String aLabel {get;set;} public String bLabel {get;set;} public PageReference actionRefreshA() { runlong(); aLabel = 'You entered ' + a; return null; } public PageReference actionRefreshB() { runlong(); bLabel = 'You entered ' + b; return null; } public PageReference verifyAExists() { if (aLabel == '' || aLabel == null) { ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR, 'aLabel does not exist', ''); ApexPages.addMessage(myMsg); } else { ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.INFO, 'aLabel exits', ''); ApexPages.addMessage(myMsg); } return null; } // simulate a long-running webservice call private String runlong() { String s = 't'; for (Integer i = 0; i < 30000; i++) { s += 't'; } return s; } }

 

Ron HessRon Hess

I think the second actionsupport request is sent to the servers with the view state that existed before the first actionsupport has completed it's round trip.

 

What would you prefer to happen, clearly the crossing of two requests can cause this issue. 

 

Would you put up a wait screen until the first request returned ? 

 

or would you gather the changes on the page until a point when the user has made several updates and then send all the changes to the server ( and place a wait screen)

 

 

schulttjschulttj

Ron,

 

Thanks for the response.

 

I don't think a wait screen would be appropriate in all circumstances, and I think we could probably simulate that in JavaScript if needed.  Our client also does not want to wait to submit several changes at once.  My problem would happily disappear at that point. 

 

Ideally, there would be a mechnism to allow partial updates to the viewstate.  This might be implemented by allowing multiple actionRegions on a page, where each actionRegion would be independent of the other.  For even more flexibility, the grouping could be determined by an attribute, so that groups wouldn't have to reside next to each other on the screen.  The ability to indicate groups of fields that should be posted together, and which in turn update the viewstate together but do not invalidate or change the rest of the viewstate, would solve the problem.

 

In truth, I wasn't holding out a lot of hope for an easy solution, but I've never seen a technical discussion of how VF implements ajax, so I didn't know if this ability existed or not. And its always good to hear what others have to say, too.  I'm sure others have run into similar issues before.

 

So if the answer is that viewstate doesn't allow partial updates, I'll just reinforce the message that users need to wait for one update to complete before starting another.