1

Not sure what is happening here. I am unable to show the spinner status or reRender the page with updated data. I did see this information about reRendering with conditionals but I am reRendering my entire form and it is still not working. The spinner only works if I put the status on the actual button, but I have never had to build an actionFunction like that before.

Unsuccessful Solutions I have tried:

  • Refreshing page via PageReference on the testErrorHandling() method
  • javascript remoting
  • button, apex:commandLink, apex:commandButton
  • putting the spinner status on the button rather then the actionFunction
  • combining an onClick and an action attribute to the button
  • returning data with the pullCredit() method
  • not returning data with the pullCredit() method
  • directly calling the pullCredit() mehtod from the vfp
  • put the whole VFP in the "stop" facet of the actionStatus

nothing seems to work which leads me to believe it is a rule about how I have written conditionals in my VFP. Can anyone see what is happening?

VFP:

<apex:page id="EquifaxCreditPullPage" showHeader="true" standardController="Lead" extensions="EquifaxCreditPullController">
    <head>
    <apex:stylesheet value="{!URLFOR($Resource.SLDS2018, 'styles/salesforce-lightning-design-system.css')}" />

    <style>
    .not-active {
          pointer-events: none;
          cursor: default;
          text-decoration: none;
          color: black;
     }
    </style>
    <script>
    function pullCredit() {
        var leadId = '{!Lead.Id}';
        var contactId = null;
        var creditReviewId = null;
        Visualforce.remoting.Manager.invokeAction(
            '{!$RemoteAction.EquifaxCreditPullController.pullCred}',
            leadId, contactId, creditReviewId,
            function(result, event){
                alert('complete!!' + result);
                console.log('result:: ' + result);
            }
        );
    };
    </script>
    </head>

<apex:form id="theForm">
    <apex:actionFunction name="pullCreditActionFunction" action="{!testErrorHandling}" onComplete="alert('completed on action function')" status="spinnerStatusCredit" reRender="theForm"/>
    <apex:pageMessages />

    <table class="slds-table slds-table--bordered slds-table--cell-buffer">
        <thead>
        <tr class="slds-text-title--caps">
            <th scope="col">
                <div class="slds-truncate" title="First Name">Name</div>
            </th>
            <th scope="col">
                <div class="slds-truncate" title="Status">Status</div>
            </th>
            <th scope="col">
                <div class="slds-truncate" title="Action">Action</div>
            </th>
        </tr>
        </thead>
        <tbody>
        <apex:repeat value="{!leadCCSMap}" var="contactOrLead">
            <tr>
                <th scope="row" data-label="Name">
                    <div class="slds-truncate" title="Name">{!contactOrLead.Name}</div>
                </th>
                <td data-label="Status">
                    <div class="slds-truncate" title="Status">{!IF(emptyCCS, 'Awaiting Pull Request', leadCCSMap[contactOrLead].Status__c)}</div>
                </td>
                <td data-label="Action" id="pullCreditButton">
                    <apex:commandButton onClick="pullCreditActionFunction()" value="Pull Credit" onComplete="alert('completed on button')"/>                        
                    <apex:actionStatus id="spinnerStatusCredit">
                       <apex:facet name="start">
                        <apex:outputPanel>
                          <apex:outputPanel layout="block"/>
                            <apex:outputPanel layout="block">
                            <img src="/img/loading24.gif" style="vertical-align:middle; horizontal-align:middle"/>
                            <span>Please wait...</span>
                          </apex:outputPanel>
                        </apex:outputPanel>
                      </apex:facet>
                   </apex:actionStatus>
                </td>
            </tr>
        </apex:repeat>
        </tbody>
    </table>
</apex:form>
</apex:page>

APEX:

