I have an outputPanel containing javascript to change formatting conditionally based on variables in Apex. This is called onComplete from the save button for the page. The custom save function is in an actionFunction that rerenders jspanel. The intent of onComplete is to remove the formatting that highlights changed fields on the page in red when the page successfully saves, but to leave it if there was an error. The variables "hasError" and "errorString" are both set in Apex. The Apex has been thoroughly tested.
<apex:outputPanel id="jspanel">
{!errorString} {!counter}
<script>
function onControllerReturn(){
if(!{!hasError}){
var x = document.querySelectorAll(".has-changed");
var i;
for (i = 0; i < x.length; i++) {
x[i].classList.remove('has-changed');
}
console.log('Removed red borders');
}
console.log('Has Error Test?', {!hasError});
console.log('Error String Test', '{!errorString}');
}
</script>
</apex:outputPanel>
<apex:actionFunction name="doControllerSave" action="{!justSave}"
rerender="{!$Component.jspanel},...(other components)" />
<apex:commandButton onclick="doControllerSave();"
oncomplete="setTimeout(onControllerReturn,1000);" value="Save" styleClass="slds-button slds-button_brand"/>
And the Apex:
public void justSave(){
try
{
//saveEvents is true on success
hasError = !saveEvents();
if(hasError){
errorString = 'ERROR';
return;
}
update target;
upsert request;
upsert opportunity;
}
catch(DmlException dmlE)
{
ApexPages.addMessages(dmlE);
return;
}
return;
}
The Apex code, including saveEvents is confirmed to be working from debug logs. The problem is this: sometimes, the outputPanel with onControllerReturn code does not rerender with the new value of hasError before it is run. Othertimes it does. It almost always works the first time: make a change, click the button, correct result. However, if additional changes to the page are made changing the error condition (a field is blank or not), and the button is clicked again, it returns the previous result some of the time.
I based my code on this: http://blog.jeffdouglas.com/2011/01/17/passing-values-to-javascript-from-apex-controller-method/