You need to sign in to do that
Don't have an account?
<apex:actionFunction> on same page as <apex:detail> not firing
I had the use case to override the "detail" action of a custom object to render/secure specific buttons. The page was composed of the following apex components, in addition to jQuery.
- apex:form
- apex:pageBlock
- apexPageBlockButtons
- apex:detail (relying on the object's default page layout)
- apex:actionFunction
- apex:outputField
One of the button's function was to make an AJAX call to update the status field and rerender the status (the act of submitting the entity). See code below.
<apex:page title="Consultant Request Form" showHeader="true" standardcontroller="Consultant_Request__c" extensions="ConsultantRequestDetail_Ext"> <apex:includeScript value="{!URLFOR($Resource.ConsultantTracker_UI, 'scripts/jquery-1.5.2.min.js')}"/> <script type="text/javascript"> var j$ = jQuery.noConflict(); j$(document).ready(function(){ j$('.JQEdit').click(function(){document.location='{!URLFOR($Action.Consultant_Request__c.Edit,Consultant_Request__c.Id)}';}); j$('.JQDelete').click(function(){ if (confirm('Are you sure you want to delete this record?')){ document.location='{!URLFOR($Action.Consultant_Request__c.Delete,Consultant_Request__c.Id)}'; } }); j$('.JQMapRequest').click(function(){ window.open('{!URLFOR($Page.Consultant_Map,Consultant_Request__c.Id,[id=Consultant_Request__c.Id,city=Consultant_Request__c.Airport_City_State__c])}',"RequestMap","menubar=no,toolbar=no,scrollbars=yes"); }); j$('.JQSubmit').click(function(){ if(confirm('Are you sure you want to submit this request to a scheduler?')){ tester(); } }); }); </script> <apex:form id="theForm"> <apex:pageBlock id="mainBlock"> <apex:pageBlockButtons > <apex:outputText rendered="{!CanEdit}"> <input type="button" value="Edit" id="editBtn" class="btn JQEdit"/> </apex:outputText> <apex:outputText rendered="{!CanDelete}"> <input type="button" value="Delete" id="deleteBtn" class="btn JQDelete"/> </apex:outputText> <apex:outputText rendered="{!CanMapRequest}"> <input type="button" value="Map Request" id="mapBtn" class="btn JQMapRequest"/> </apex:outputText> <input type="button" value="Generate PDF" id="pdfBtn" class="btn"/> <apex:outputText rendered="{!CanSubmit}"> <input type="button" value="Submit to Scheduler" id="submitBtn" class="btn JQSubmit"/> </apex:outputText> <input type="button" value="Send Request to Manager" id="managerBtn" class="btn JQSend"/> </apex:pageBlockButtons> <apex:outputField id="statusField" value="{!Consultant_Request__c.Status__c}" rendered="true"/> <apex:detail id="detailBlock" relatedList="true" title="true" subject="{!Consultant_Request__c.Id}" relatedListHover="false"/> </apex:pageBlock> <apex:outputField value="{!Consultant_Request__c.Status__c}" rendered="false"/> <apex:outputField value="{!Consultant_Request__c.Id}" rendered="false"/> <apex:outputField value="{!Consultant_Request__c.Airport_City_State__c}" rendered="false"/> <apex:actionFunction name="tester" action="{!updateStatus}" rerender="statusField" oncomplete="alert('hello');"/> </apex:form> </apex:page>
However, when clicking the "submit" button, the page would perform essentially a full page load on the AJAX callback, without throwing any errors. I tried taking out the apex:detail component and then the actionFunction call worked. Not giving up, I tried a few more things. I stumbled on a solution: in the apex:detail component, set the relatedList attribute to false and then explicitly reference the desired related lists. These references must be done outside of the apex:form component. See working page below.
<apex:page title="Consultant Request Form" showHeader="true" standardcontroller="Consultant_Request__c" extensions="ConsultantRequestDetail_Ext"> <apex:includeScript value="{!URLFOR($Resource.ConsultantTracker_UI, 'scripts/jquery-1.5.2.min.js')}"/> <script type="text/javascript"> var j$ = jQuery.noConflict(); j$(document).ready(function(){ j$('.JQEdit').click(function(){document.location='{!URLFOR($Action.Consultant_Request__c.Edit,Consultant_Request__c.Id)}';}); j$('.JQDelete').click(function(){ if (confirm('Are you sure you want to delete this record?')){ document.location='{!URLFOR($Action.Consultant_Request__c.Delete,Consultant_Request__c.Id)}'; } }); j$('.JQMapRequest').click(function(){ window.open('{!URLFOR($Page.Consultant_Map,Consultant_Request__c.Id,[id=Consultant_Request__c.Id,city=Consultant_Request__c.Airport_City_State__c])}',"RequestMap","menubar=no,toolbar=no,scrollbars=yes"); }); j$('.JQSubmit').click(function(){ if(confirm('Are you sure you want to submit this request to a scheduler?')){ tester(); } }); }); </script> <apex:form id="theForm"> <apex:pageBlock id="mainBlock"> <apex:pageBlockButtons > <apex:outputText rendered="{!CanEdit}"> <input type="button" value="Edit" id="editBtn" class="btn JQEdit"/> </apex:outputText> <apex:outputText rendered="{!CanDelete}"> <input type="button" value="Delete" id="deleteBtn" class="btn JQDelete"/> </apex:outputText> <apex:outputText rendered="{!CanMapRequest}"> <input type="button" value="Map Request" id="mapBtn" class="btn JQMapRequest"/> </apex:outputText> <input type="button" value="Generate PDF" id="pdfBtn" class="btn"/> <apex:outputText rendered="{!CanSubmit}"> <input type="button" value="Submit to Scheduler" id="submitBtn" class="btn JQSubmit"/> </apex:outputText> <input type="button" value="Send Request to Manager" id="managerBtn" class="btn JQSend"/> </apex:pageBlockButtons> <apex:outputField id="statusField" value="{!Consultant_Request__c.Status__c}" rendered="true"/> <apex:detail id="detailBlock" relatedList="false" title="true" subject="{!Consultant_Request__c.Id}" relatedListHover="false"/> </apex:pageBlock> <apex:outputField value="{!Consultant_Request__c.Status__c}" rendered="false"/> <apex:outputField value="{!Consultant_Request__c.Id}" rendered="false"/> <apex:outputField value="{!Consultant_Request__c.Airport_City_State__c}" rendered="false"/> <apex:actionFunction name="tester" action="{!updateStatus}" rerender="statusField" oncomplete="alert('hello');"/> </apex:form> <!-- Had to resort to explicitly listing the related lists as they prevented the actionFunction from firing properly--> <apex:relatedList list="Consultant_Assignments__r" /> </apex:page>
Hope this helps someone in the future.
-Brian