function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
BrianDunzweilerBrianDunzweiler 

<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