You need to sign in to do that
Don't have an account?

Visualforce page with fields set programatically not updating
I created a custom controller as an extension to the standard Opportunity cotroller. My visualforce page lists all of the OpportunityLineItems. When a picklist changes it launches (actionsupport) a method in my custom controller called recalcProtex. This method sets a number of custom fields based on the picklist selection. The visualforce page updates the values via the rerender attruibute on my actionsupport. So the values are showing properly on the page but when I save the values are not updating in Salesforce. The OpportunityLineItems fields that my method set are equal to null (orginal value) when mySave() medthod is called. What am I doing wrong? The field in question is Actual_List_Price__c
Apex Class
public class OppLineItemController {
private Opportunity opp;
public OppLineItemController(ApexPages.StandardController controller) {
this.opp = (Opportunity)controller.getRecord();
System.debug(opp.OpportunityLineItems[0].Actual_List_Price__c); // Set to null, which is correct
}
public PageReference recalcProtex( ) {
for(OpportunityLineItem oli : opp.OpportunityLineItems){
if(oli.PricebookEntry.Name == 'Protex'){
if (oli.Protex_Option__c != 'None'){
List<String> option = oli.Protex_Option__c.split(' ',-1);
System.debug(option);
// Users
oli.Users__c = option[0];
// Code Limit
oli.Code_Base_in_MB__c = option[2];
// List Price
String price= option[5].substring(1);
oli.Actual_List_Price__c = double.valueOf(price);
}
}
}
System.debug(opp.OpportunityLineItems[0].Actual_List_Price__c); // Set to proper value, e.g. not null
return null;
}
public PageReference mySave() {
System.debug(opp.OpportunityLineItems[0].Actual_List_Price__c); // Set to null again, why?
update opp.OpportunityLineItems;
PageReference oppPage = new PageReference('/' +System.currentPageReference().getParameters().get('id'));
return oppPage;
}
}
Visualforce Page
<apex:page standardController="Opportunity" extensions="OppLineItemController" tabstyle="Opportunity" >
<apex:form id="form1" >
<apex:pageBlock title="Products">
<apex:pageBlockTable value="{!Opportunity.OpportunityLineItems}" var="oli" cellpadding="4" >
<apex:column headerValue="Name" > {!oli.PricebookEntry.Name} </apex:column>
<apex:column headerValue="Option" >
<apex:inputField value="{!oli.Protex_Option__c}"> <apex:actionSupport event="onchange" action="{!recalcProtex}" rerender="ListPrice" /> </apex:inputField>
</apex:column>
<apex:column headerValue="List Price" id="ListPrice" >{!oli.Actual_List_Price__c} </apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
<apex:commandButton action="{!mySave}" value="Save Products"/>
</apex:form>
</apex:page>
do something like this :
<apex:outputPanel id="ListPriceTable" > <apex:pageBlockTable value="{!Opportunity.OpportunityLineItems}" var="oli" cellpadding="4" > <apex:column headerValue="Name" > {!oli.PricebookEntry.Name} </apex:column> <apex:column headerValue="Option" > <apex:inputField value="{!oli.Protex_Option__c}"> <apex:actionSupport event="onchange" action="{!recalcProtex}" rerender="ListPriceTable" /> </apex:inputField> </apex:column> <apex:column headerValue="List Price" id="ListPrice" >{!oli.Actual_List_Price__c} </apex:column> </apex:pageBlockTable> </apex:pageBlock> </apex:outputPanel>
The idea is that the output panel is outside the table , so the entire table will be refreshed, instead of the page.
you cannot refresh just a single column of a table, i believe this is a limitation of HTML ( in IE if i recall)
So, you go for the DIV outside the table as your refresh point.
that avoids refreshing the entire page and re-running the page constructor.
All Answers
i think what is happening is that the standard controller is called again when you redraw the page, thus overwriting the total that you calculated.
here is what i think is going on:
page works as you designed,
but rerender on a column is not hooked up (on our side) so the entire page is re-drawn
the entire page then causes the standard controller to fetch the opportunity record again, tossing your calculated value.
my theory has large holes in it, but somehow you need to prove that the opp lineitems list has not been re-fetched between the time you modified it , and the time you go to save it.
do something like this :
<apex:outputPanel id="ListPriceTable" > <apex:pageBlockTable value="{!Opportunity.OpportunityLineItems}" var="oli" cellpadding="4" > <apex:column headerValue="Name" > {!oli.PricebookEntry.Name} </apex:column> <apex:column headerValue="Option" > <apex:inputField value="{!oli.Protex_Option__c}"> <apex:actionSupport event="onchange" action="{!recalcProtex}" rerender="ListPriceTable" /> </apex:inputField> </apex:column> <apex:column headerValue="List Price" id="ListPrice" >{!oli.Actual_List_Price__c} </apex:column> </apex:pageBlockTable> </apex:pageBlock> </apex:outputPanel>
The idea is that the output panel is outside the table , so the entire table will be refreshed, instead of the page.
you cannot refresh just a single column of a table, i believe this is a limitation of HTML ( in IE if i recall)
So, you go for the DIV outside the table as your refresh point.
that avoids refreshing the entire page and re-running the page constructor.