2

I've written a Visualforce page and controller intended to override both the New and Edit buttons for the standard Case object.

I have an inputField for an Account lookup enclosing an actionSupport component. The action displaySessions() recomputes a list of objects of a custom Apex wrapper class that each have lookups to the same Account object, then rerenders a pageBlockSection on the New/Edit page of the properties of those objects.

The below code works perfectly fine when overriding a typical edit page. In testing, this usually looked like

cs53.salesforce.com/apex/editcase?id=5000j000001k27U

In practice when overriding, SF throws in some extra params, but the functionality works either way:

https://c.cs53.visual.force.com/apex/EditCase?retURL=%2F5000j000001k27U&scontrolCaching=1&_CONFIRMATIONTOKEN=VmpFPSxNakF4Tnkwd055MHhOVlF5TURvek16b3dPQzQ1TmpkYSxSNGp3Ymoxc05vbEFHbkxUVGxDV05ELE9EUTVNREpp&common.udd.actions.ActionsUtilORIG_URI=%2F5000j000001k27U%2Fe&sfdc.override=1&id=5000j000001k27U

However, when creating a case from scratch by clicking an overridden New button, the functionality does not work. The page loads the initial pageBlockTable (logic in controller code below omitted) but rerender does not occur. I included a debug statement in the displaySessions() code that that the vfp action= should call (see below code), and while the debug statement appears when the id param is passed in, it doesn't in the New Case scenario, where the id param is missing:

https://c.cs53.visual.force.com/apex/EditCase?retURL=%2F500%2Fo&RecordType=0121a000000QwQH&ent=Case&save_new=1&sfdc.override=1

Same behavior whether I use the inbuilt record type select UI or override/skip it. Adding &id=5000j000001k27U to the above and reloading causes expected behavior to return.

This all leads me to believe that not setting the controller extension constructor on load is preventing inputField actionSupport from firing, but at a loss for how to change this.

Any help much appreciated. Code snippets below:

VFP

<apex:inputField value="{!Case.AccountId}" required="true" rendered="{!ISBLANK($CurrentPage.parameters.fromAcc)}">
  <apex:actionSupport action="{!displaySessions}" event="onchange" rerender="session_block" >
  </apex:actionSupport>
</apex:inputField>

...

        <apex:pageBlockSection title="Session Association" columns="1" collapsible="true" id="session_block">   
            <apex:outputPanel rendered="{!IF(AND(OR(ISBLANK(sessions), sessions.size < 1), ISBLANK($CurrentPage.parameters.fromAcc), case.AccountId == null), true, false)}" style="display:block; width:100%; border: 1px solid #e0e3e5; padding:4px; margin-bottom:-10px;">
                No records to display.
            </apex:outputPanel> 
            <apex:outputPanel rendered="{!IF(AND(OR(ISBLANK(sessions), sessions.size < 1), ISBLANK($CurrentPage.parameters.fromAcc), case.AccountId != null), true, false)}" style="display:block; width:100%; border: 1px solid #e0e3e5; padding:4px; margin-bottom:-10px;" >
                No sessions for selected account. A new open session will be automatically created with case. 
            </apex:outputPanel>  
            <apex:outputText label="Currently Selected Session" value="{!Case.Session__r.Name}" rendered="{!IF(AND(NOT(ISBLANK(sessions)), sessions.size > 0, ISBLANK($CurrentPage.parameters.fromAcc), NOT(newSessionCreated = true)), true, false)}" />
            <apex:commandButton value="New Session" action="{!newSession}" style="margin-left:18%;" rerender="session_block" rendered="{!AND(ISBLANK($CurrentPage.parameters.fromAcc), NOT(newSessionCreated = true), AND(sessions != null, sessions.size > 0))}"/>
            <apex:pageBlockTable id="sessions" value="{!sessions}" var="s" rendered="{!IF(AND(NOT(ISBLANK(sessions)), sessions.size > 0, ISBLANK($CurrentPage.parameters.fromAcc), NOT(newSessionCreated = true)), true, false)}">
              <apex:column headerValue="Select" >
                 <apex:actionsupport event="onclick" rerender="">  
                    <input type="radio" name="selectRadio" value="Case.selectedSessionId"/>                    
                        <apex:param name="sessid" value="{!s.s.id}" assignTo="{!selectedSessionId}">
                    </apex:param>
                 </apex:actionsupport>
              </apex:column>
              <apex:column headerValue="Session">
                  <apex:outputLink value="{! '/' & s.s.id}">{!s.s.Name}</apex:outputLink>
              </apex:column>
              <apex:column width="90%" >
                <apex:pageblocktable value="{!s.cases}" var="c" width="100%" rendered="{!IF(s.cases.Size = 0, false, true)}" id="PleaseHideMe"> 
                  <apex:column headerValue="Case" width="6%">
                    <apex:outputLink value="{!URLFOR($Action.Case.View, c.id)}">{!c.CaseNumber}</apex:outputLink>
                  </apex:column>
                  <apex:column headerValue="Subject" value="{!c.Subject}" width="15%"/>
                  <apex:column headerValue="Category" value="{!c.Category__c}" width="12%"/>
                  <apex:column headerValue="Date Opened" value="{!c.CreatedDate}" width="10%"/>
                  <apex:column headerValue="Status" value="{!c.Status}" width="11%"/>
                  <apex:column headerValue="Owner" value="{!c.Owner.Name}" width="15%"/>
                </apex:pageblocktable>
              </apex:column> 
            </apex:pageBlockTable>  
            <apex:outputText label="Session" value="{!singleSession.Name}" rendered="{!$CurrentPage.parameters.fromAcc = 'true'}" />
            <apex:outputText label="Session" value="{!singleSession.Name}" rendered="{!newSessionCreated = true}" />
            <apex:commandButton value="Undo" action="{!undoNewSession}" style="margin-top:5px;margin-bottom:-5px; margin-left:18%;" rendered="{!newSessionCreated = true}" rerender="session_block" />
        </apex:pageBlockSection> 

