+ Start a Discussion
AdrianCCAdrianCC 

Joys of VF: rerender multipicklist and viewstate stuff

Hi guys,

 

Got a small custom VF page for modifying account data. It's actually a big apex:form with a pageblock inside. Fields are grouped using apex:pageBlockSections. 

 

I've got 2 problems with it.

 

1. in one section I have a multiselect picklist fields with an actionsupport that "should" rerender another blocksection with some attachments.

Selected_Services__c is the picklist. 

<apex:page standardController="Account" extensions="AccountStatusChangeController" action="{!checkAttachments}" >	

	<apex:form id="theform" >
			  		
	        <apex:pageMessages />
	        
	        <apex:pageBlock title="Account {!account.Name}" >
	        	...
	        	<apex:pageBlockSection id="w9" columns="2" title="More Information" rendered="{!account.Status__c<>'LIVE'}" >
	        		...
	        		<apex:inputField value="{!account.Selected_Services__c}" required="true" label="Selected Services" >
	                	<apex:actionSupport event="onchange" reRender="attachments" immediate="true" /><!--  action="{!saveAccountModifications}"   -->
	                </apex:inputField>
	            </apex:pageBlockSection>
            
            <apex:pageBlockSection title="Attachments" columns="1" id="attachments" rendered="{!account.Status__c<>'LIVE'}" >
            	<apex:outputPanel rendered="{!account.Selected_Services__c<>null}" style="color:red;font-weight:bold" >
            		<br/>Please upload the following files: <br/>
            	</apex:outputPanel>
            	
            	<apex:outputPanel rendered="{!OR(CONTAINS(account.Selected_Services__c,'Programmatic Buying'),CONTAINS(account.Selected_Services__c,'Programmatic Selling'),CONTAINS(account.Selected_Services__c,'Ad Serving'),CONTAINS(account.Selected_Services__c,'ATM Buy'),CONTAINS(account.Selected_Services__c,'ATM Sell'),CONTAINS(account.Selected_Services__c,'ATM Buy/Sell'),CONTAINS(account.Selected_Services__c,'RTB'))}" >
           			<apex:outputText value=" - Self-service Contract" />
           			<br/>&nbsp;&nbsp;&nbsp;
           			<apex:commandLink value="Attach Self-service Contract" action="{!uploadServiceContract}" style="color:{!IF(serviceAttached='true','green','red')};font-weight:bold" />
           		</apex:outputPanel>
           		...
           	</apex:pageBlockSection>
           	
           	<apex:pageBlockButtons id="buttons" location="bottom" rendered="true" ><!-- shown all the time on the page -->
	            <apex:commandButton value="Submit Account For Approval" action="{!submit}" rerender="theform" /> 
	            <apex:commandButton value="Cancel" action="{!cancel}" />
            </apex:pageBlockButtons>
			            
        </apex:pageBlock>
        
         
    </apex:form> 
    
    
</apex:page>		

 

2nd problem is with some links that I have in the page. There are a New Contact apex:commandlink and also 3 links for uploading new attachments. These have actions with PageRefences that load other pages. On leaving the main form I save the modifications that the user has done to the form(most of the fields are required so I use immediate="true"). I've put a System.debug before the update account line and all the fields that have been modificated don't have the correct values. 

Let say BillingStreet is blank. User comes on the page and inputs it, then clicks the link to create a new Contact. Before returning the NewContact page the method saves the account, but!! Billing Street is still blank!! WTH?!

<apex:page standardController="Account" extensions="AccountStatusChangeController" action="{!checkAttachments}" >	

	<apex:form id="theform" >
			  		
	        <apex:pageMessages />
	        
	        <apex:pageBlock title="Account {!account.Name}" >
	        	
	        	<apex:pageBlockSection id="address" columns="2" title="Address" rendered="{!account.Status__c<>'LIVE'}" >
              		...
              		<apex:inputField value="{!account.BillingStreet}" required="true" />
              	</apex:pageBlockSection>	
\
            <apex:pageBlockSection id="w9" columns="2" title="More Information" rendered="{!account.Status__c<>'LIVE'}" >
                <apex:pageblocksectionitem >
                	<apex:outputLabel value="Finance/Billing Contact" for="FinanceContactName"  />
	                <apex:outputPanel style="text-align:center" >
	                	<apex:inputText id="FinanceContactName" value="{!financeContactName}" label="Finance/Billing Contact" styleClass="" />
	                	<apex:inputHidden value="{!financeContactId}" id="hiddenFinanceContactId" />
	                	<a title="Search" onclick="window.open('/apex/CustomContactLookup?name={!$Component.FinanceContactName}&cid={!$Component.hiddenFinanceContactId}&id={!accountId}','Search','width=500,height=400')" >
							<img class="lookupIcon" onmouseover="this.className='lookupIconOn';this.className='lookupIconOn';this.style.cursor='pointer';" onmouseout="this.className='lookupIcon';this.className='lookupIcon';" onfocus="this.className='lookupIconOn';" onblur="this.className='lookupIcon';" alt="Search" src="/s.gif" />
						</a>
						<apex:commandLink value="New" action="{!createNewFinanceContact}" />
	                </apex:outputPanel>
                </apex:pageblocksectionitem>

 

public void saveAccountModifications() {
    	try{
    		System.debug('before account has this value: ' + account);
    		account.Finance_Billing_Contact__c = financeContactId;
            update account;
            System.debug('account updated succesfully!');
            account = [SELECT Id, Name, Status__c, Requested_Account_Status__c, BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry, 
	        			Selected_Services__c, Final_Signed_Agreement__c, Finance_Billing_Contact__c, Credit_Application__c, First_User__c, Account_Director__c, Senior_Client_Services_Lead__c, 
	        			Management_Override__c, (SELECT Id, Name, Description FROM Attachments), Finance_Billing_Contact__r.LastName, Finance_Billing_Contact__r.FirstName, Currency_Selection__c 
	        			FROM Account WHERE Id =: accountId LIMIT 1];//(SELECT Id, IsNote, Title, Description FROM NotesAndAttachments)
	        System.debug('account has this value: ' + account);
        } catch(Exception e) {
        	System.debug('account update failed: ' + e.getMessage());
            ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR, 'Unable to update account '+e.getMessage()+e.getStackTraceString()));
        }
    }
 	
 	public PageReference createNewFinanceContact() {
 		saveAccountModifications();
 		return new PageReference('/apex/CustomContactCreate?accid=' + account.Id);	
 	}

 

 

I have this nagging feeling that I'm missing something simple :(. Hmmm, if anyone wants I'll add the full page and controller here.

 

Thank you,

Adrian

 

 

 

 

 

 

 

 

Alderete_SFDCAlderete_SFDC

I think your problem is the immediate="true".

 

(The effects of this are poorly documented, and I have a bug for it, but figuring out the full details is really complicated, so it's on my Backlog, and will be there for a while. Sadly.)

 

Nutshell is, the use case for immediate=true is a [Cancel] button. That is, a button that will take you somewhere without submitting the form data. The doc says stuff about bypassing validation, and so on, and it's not wrong, but the most important thing to understand is the use case. Is the action you're using immediate=true like a [Cancel] button? If the answer is no, you should probably not use immediate=true, and instead accomplish that logic some other way.

 

So, try removing the immediate=true, and see if the problems don't go away.