0

I encounter this weird problem in visualforce page wherein for every checkbox click, there is an extra table row added, whether I tick/untick it. The table row is supposed to display only if I tick the checkbox, and hide if I untick it.

There's nothing wrong with displaying the table row whenever I tick the checkbox. This feature works. The only problem is that every time I untick it, it adds another table row, instead of hiding the said table row.

I use two objects: the standard Account object and a custom object named CustomObj__c.

Controller: AccountController

public class AccountController {
    private ApexPages.StandardController controller {get;set;}
    public Boolean b1 {get;set;}
    public List<Account> accList {get;set;}
    public List<CustomObj__c> customList {get;set;}
    public List<MyWrapper> wrapCls {get;set;}

    public AccountController(ApexPages.StandardController con) {
        controller = con;
        b1 = true;       
        wrapCls = new List<MyWrapper>():
        customList = new List<CustomObj__c>();
    }

    public void clickAction() {
        customList.add(new CustomObj__c()); 
    }

    public class MyWrapper {
        public Account listA {get;set;}
        public Boolean IsSelected {get;set;}

        public MyWrapper(Boolean sel, Account a) {
            IsSelected = sel;
            listA = a;
        } 
    }
} 

Visualforce Page: AccountPage

<apex:page standardController="Account" extensions="AccountController">

    <style type="text/css">
        #blkToRender {
            display: none;
        } 
    </style>

    <script type="text/javascript">
        function selectAllCheckboxes(obj,receivedInputID) {
            var inputCheckbox = document.getElementsByTagName("input");
            for(var i=0; i<inputCheckbox.length; i++) {
                if(inputCheckbox[i].id.indexOf(receivedInputID)!=-1) {
                    inputCheckbox[i].checked = obj.checked;
                }
            }
        }
    </script>  

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

    <script type="text/javascript">
        var $ = jQuery.noConflict();

        $(document).ready(function() {
            $('[id$=chk]').onclick(function() {
                $('[id$=blkToRender]').css('display','block');
            });
        }); 

    </script>  

    <apex:pageBlock id="pb1" rendered="{!b1}">
        <apex:pageBlockTable value="{!wrapCls}" var="acc">
            <apex:column>
            <apex:facet name="header">
                <apex:inputCheckbox onclick="selectAllCheckboxes(this,'chk')"/>
            </apex:facet>   
            <apex:inputCheckbox value="{!acc.IsSelected}" id="chk">
                <apex:actionSupport event="onclick" reRender="blkToRender" action={!clickAction}/>
            </apex:inputCheckbox> 
            </apex:column> 
            <apex:column>
                <apex:inputField value="{!acc.listA.Type}"/>
            </apex:column>   

        </apex:pageBlockTable>    
    </apex:pageBlock>  

    <apex:pageBlockTable id="blkToRender" value="{!customList}" var="cl">
               <apex:column>
                   <apex:inputField value="{!cl.Type__c}"/>
               </apex:column>   
           </apex:pageBlockTable> 

    </apex:pageBlock>   

</apex:page>

Updated Controller:

public class AccountController {
    private ApexPages.StandardController controller {get;set;}
    public Account returnAcc {get;set;}
    public Boolean b1 {get;set;}
    public List<Account> accList {get;set;}
    public List<CustomObj__c> customList {get;set;}
    public List<MyWrapper> wrapCls {get;set;}

    public AccountController(ApexPages.StandardController con) {
        controller = con;
        b1 = true;       
        wrapCls = new List<MyWrapper>():
        customList = new List<CustomObj__c>();
        returnAcc = new Account();
    }

    public void accSearch() {
        List<Account> accounts = new List<Account>();
        List<MyWrapper> wraptemp = new List<MyWrapper>();

        accounts = [SELECT Id, Name, CustomObj__c, Type FROM Account WHERE CustomObj__c =: returnAcc.CustomObj__c];

        for(Account accloop : accounts) {
            wraptemp.add(new MyWrapper(false,accloop));
        }

        if(wraptemp != null) {
            wrapCls = wraptemp;
        }

    }  

