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
EMHDevEMHDev 

actionSupport rerender not working, also trigger for lookup?

I have a custom object which has lookup fields to Account and Opportunity.  If the Account is populated, instead of using the standard search popup (which shows all opportunities, not just those belonging to the account), I want to use an Opportunity picklist which is populated with the opportunities belonging to the account whenever the account is selected/changed.  I think actionSupport is the right thing to use for this, but I can't get it to work correctly when creating a new record. It works fine in edit mode, when the account is already populated, but when creating a new record, when the search button next to account is used to pick the account, the event is not triggered (first problem).  If I just click in the account field to trigger the OnClick event, it triggers (I can see this in the system log), but the rerender does not happen.  Can anyone explain this?  I'd prefer to invoke actionSupport without having to click in the Account field, but the rerender is the bit giving me the biggest headache.

 

The page code is as follows:

 

<apex:page standardController="Call_Meeting_Report__c" extensions="OpportunitySearchController" showHeader="true" sidebar="true">
<apex:form >
<apex:pageBlock title="Call/Meeting Report" mode="edit" id="thePageBlock">
<apex:pageMessages />
<apex:pageBlockButtons >
<apex:commandButton value="Save" action="{!save}"/>
<apex:commandButton value="Cancel" action="{!cancel}" immediate="true"/>
</apex:pageBlockButtons>
<apex:pageBlockSection columns="2">
<apex:inputField value="{!Call_Meeting_Report__c.Account__c}" >
<apex:actionSupport event="onChange" action="{!getOpportunities}" rerender="ChooseOpp" />
<apex:actionSupport event="onkeyup" action="{!getOpportunities}" rerender="ChooseOpp"/>
<apex:actionSupport event="onclick" action="{!getOpportunities}" rerender="ChooseOpp"/>
</apex:inputField>
<apex:pageBlockSectionItem >
<apex:outputPanel id="ChooseOpp">
<apex:outputLabel value="Choose Opportunity"/>
<apex:selectList value="{!Call_Meeting_Report__c.Opportunity__c}" id="opps" size="1">
<apex:selectOptions value="{!Opportunities}"/>
</apex:selectList>
</apex:outputPanel>
</apex:pageBlockSectionItem>
<apex:inputField value="{!Call_Meeting_Report__c.Type__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Purpose__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Primary_Contact__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Other_people_present__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Next_actions__c}"/>
<apex:inputField value="!Call_Meeting_Report__c.Date__c}"/>
<apex:inputField value="!Call_Meeting_Report__c.Other_people_present__c}"/>
<apex:inputField value="{!Call_Meeting_Report__c.Discussion__c}"/>
<apex:pageBlockSectionItem />
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>

 and the controller is:

 

public class OpportunitySearchController {

//add an instance variable for the standard controller
private ApexPages.StandardController controller {get; set;}
// the actual call/meeting report
private Call_Meeting_Report__c cmr {get; set;}
private Id a;

public List <selectOption> Opps;

// Initialise the controller
public OpportunitySearchController(ApexPages.StandardController controller) {

//initialise the standard controller
this.controller = controller;
cmr = (Call_Meeting_Report__c)controller.getRecord();
//this.a = (Account)controller.getRecord();

}

// the results from the search
public PageReference getOpportunities() {
Opps = new List<selectOption>();

a = cmr.Account__c;
system.debug('### Account is '+a);
// use some dynamic soql to find the related opportunities by name
try {
List <Opportunity> opplist = [Select o.Id, o.Name from Opportunity o Where AccountId = :a Order By o.Name];
for (Opportunity u:opplist) {
Opps.add(new selectOption(u.Id, u.Name));
system.debug('### option added -'+u.Name);
}
}
catch (Exception e) {
System.debug('### error '+e);
ApexPages.addMessages(e);
}
return null;

}


}

 

Debug log is showing that the code does get called, but the populated Opportunity pulldown does not appear on the page, which means the rerender isn't happening or I'm doing something else wrong.  Debug log:

 



