Sunday, January 29, 2017

apex:input in visualforce components causes page to crash on rerender when referencing a wrapper class value (Updated with fix)

Too complicated to follow? Let me break it down...

1. I created a visualforce page
2. I created a component to contain some logic
3. I created a wrapper class to contain an instance of object and some related attributes, so that I could fetch and print a list of those objects in a dataTable/apex:repeat

Then, within the visualforce component:
4. I created a checkbox to rerender the page
5. Based on the selected value, it shows/hides the column containing the <apex:input> tag that references an integer attribute within the wrapper class

Behavior:
On checking/unchecking the checkbox, the presence of the <apex:input> tag referencing a wrapper class member causes the visualforce to crash

Workarounds:
1. Wrap <apex:inputCheckbox> within an <apex:ActionRegion> (kudos to Ana Esrich for finding this one... https://developer.salesforce.com/forums/ForumsMain?id=9060G000000I3jc )
2. Use apex:inputText instead of apex:input, or any other suitable alternative
3. Place the visualforce code directly in the visualforce page, instead of in a component



Here's some sample code:

Class


public class TestApexInput {
    
    public Class classWrapper {
        public Integer cwInt {get; set;}
        public Contact cwCont {get; set;}
        
        public classWrapper (Contact c) {
            cwCont = c;
            cwInt = 1;
        }
    }
    
    public TestApexInput () {
        
    }
    
    public List<classWrapper> listCW {
        get {
            if(listCW == null){
                listCW = new List<classWrapper>();
                
                for(Contact c: [Select Id, Name From Contact])
                    listCW.add(new ClassWrapper(c));
            }
            
            return listCW;
        } 
        set;
    }
    
    public Boolean chkbxAI {get {if(chkbxAI==null) chkbxAI = true; return chkBxAI; } set;}
    public Integer noncwInt {get; set;}

}

Sample Visualforce

<apex:page docType="html-5.0">
    <c:testapexcmp />

</apex:page>

Sample Component

<apex:component controller="TestApexInput">
        <apex:form id="testApexInputForm">
        <apex:inputcheckbox id="chkbxAI" value="{!chkbxAI}" >
            <apex:actionSupport reRender="testApexInputForm" id="actfunTAI" event="onclick"/>
        </apex:inputcheckbox>
   <table>
        <apex:repeat value="{!listCW}" var="cw" id="dtable">
            <tr>
           <td><apex:outputText value="{!cw.cwCont.Name}" /></td>
           <td><apex:outputText value="{!cw.cwCont.Id}" /></td>
           <td><apex:outputPanel rendered="{!chkbxAI}">
                <td><!--apex:input value="{!cw.cwInt}" type="number" id="apexInputInt"/--></td>
                <td><apex:input value="{!noncwInt}" type="number" id="apexInputnonCWInt"/></td>
                <td><apex:inputText value="{!cw.cwInt}" id="apexInputInt2"/></td>
           </apex:outputPanel></td>
            </tr>
    </apex:repeat>
    </table>
        Flag: {!chkbxAi}
    </apex:form>

</apex:component>

No comments:

Post a Comment