Controller

public Case cas {get; set;}

public EditCaseController(ApexPages.StandardController controller) {

    ... 

    // set Case to existing case if in Edit mode, create new case otherwise 
    cId = ApexPages.currentPage().getParameters().get('id'); 
    if(cId != null  && cId != '') {
       cas = (Case) stdCtrl.getRecord(); 
    } else {
       cas = new Case(); 
    }

    ...

}

public void displaySessions() {
    System.Debug('DISPLAYSESSIONS RAN');

    newAccId = cas.AccountId;
    if (newAccId != null) {
        acc = [Select Id from Account where Id =: newAccId limit 1];   
        sessionObjs = [Select Id, Name, Account__c, Start_Time__c, End_Time__c 
                       from Session__c where Account__c =:acc.Id order by Name Desc];                            
        createSessionWrapper(sessionObjs);          
    } 
}

Correct behavior when id in URL: Correct behavior

Incorrect behavior when id is missing from URL: Incorrect behavior

EDIT Code I tried so far using apex:actionFunction in place of Support:

<apex:inputField value="{!Case.AccountId}" rendered="{!ISBLANK($CurrentPage.parameters.fromAcc)}" onchange="rerenderSessions">
    <apex:actionFunction action="{!displaySessions}" name="rerenderSessions" rerender="session_block" >
    </apex:actionFunction>
</apex:inputField>`

EDIT 2 Got it to work by grabbing the record again in displaySessions() while using an actionRegion (needs to use this hierarchy to display correctly) and most importantly, by calling getRecord in the controller action method:

VFP

<apex:pageBlockSectionItem id="AccountSelectionItem">
    <apex:outputLabel value="Account Name" for="accountfield" />
    <apex:actionRegion >
        <apex:inputField value="{!Case.AccountId}" label="Account" required="true" id="accountfield">              
            <apex:actionSupport event="onchange" action="{!displaySessions}" rerender="session_block" />              
        </apex:inputField>
    </apex:actionRegion>  
</apex:pageBlockSectionItem>

Controller

public void displaySessions() {
    System.Debug('DISPLAYSESSIONS RAN');
    System.Debug('NEWACCID: ' + newAccId); 

    cas = (Case) stdCtrl.getRecord(); 
    newAccId = cas.AccountId;
    System.Debug('CAS.ACCID: ' + cas.AccountID); 
    if (newAccId != null) {
        acc = [Select Id from Account where Id =: newAccId limit 1];   
        sessionObjs = [Select Id, Name, Account__c, Start_Time__c, End_Time__c 
                       from Session__c where Account__c =:acc.Id order by Name Desc];                            
        createSessionWrapper(sessionObjs);          
    } 
}
1

Since you are using actionSupport with input field as required, thats why if inputfield is blank then actionSupport will not work properly.

Just to tell you, properties values are assigned first then controller methods are getting called.

Better to perform same operation using actionFunction instead of actionSupport, it will work.

Refer my answer: ReRendered form with wrong data on inputFields dependent picklist

  • Tried implementing this but it's not working (maybe I've implemented incorrectly). This code also breaks displaySessions() when the id param is present. Code above in edit – Allen Johnson Jul 12 '17 at 23:26
0

Time to start commenting out your page and adding stuff back in to see where it breaks. I also see that you do not seem to have a pagemessages component on your page. You could be throwing an error and not displaying it.

Below is conceptually a barebones version of your page to show that without all the noise it works as expected:

Class

public class myExampleController{

    public case cas {get;set;}

    public string displayMe {get;set;}
    public myExampleController(ApexPages.standardController con){

        String cId = ApexPages.currentPage().getParameters().get('id'); 
        if(cId != null  && cId != '') {
           cas = (Case) con.getRecord(); 
        } else {
           cas = new Case(); 
        }

    }

    public void displaySessions() {
        displayMe = 'I am a string';
    }


}

Page

<apex:page standardController="Case" extensions="myExampleController">
    <apex:form>
        <apex:inputField value="{!Case.AccountId}" required="true" rendered="{!ISBLANK($CurrentPage.parameters.fromAcc)}">
            <apex:actionSupport action="{!displaySessions}" event="onchange" rerender="session_block" />

        </apex:inputField>
    </apex:form>

    <apex:pageBlock>
    <apex:pageBlockSection title="Session Association" columns="1" collapsible="true" id="session_block">   
         {!displayMe}
    </apex:pageBlockSection>
    </apex:pageBlock>
</apex:page>

Url to access (without Id)

https://[pod].salesforce.com/apex/myExamplePage

It also works when placed as a new case override page

On Load

enter image description here

After picking account

enter image description here

I know it is not a direct answer but the adding of the pagemessages component would be the first item and see if a message is displayed. The next step is to comment out everything down to bare bones and add back in until it breaks. Then you will know what did it and can resolve it.

Sometimes this is quicker than banging your head trying to work through the rabbit hole of debug logs and potential typos.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.