    public void clickAction() {
        customList.add(new CustomObj__c()); 
    }

    public class MyWrapper {
        public Account listA {get;set;}
        public Boolean IsSelected {get;set;}

        public MyWrapper(Boolean sel, Account a) {
            IsSelected = sel;
            listA = a;
        } 
    }
} 

Updated VF Page:

<apex:page standardController="Account" extensions="AccountController">

    <script type="text/javascript">
        function selectAllCheckboxes(obj,receivedInputID) {
            var inputCheckbox = document.getElementsByTagName("input");
            for(var i=0; i<inputCheckbox.length; i++) {
                if(inputCheckbox[i].id.indexOf(receivedInputID)!=-1) {
                    inputCheckbox[i].checked = obj.checked;
                }
            }
        }
    </script>  

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

    <script type="text/javascript">
    function displayTable(obj) {
        if(obj.checked) {
            $('[id$=blkToRender]').css('display','block');
            CallApexMethod();
        }
        else {
            $('[id$=blkToRender]').css('display','none');
        }
    }      
    </script>  

    <apex:actionFunction name="CallApexMethod" action="{!clickAction}" rerender="blkToRender" oncomplete="alert(1);"/>

    <apex:pageBlock id="pb1" rendered="{!b1}">
        <apex:inputField value="{!returnAcc.CustomObj__c}">
            <apex:actionSupport action="{!accSearch}" event="onchange" />
        </apex:inputField>
        <apex:pageBlockTable value="{!wrapCls}" var="acc">
            <apex:column>
            <apex:facet name="header">
                <apex:inputCheckbox onclick="selectAllCheckboxes(this,'chk')"/>
            </apex:facet>   
            <apex:inputCheckbox value="{!acc.IsSelected}" id="chk" onclick="displayTable(this)">
            </apex:column> 
            <apex:column>
                <apex:inputField value="{!acc.listA.Type}"/>
            </apex:column>   

        </apex:pageBlockTable>    
    </apex:pageBlock>  

    <apex:pageBlockTable id="blkToRender" value="{!customList}" var="cl">
               <apex:column>
                   <apex:inputField value="{!cl.Type__c}"/>
               </apex:column>   
           </apex:pageBlockTable> 

    </apex:pageBlock>   

</apex:page>
1
2

it is doing this because you have written code like this.

<apex:inputCheckbox value="{!acc.IsSelected}" id="chk">
     <apex:actionSupport event="onclick" reRender="blkToRender" action={!clickAction}/>
</apex:inputCheckbox>

You are controller method onclick of checkbox and which in turn add the row.

You need to do something like

<script>
function displayTable(obj)
{

if(obj.checked)
{
  $('[id$=blkToRender]').css('display','block');
   //call other method or controller code here
}
else
  $('[id$=blkToRender]').css('display','none');

}
</script>
 <apex:inputCheckbox value="{!acc.IsSelected}" id="chk" onclick="displayTable(this)"/>

You can call controller method here and also remove the jquery method from your code.

I am not sure that you are still facing this problem because when I run your code in my org after getting some compile time error (most common apex:form is missing) the code run successfully for me.

I have changed customObj with Contact for reproduction.

Apex Class

public class AccountController {
    private ApexPages.StandardController controller {get;set;}
    public Account returnAcc {get;set;}
    public Boolean b1 {get;set;}
    public List<Account> accList {get;set;}
    public List<contact> customList {get;set;}
    public List<MyWrapper> wrapCls {get;set;}

    public AccountController(ApexPages.StandardController con) {
        controller = con;
        b1 = true;       
        wrapCls = new List<MyWrapper>();
        customList = new List<contact>();
        returnAcc = new Account();
    }

