3

On my visualforce page I have a pageblocksection that starts off hidden, this pageblock is shown when the user selects a value from a picklist.

This feature works, but breaks the 'showOnEdit' function on my output fields. The save button wont show up when inline editing.

But if I don't have the pageblocksection dynamically rendered or if I refresh the whole page after selecting the picklist it works.

[edited with more code below] The problem area being in the 'List Details Section', where using the inlineEditSupport doesn't make the saveDetail button appear.

The picklist which determins the values within this section is the last selectList in the 'List Filter Section' with value="{!strCurrListId}"

<apex:page standardController="Search_List__c" extensions="SearchListController" sidebar="true" >
<apex:form >
    <apex:outputPanel id="MainPanel">
        <apex:pageBlock id="MainBlock" title="Search List" >

            <script type="text/javascript" src="/soap/ajax/23.0/connection.js">
            </script>
            <script type="text/javascript" src="/soap/ajax/23.0/apex.js">
            </script>

            <apex:actionFunction action="{!doRefreshAllPageData}" name="actSetUpDetails" reRender="MainPanel" status="RefreshData"/>

            <!-- List Filter Section -->
            <apex:actionFunction action="{!doFilterSearchList}" name="actFilterList" reRender="blkListFilter" status="FilterListStatus"/>

            <apex:pageBlockSection id="blkListFilter" title="List Filter" columns="2" collapsible="false" >
                <apex:selectList value="{!strCurrChannel}" onchange="actFilterList()" size="1" label="Channel: ">
                    <apex:selectOptions value="{!selOptChannel}" />
                </apex:selectList>
                [More selectLists for filtering list below]
                <apex:selectList value="{!strCurrListId}" size="1" label="Lists: ">
                    <apex:selectOptions value="{!selOptLists}" />
                    <apex:actionSupport event="onchange" oncomplete="actSetUpDetails()" reRender="none" status="RefreshData"/>
                </apex:selectList>
                <apex:actionStatus id="FilterListStatus">
                    <apex:facet name="start">
                        <img src="/img/loading.gif" /> Filtering List, please wait...
                    </apex:facet>
                </apex:actionStatus>
            </apex:pageBlockSection>

            <!-- List Details Section -->
            <apex:actionFunction action="{!doSaveDetails}" name="actSaveDetails" oncomplete="actSetUpDetails()" status="SaveListStatus"/>

            <apex:outputPanel id="PanelDetails">
                <apex:pageBlockSection id="blkDetail" title="{!GetCurrentList.name} Detail:" columns="2" collapsible="false" rendered="{!strCurrListId != null}" >
                    <apex:outputField value="{!GetCurrentList.name}">
                        <apex:inlineEditSupport event="ondblclick" showOnEdit="saveDetails" hideOnEdit="cmdApplyToJob, cmdAddCandidate , cmdDelCandidate" />
                    </apex:outputField>
                    [Some more output fields in the same format as above]
                </apex:pageBlockSection>
                <div align="center">
                    <apex:commandButton id="saveDetails" value="Save Details" style="display:none" onclick="actSaveDetails()" reRender="none"/>      
                </div>
            </apex:outputPanel> 

        </apex:pageBlock>
    </apex:outputPanel>
</apex:form>

  • This question is similar, but I would like to be able to do this without refreshing the page and was wondering if anyone has anymore information on this. – Will.T Dec 9 '14 at 17:17
  • Could you add a bit more of your code - where is the picklist that toggles the pageblocksection render? – Force Hero Dec 9 '14 at 21:15
  • I have added the code which updates the values being shown in the detail section (in list filter section) and also the actionFunction which reloads the data then reRenders the MainPanel (name="actSetUpDetails"). – Will.T Dec 10 '14 at 9:29
  • I'll setup a test page when I get home from work and try to help you out :) – Force Hero Dec 10 '14 at 11:47
1

Well this looks like a possible bug with VF to me - or maybe its expected behaviour. But it seems like the fact the button doesn't exist in the DOM when the page loads means the apex:inlineEditSupport showOnEdit function doesn't register it - maybe it tries to cache it when the page first loads... I'm not sure.

The only solution I could come up with is instead of using the rendered attribute on the pageBlockSection use Javascript to show/hide the pageBlockSection. You should bear in mind this means any properties referenced in the controller will run even if the pageBlockSection won't be shown whereas using the rendered attribute is server side and therefore properties won't run.

Visualforce code:

