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 anaction
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);
}
}
Best Answer
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
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
Alternatively, if you get rid of the re-render altogether, the page will do a full refresh which would recall your constructor.