[SalesForce] Update Record values on Visualforce Extension by actionSupport

Background

I have a VF page that use StandardController="Opportunity" and also extensions="OpportunityControllerExt".

I'm showing the opp.stageName and the opp.Probability. When the StageName changes I need to update the right probability.

Approach

I've created a map<stageName,probability> and also a actionSupport onchange that update the probability (for visualisation) on my extension.

sample code:

page:

<apex:actionRegion >
                    <apex:inputField value="{!Opportunity.StageName}" id="status">
                        <apex:actionSupport event="onchange" action="{!updateProbability}"
                            rerender="blockSection"  immediate="true">
                        </apex:actionSupport>    
                    </apex:inputField>    
                </apex:actionRegion>  

<apex:inputField value="{!Opportunity.Probability}" id="probability"/> 

extension:

public class OpportunityControllerExt {
    public static Opportunity opp {get;set;}
   
    private map<string,decimal> probabilities = new map<string,decimal>();
    public OpportunityControllerExt(ApexPages.StandardController stdController){        
        OpportunityControllerExt.opp = (Opportunity)stdController.getRecord();
        .....
    }
    public PageReference updateProbability(){
        //probabilities map was made before
        OpportunityControllerExt.opp.Probability = probabilities.get(OpportunityControllerExt.opp.StageName);
        
        return null;
    }

The method is called fine, but…

Problem

The referenced Opp on my extension is not getting the updated value of stageName. I think that I'm doing something wrong when i'm binding the opp record.

Question

Is any way to get a changed field value from and extension and then update the value of other field?

Best Answer

Yes. You have specified immediate="true". Doing that causes the setters to not be called, so the value is not set. You need to change it to immediate="false" or just remove it as false is the default.

The <apex:actionSupport> documentation doesn't exactly specify that, so it isn't clear. Note that setting immediate="false" will cause validation to fire, so if you have anything like required fields or something on the page you should look into using <apex:actionRegion> to limit what is processed on the submission.

The Order of Execution for Visualforce Postback Requests documents the behavior of immediate="true", specifically that the view state is not decoded (i.e., new values won't be used). It has the following for step #1 in the processing:

  1. During a postback request, the view state is decoded and used as the basis for updating the values on the page.

Note A component with the immediate attribute set to true bypasses this phase of the request. In other words, the action executes, but no validation is performed on the inputs and no data changes on the page.

A common use of immediate="true" is navigating via a command button. For example:

<apex:commandButton action="{!cancel}" value="Cancel" immediate="true"/>
Related Topic