<apex:page controller="SearchListController" sidebar="true" >

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
    </script>

    <script>
        var $j = jQuery.noConflict();

        $j( document ).ready(function() {
            togglePgBlkSectionVis();
        });

        function escId(myid) {
            return myid.replace(/(:|\.)/g,'\\\\$1');
        }

        function togglePgBlkSectionVis() {
            var show = {!strCurrListId != null};

            if (show) {
                $j('#' + pgBlkSecId).show();
            }
            else {
                $j('#' + pgBlkSecId).hide();
            }
        }
    </script>

    <apex:form >
        <apex:outputPanel id="MainPanel">
            <apex:pageBlock id="MainBlock" title="Search List" >

                <script type="text/javascript" src="/soap/ajax/23.0/connection.js">
                </script>
                <script type="text/javascript" src="/soap/ajax/23.0/apex.js">
                </script>

                <apex:actionFunction action="{!doRefreshAllPageData}" name="actSetUpDetails" reRender="MainPanel" status="RefreshData"/>

                <!-- List Filter Section -->
                <apex:actionFunction action="{!doFilterSearchList}" name="actFilterList" reRender="blkListFilter" status="FilterListStatus"/>

                <apex:pageBlockSection id="blkListFilter" title="List Filter" columns="2" collapsible="false" >
                    <apex:selectList value="{!strCurrChannel}" onchange="actFilterList()" size="1" label="Channel: ">
                        <apex:selectOptions value="{!selOptChannel}" />
                    </apex:selectList>
                    <apex:selectList value="{!strCurrListId}" size="1" label="Lists: ">
                        <apex:selectOptions value="{!selOptLists}" />
                        <apex:actionSupport event="onchange" oncomplete="actSetUpDetails()" reRender="none" status="RefreshData"/>
                    </apex:selectList>
                    <apex:actionStatus id="FilterListStatus">
                        <apex:facet name="start">
                            <img src="/img/loading.gif" /> Filtering List, please wait...
                        </apex:facet>
                    </apex:actionStatus>
                </apex:pageBlockSection>

                <!-- List Details Section -->
                <apex:actionFunction action="{!doSaveDetails}" name="actSaveDetails" oncomplete="actSetUpDetails()" status="SaveListStatus"/>

                <apex:outputPanel id="PanelDetails">

                    <script>
                        var pgBlkSecId = escId('{!$Component.blkDetail}');
                    </script>

                    <apex:pageBlockSection id="blkDetail" title="{!Con.FirstName} Detail:" columns="2" collapsible="false" >
                        <apex:outputField value="{!Con.FirstName}">
                            <apex:inlineEditSupport event="ondblclick" showOnEdit="saveDetails" hideOnEdit="cmdApplyToJob, cmdAddCandidate , cmdDelCandidate" />
                        </apex:outputField>
                    </apex:pageBlockSection>
                    <div align="center">
                        <apex:commandButton id="saveDetails" value="Save Details" style="display:none" onclick="actSaveDetails()" reRender="none"/>      
                    </div>
                </apex:outputPanel> 

            </apex:pageBlock>
        </apex:outputPanel>
    </apex:form>
</apex:page>

My dummy apex class for completeness:

public class SearchListController {

    public List<SelectOption> selOptChannel {get; set;}
    public List<SelectOption> selOptLists {get; set;}

    public String strCurrChannel {get; set;}
    public String strCurrListId {get; set;}

    public Contact Con {get; set;}

    public SearchListController() {
        Con = new Contact();
        Con.FirstName = 'ForceHero';

        selOptChannel = new List<SelectOption>();
        selOptChannel.add(new SelectOption('first', 'first'));

        selOptLists = new List<SelectOption>();
        selOptLists.add(new SelectOption('first', 'first'));
        selOptLists.add(new SelectOption('second', 'second'));
    }

    public void doRefreshAllPageData() {

    }

    public void doFilterSearchList() {

    }

    public void doSaveDetails() {

    }

}

So the key points are:

  • Remove your rendered attribute in the pageBlockSection
  • Move the rendered logic into the document ready event in jQuery to show/hide the pageBlockSection instead

If you move the pageBlockSection ensure you move the

<script>
    var pgBlkSecId = escId('{!$Component.blkDetail}');
</script>

code with it to ensure the correct id generated by Salesforce is set.

  • So from what I understand, if i reRender the mainpanel which contains all the other panels, then it will reRender the child pageBlockSections as well even if they are hidden using the script, meaning the functions linked will also be called as well? – Will.T Dec 11 '14 at 9:27
  • If there's any property getters inside them yes they will run because as far as the Salesforce server is concerned they are going to be visible - we then make them non-visible on the client side. – Force Hero Dec 11 '14 at 9:33

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.