3

I am looking into a strange Visualforce effect. Now the problem can be simplified using the following example.

MyController:

public class MyController {        
    public String firstName {get; set;}
    
    public PageReference doAction() {
        return null;
    }
}

The Visualforce MyPage:

<apex:page controller="MyController">
    <apex:form id="myForm">
        <apex:outputPanel>
            <apex:inputText value="{!firstName}"/>
            <apex:actionSupport event="onchange" action="{!doAction}" rerender="myForm" />
        </apex:outputPanel>
        
        <table class="list" border="0" cellpadding="0" cellspacing="0">
            <thead>
                <tr>
                    <th>Benefit</th>
                </tr>
            </thead>
            <tbody>
                <c:MyComponent/>
            </tbody>
        </table>
    </apex:form>
</apex:page>

MyComponent:

<apex:component>
    <tr>
        <td>
            <div>Test name</div>
        </td>
    </tr>
</apex:component>

When a value is changed in the inputText, the form gets re-rendered but the content in MyComponent disappeared. This seems to be a very old issue. A similar problem can be found here but there is no answer: https://developer.salesforce.com/forums/?id=906F0000000962mIAA

I am refactoring a long Visualforce page that has the same component's <tr> content which is large itself. Since the <tr> content is duplicated in many places, it should ideally be wrapped in a component. I'm a bit stuck on the issue as otherwise I have to repeat the same <tr> content everywhere in the page. Am I missing something fairly straight-forward?

2
  • That's interesting. I have no idea how to fix this aside from just moving to Lightning or otherwise using client-side rendering. I'll see if I can't get someone to look in to this at Salesforce. – sfdcfox Dec 13 '20 at 18:46
  • Thanks for looking into the issue @sfdcfox. – Chun Dec 14 '20 at 10:42
3

I'm not sure about the "why" your problem happens, but I would try solving it by narrowing the scope of the rerender, e.g. try to rerender a panel around your <table> element:

<apex:page controller="MyController">
    <apex:form id="myForm">
        <apex:outputPanel>
            <apex:inputText value="{!firstName}"/>
            <apex:actionSupport event="onchange" action="{!doAction}" rerender="panelToRerender" />
        </apex:outputPanel>
        
        <apex:outputPanel id="panelToRerender" layout="block">
            <table class="list" border="0" cellpadding="0" cellspacing="0">
                <thead>
                    <tr>
                        <th>Benefit</th>
                    </tr>
                </thead>
                <tbody>
                    <c:MyComponent/>
                </tbody>
            </table>
        </apex:outputPanel>
    </apex:form>
</apex:page>

The generic idea is: wrap the block you want to rerender with a panel and rerender it instead. It helped me a couple of times.

1
  • Thanks a lot Francesco. This does fix the problem. It seems that re-rendering the wrapping component (panel or form) caused it. – Chun Dec 15 '20 at 10:51

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.