18.0 DB,INFO;WORKFLOW,INFO;VALIDATION,INFO;CALLOUT,INFO;APEX_CODE,DEBUG;APEX_PROFILING,INFO
19:08:05.661|CODE_UNIT_STARTED|[EXTERNAL]VForcePage
19:08:05.662|USER_DEBUG|[27,9]|DEBUG|### Account is 001T000000Ga6kPIAR
19:08:05.662|SOQL_EXECUTE_BEGIN|[30,33]|Aggregations:0|Select o.Id, o.Name from Opportunity o Where AccountId = :a Order By o.Name
19:08:05.669|SOQL_EXECUTE_END|[30,33]|Rows:2|Duration:7
19:08:05.670|USER_DEBUG|[34,5]|DEBUG|### option added -Crazy Horses Ltd - Test 1
19:08:05.670|USER_DEBUG|[34,5]|DEBUG|### option added -Crazy Horses Ltd - Test 2
19:08:05.670|CODE_UNIT_FINISHED
19:08:05.672|VF_APEX_CALL|j_id36|{!getOpportunities}|PageReference: none
19:08:05.692|CODE_UNIT_STARTED|[EXTERNAL]VForcePage
19:08:05.692|CODE_UNIT_STARTED|[EXTERNAL]VForcePage
19:08:05.692|USER_DEBUG|[27,9]|DEBUG|### Account is 001T000000Ga6kPIAR
19:08:05.692|SOQL_EXECUTE_BEGIN|[30,33]|Aggregations:0|Select o.Id, o.Name from Opportunity o Where AccountId = :a Order By o.Name
19:08:05.702|SOQL_EXECUTE_END|[30,33]|Rows:2|Duration:10
19:08:05.702|USER_DEBUG|[34,5]|DEBUG|### option added -Crazy Horses Ltd - Test 1
19:08:05.703|USER_DEBUG|[34,5]|DEBUG|### option added -Crazy Horses Ltd - Test 2
19:08:05.703|CODE_UNIT_FINISHED
19:08:05.703|CODE_UNIT_FINISHED

 Any help would be greatly appreciated -

Erica

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

This first part is browser behaviour rather than VisualForce - an onChange event is fired by the element that the account name appears in when it is changed by a user. If it is changed through JavaScript (which is what happens when you use the lookup - JavaScript is called from the popup window to fill in the details in the main window), no event is fired.  The reason for this is that it is assumed that if you are controlling the population of the field through javascript, you can carry out any additional processing at that time.  Unfortunately, SalesForce JavaScript is in control of this and you can't hook into it to add additional functionality.

 

The second part is because you are using {!opportunities} to populate your SelectOptions - this equates to a getOpportunities method call, which always returns null.  Add a {get; set;} to your controller declaration of opps and set the value attribute of selectoptions to {!opps} and you will get the list that was built by your actionmethod.

 

All Answers

bob_buzzardbob_buzzard

This first part is browser behaviour rather than VisualForce - an onChange event is fired by the element that the account name appears in when it is changed by a user. If it is changed through JavaScript (which is what happens when you use the lookup - JavaScript is called from the popup window to fill in the details in the main window), no event is fired.  The reason for this is that it is assumed that if you are controlling the population of the field through javascript, you can carry out any additional processing at that time.  Unfortunately, SalesForce JavaScript is in control of this and you can't hook into it to add additional functionality.

 

The second part is because you are using {!opportunities} to populate your SelectOptions - this equates to a getOpportunities method call, which always returns null.  Add a {get; set;} to your controller declaration of opps and set the value attribute of selectoptions to {!opps} and you will get the list that was built by your actionmethod.

 

This was selected as the best answer
EMHDevEMHDev
That's it, brilliant.  Thanks so much.  It works like a dream now.
Developer129Developer129

Hi,

 

Can you please tell me how you managed to solve the first problem.

 

Thanx

EMHDevEMHDev

Hi,

 

I changed my approach and used an action on loading the page to call a method in the controller which determined where it had been called from and populated the defaults accordingly - so the first line of the page looked like this:

 

<apex:page standardController="Call_Meeting_Report__c" extensions="ReportSearchController" showHeader="true" sidebar="true" action="{!loadDefaults}">  

 

then I wrote a very complicated method in the controller which started like this:

 

Opps = new List<selectOption>();
	Conts = new List<selectOption>(); 
	String OppName, ContName;
	Boolean fromOpp, fromCont, fromAcc;
        
        a = cmr.Account__c;

        fromAcc = (a!=null);
        OppThere = cmr.Opportunity__c;
        fromOpp = (OppThere != null);
        ContThere = cmr.Primary_Contact__c;
        fromCont = (ContThere != null);

		try {
			if (fromAcc){  // populate Opportunity and Contact pulldowns
				popOpplist();
				popContlist();
			} else {
				if (fromOpp){

 - you get the picture.

 

Hope this helps -

Erica

 

lakslaks

Hi,

 

Does that mean that we cannot write an actionsupport against an inputfield that is a lookup and process something based on that.

 

Basically I want to populate some textboxes with the Address of the Account object which I am selecting via an Account lookup in my VF page.

 

I wrote an actionSupport against it but it doesn't seem to get invoked.

 

 

Regards,

Lakshmi.