[SalesForce] SOLVED: Rerendering item in a parallel repeat tag

I'm refactoring a page (advanced clone tool with grnadchild records) to be more dynamic and extensible, but some of my rerendering refuses to work under the new DOM model. You can see in the page snippet below that there's an actionSupport nested inside the first repeat's pageBlockSectionItem. When a user ticks the box, I need to rerender the content of the other repeat (or better yet, a specific item of it) which will display an additional sectionItem that isn't supposed to be selectable unless user has checked the first box.

I've tried many permutations of that rerender attribute, but I just can't seem to find one that works since introducing that second repeat component. If I simply rerender $Component.relatedItems or $Component.optionals (as many pages have suggested), nothing seems to rerender at all. If I try to rerender the mainPageBlock, it throws out all user selections and results in an error because it lost the required field data… I've also tried wrapping the repeat in another tag, but this thoroughly breaks the appearance of all the pageBlockSectionItems…

Any suggestions are welcome.

<apex:page standardController="Plan__c" extensions="AdvancedCloningUtil" title="{!parentObjectLabel} Clone" deferLastCommandUntilReady="true" id="thePage">

    <apex:variable value="{!typesWithOptionalGrandchildren} " var="typesForOptional" />
    <apex:pageMessages showDetail="false" rendered="true" />

    <apex:form id="theForm">
        <c:LockScreen />
        <apex:pageBlock id="mainPageBlock" title="New {! parentObjectLabel} Details">

            <apex:pageBlockSection id="mainSection" columns="1" rendered="{!safeFields[parentObjectName]}" >
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="{!parentObjectLabel} Name" styleclass="lblNewData" />
                    <apex:inputField id="txtPlanName" required="true" styleClass="required" value="{! cloneRecord['Name']}" styleclass="tbxField" />
                </apex:pageBlockSectionItem>

                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Owner" styleclass="lblNewData"  />
                    <apex:inputfield id="txtPlanOwner" required="true" value="{! cloneRecord['OwnerId']}" styleclass="tbxField" />
                </apex:pageBlockSectionItem>

                <apex:repeat id="relatedItems" value="{!childRelations}" var="childObj" >

                    <apex:pageBlockSectionItem id="item" >
                        <apex:outputLabel value="{! $ObjectType[childObj].LabelPlural}" styleclass="lblRelated" />
                        <apex:panelGrid columns="2">
                            <apex:actionRegion id="region" >

                                <apex:inputCheckbox id="chkCloneRelated" selected="false" value="{!selectedRelationships[childObj]}" styleclass="chkRelated" >
                                    <apex:actionSupport id="relatedItemsChanger" event="onchange"
                                        reRender="{!$Component.relatedItems.optionals}" />
                                </apex:inputCheckbox>

                            </apex:actionRegion>
                            <apex:outputText id="msgOutput" value="{! msgsByObj[childObj] }" escape="false" />
                        </apex:panelGrid>
                    </apex:pageBlockSectionItem>


                    <apex:repeat id="optionals" value="{!optionalGrandchildren}" var="gcName" >
                        <apex:pageBlockSectionItem id="subitem" rendered="{!childObj == optionalGrandchildren[gcName]}"
                            helpText="{!$ObjectType[gcName].LabelPlural} may be optionally included only when the {!$ObjectType[childObj].LabelPlural} are also included."
                        >
                            <apex:outputLabel value="{!$ObjectType[gcName].LabelPlural}" styleclass="lblRelated" />
                            <apex:panelGrid id="subgrid" columns="2">
                                <apex:inputCheckbox id="chkCloneRelatedSub" selected="false" value="{!selectedRelationships[gcName]}" styleclass="chkRelated" />
                                <apex:outputText id="msgOutput" value="{! msgsByObj[gcName] }" escape="false" />
                            </apex:panelGrid>
                        </apex:pageBlockSectionItem>
                    </apex:repeat>
                </apex:repeat>

            </apex:pageBlockSection>

            <apex:pageBlockButtons location="bottom">
                <apex:commandButton value="Clone" action="{! cloneAction }" status="lockScreen" rendered="{!safeFields[parentObjectName]}" />
                <apex:commandButton value="Cancel" action="{! cancel }" />
            </apex:pageBlockButtons>

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

</apex:page>