    public void accSearch() {
        List<Account> accounts = new List<Account>();
        List<MyWrapper> wraptemp = new List<MyWrapper>();

        accounts = [SELECT Id, Name, Type FROM Account WHERE Name =: returnAcc.Name];

        for(Account accloop : accounts) {
            wraptemp.add(new MyWrapper(false,accloop));
        }

        if(wraptemp != null) {
            wrapCls = wraptemp;
        }

    }  

    public void clickAction() {
        customList.add(new contact()); 
    }

    public class MyWrapper {
        public Account listA {get;set;}
        public Boolean IsSelected {get;set;}

        public MyWrapper(Boolean sel, Account a) {
            IsSelected = sel;
            listA = a;
        } 
    }
} 

VF page

<apex:page standardController="Account" extensions="AccountController">
    <apex:form>
    <script type="text/javascript">
        function selectAllCheckboxes(obj,receivedInputID) {
            var inputCheckbox = document.getElementsByTagName("input");
            for(var i=0; i<inputCheckbox.length; i++) {
                if(inputCheckbox[i].id.indexOf(receivedInputID)!=-1) {
                    inputCheckbox[i].checked = obj.checked;
                }
            }
        }
    </script>  

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

    <script type="text/javascript">
    function displayTable(obj) {
        if(obj.checked) {
            $('[id$=blkToRender]').css('display','block');
            CallApexMethod();
        }
        else {
            $('[id$=blkToRender]').css('display','none');
        }
    }      
    </script>  

    <apex:actionFunction name="CallApexMethod" action="{!clickAction}" rerender="blkToRender" oncomplete="alert(1);"/>

    <apex:pageBlock id="pb1" rendered="{!b1}">
        <apex:inputField value="{!returnAcc.Name}">
            <apex:actionSupport action="{!accSearch}" event="onchange" />
        </apex:inputField>
        <apex:pageBlockTable value="{!wrapCls}" var="acc">
            <apex:column>
            <apex:facet name="header">
                <apex:inputCheckbox onclick="selectAllCheckboxes(this,'chk')"/>
            </apex:facet>   
            <apex:inputCheckbox value="{!acc.IsSelected}" id="chk" onclick="displayTable(this)"/>
            </apex:column> 
            <apex:column>
                <apex:inputField value="{!acc.listA.Type}"/>
            </apex:column>   

        </apex:pageBlockTable>    


         <apex:pageBlockTable id="blkToRender" value="{!customList}" var="cl">
               <apex:column>
                   <apex:inputField value="{!cl.firstName}"/>
               </apex:column>   
           </apex:pageBlockTable> 
       </apex:pageBlock>    
    </apex:form>
</apex:page>

Working Screenshot enter image description here With Alert enter image description here

15
  • should i still include the actionsupport line in my vf page?
    – curdual
    Oct 15 '16 at 18:07
  • @curdual you can remove that as well.if you want to call controller method you can do that using actionfunction Oct 15 '16 at 18:16
  • I've tried adding this line at the top of the <apex:pageBlock> part: <apex:actionFunction name="CallApexMethod" action="{!clickAction}"/> and added this below $('[id$=blkToRender]').css('display','block'); CallApexMethod(), but the table row does not display anymore.
    – curdual
    Oct 15 '16 at 18:33
  • 1
    @curdual add oncomplete="alert(1); in your action function and check if you get any alert. Also check if you are getting any exception in console. Oct 15 '16 at 19:06
  • 1
    After thorough code inspection, I've noticed that jquery codes I've used in my original post were commented in <!-- --> format, instead of /*... */. Deleting all the unnecessary comments and leaving only the javascript function solves the problem behind why the display/hide function is not working. Didn't know simple comment formatting affects the behavior of javascript codes that much. On the other hand, extra row is still added each time I tick/untick the checkbox, where it's supposed to depend the number of empty rows displayed on the number of selected rows only.
    – curdual
    Oct 17 '16 at 6:10

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.