global class EquifaxCreditPullController {

public List<Consumer_Credit_Summary__c> cc{get;set;}
public List<Contact> acctContact{get;set;}
public Map<Contact, Consumer_Credit_Summary__c> contactCCSMap {get;set;}
public Map<Lead, Consumer_Credit_Summary__c> leadCCSMap {get;set;}
public Boolean emptyCCS {get;set;}

public EquifaxCreditPullController(ApexPages.StandardController controller){
    //code that fills in data if it is available on page load 
}

@RemoteAction
global static string pullCred(String leadId, String contactId, String creditReviewId) {
    String status;
    ApexPages.Message msg;
    String jsonBody = '{"LeadId" : "' + leadId + '" }';
    ....webservice callout....
        JSONParser parser = JSON.createParser(res.getBody());
        while (parser.nextToken() != null) {
            if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && (parser.getText() == 'ResultStatus')) {
                parser.nextToken();
                status = parser.getText();
            }
        }
        if(status == 'Success'){
            system.debug('got into Success:: ' + status);
        }
        else if(status == 'CriticalError'){
            msg=new ApexPages.Message(ApexPages.Severity.ERROR, 'CriticalError');
            ApexPages.addMessage(msg);
        }
        else if(status == 'NotImplemented'){
            msg=new ApexPages.Message(ApexPages.Severity.ERROR, 'NotImplemented');
            ApexPages.addMessage(msg);
        }
        else {
            msg=new ApexPages.Message(ApexPages.Severity.ERROR, 'TBD');
            ApexPages.addMessage(msg);
        }
        return status;
    }
    catch (System.CalloutException z) {
        return null;
    }
}

public void testErrorHandling(){
    Id currentPageId = ApexPages.currentPage().getParameters().get('id');
    pullCred(currentPageId, null, null);
}
}
  • When you click the button do you see any JS errors in the chrome developer console? Do you see any logs pop up in the Apex developer console? Your page also doesn't seem to have an apex:pageMessages tag which could be hiding errors from you. – gNerb Jun 6 '18 at 15:23
  • Upon copy and pasting the code over I accidentally deleted the pageMessages. It is in there, I just updated the question. When I am in the console I do not see any errors. When I use JS remoting I am unable to get into the callback function which is another different issue, but for the sake of this question I am going to stick with actionFunction. I can see in the debug logs that status is being set. When I refresh the page, the table is updated with the returned callout information. So I know the callout is working and updating SF appropriately. – Olivia Jun 6 '18 at 15:37
  • 1
    Have you checked the while loop? I suspect that it will never end the loop because of parser.nextToken() is within the if condition. You are not incrementing the next token outside of the if condition. So please use the debug statement to make sure you are hitting the correct FIELD_NAME and then break out from the while loop – Prolay Chaudhury Jun 6 '18 at 15:41
  • Not sure if this matters that much but you should move your action status to be a direct child of the form, not within the TD element. It's theoretically possible that your TD never renders which means your status doesn't exist on the page so of course it can't be displayed when you click the button. It could also result in duplicate status components which could confuse the page. – gNerb Jun 6 '18 at 15:44
  • 1
    For my sanity, can you try again but remove those pesky on complete alerts. – gNerb Jun 6 '18 at 15:57
1

Based on discussion on comments there are 3 issues:

Issue 1

Your action status does not show because it is a child of the TD element. This poses two potential issues

  1. The TD element may not get rendered at all meaning your status will never appear on the page and thus cannot be used in an action function.
  2. The status component could get rendered multiple times confusing the page.

To fix this, simply make your status a child of the apex:form tag.

Issue 2

I believe there is a chance that the oncomplete calls in your action function and button are interfering with or possibly overriding the re-render call. Try removing those and see if the re-render begins to work

Issue 3

You need to make sure the list you are iterating over contains the updated data before the re-render is called. This can be accomplished by

  • directly modifying the record in the list
  • Removing the record and re-adding it to the list after updating it
  • requerying for the entire dataset once your method is completed

Alternatively, if you get rid of the re-render altogether, the page will do a full refresh which would recall your constructor.

  • Thank you for the clarifications! Super helpful. Per your last suggestion, if I get rid of the re-render altogether, the page does not do a full refresh. Could this be because I am calling it in the Lead standard page as an iFrame? – Olivia Jun 6 '18 at 18:13
  • I'd imagine in that situation, only the iframe would refresh – gNerb Jun 6 '18 at 18:56

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.