Here's a screenshot to illustrate a little better: Plan Exercise Findings should become enabled once it's parent (Plan Exercies) gets selected
Plan Exercise Findings should become enabled

EDIT: solution found
rerender attribute needs to read as {!$Component.optionals.subitem.subgrid}, this is due to the fact that you can't call rerender directly on an apex:pageBlockSectionItem, so you just need to specify a descendant.

Best Answer

Have you looked at blogpost from Bob on this topic

http://bobbuzzard.blogspot.com/2011/02/visualforce-re-rendering-woes.html

The issue can be you need to have atleast component being rendered and it can't be initially hidden .

It needs to generate the output .So i would modify your code with outputPanels placed as below

<apex:page standardController="Plan__c" extensions="AdvancedCloningUtil" title="{!parentObjectLabel} Clone" deferLastCommandUntilReady="true" id="thePage">

<apex:variable value="{!typesWithOptionalGrandchildren} " var="typesForOptional" />
<apex:pageMessages showDetail="false" rendered="true" />

<apex:form id="theForm">
    <c:LockScreen />
    <apex:pageBlock id="mainPageBlock" title="New {! parentObjectLabel} Details">
        <apex:outputPanel id="thePanel">
        <apex:pageBlockSection id="mainSection" columns="1" rendered="{!safeFields[parentObjectName]}" >
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="{!parentObjectLabel} Name" styleclass="lblNewData" />
                <apex:inputField id="txtPlanName" required="true" styleClass="required" value="{! cloneRecord['Name']}" styleclass="tbxField" />
            </apex:pageBlockSectionItem>

            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Owner" styleclass="lblNewData"  />
                <apex:inputfield id="txtPlanOwner" required="true" value="{! cloneRecord['OwnerId']}" styleclass="tbxField" />
            </apex:pageBlockSectionItem>

            <apex:repeat id="relatedItems" value="{!childRelations}" var="childObj" >

                <apex:pageBlockSectionItem id="item" >
                    <apex:outputLabel value="{! $ObjectType[childObj].LabelPlural}" styleclass="lblRelated" />
                    <apex:panelGrid columns="2">
                        <apex:actionRegion id="region" >

                            <apex:inputCheckbox id="chkCloneRelated" selected="false" value="{!selectedRelationships[childObj]}" styleclass="chkRelated" >
                                <apex:actionSupport id="relatedItemsChanger" event="onchange"
                                    reRender="{!$Component.relatedItems.optionals}" />
                            </apex:inputCheckbox>

                        </apex:actionRegion>
                        <apex:outputText id="msgOutput" value="{! msgsByObj[childObj] }" escape="false" />
                    </apex:panelGrid>
                </apex:pageBlockSectionItem>


                <apex:repeat id="optionals" value="{!optionalGrandchildren}" var="gcName" >
                 <apex:outputPanel id="thePanel2">
                    <apex:pageBlockSectionItem id="subitem" rendered="{!childObj == optionalGrandchildren[gcName]}"
                        helpText="{!$ObjectType[gcName].LabelPlural} may be optionally included only when the {!$ObjectType[childObj].LabelPlural} are also included."
                    >
                        <apex:outputLabel value="{!$ObjectType[gcName].LabelPlural}" styleclass="lblRelated" />
                        <apex:panelGrid id="subgrid" columns="2">
                            <apex:inputCheckbox id="chkCloneRelatedSub" selected="false" value="{!selectedRelationships[gcName]}" styleclass="chkRelated" />
                            <apex:outputText id="msgOutput" value="{! msgsByObj[gcName] }" escape="false" />
                        </apex:panelGrid>
                    </apex:pageBlockSectionItem>
                  </apex:outputPanel><!--The Panel ends here>
                </apex:repeat>
            </apex:repeat>

        </apex:pageBlockSection>
       </apex:outputPanel>

        <apex:pageBlockButtons location="bottom">
            <apex:commandButton value="Clone" action="{! cloneAction }" status="lockScreen" rendered="{!safeFields[parentObjectName]}" />
            <apex:commandButton value="Cancel" action="{! cancel }" />
        </apex:pageBlockButtons>

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

Also to add apex:outputPanel> can be made as Div or Span using layout="block" or layout="inline" .Hence please use whatever works .Layout="block" should work for you .

Related Topic