+ Start a Discussion
Swetha Sfdc1Swetha Sfdc1 

How to add columns dynamically

Hi friends Thanks in advance,

How to add columns dynamically. when user add new row dynamically calculate the value & show total count in
Total amount field.
<apex:page StandardController="Account" extensions="MultiAdding" id="thePage">

<apex:form >
<apex:pageblock id="pb" >
    <apex:pageBlockButtons >
        <apex:commandbutton value="Add" action="{!Add}" rerender="pb1"/>
        <apex:commandbutton value="Save" action="{!Save}"/>
    </apex:pageBlockButtons>
    
        
        <apex:pageblock id="pb1">
            
        <apex:repeat value="{!lstInner}" var="e1" id="therepeat">
                <apex:panelGrid columns="5">
                
                <apex:panelGrid headerClass="Name">
                    
                    <apex:commandButton value="X" action="{!Del}" rerender="pb1">
                        <apex:param name="rowToBeDeleted" value="{!e1.recCount}" assignTo="{!selectedRowIndex}"></apex:param>
                    </apex:commandButton>
                </apex:panelGrid> 
                                
                <apex:panelGrid >                   
                    <apex:inputfield value="{!e1.acct.Count}"/>
                </apex:panelGrid>
            </apex:panelgrid> 
            
        </apex:repeat>
                <apex:outputLink style="padding-left: 1cm;">
           <apex:inputtext style="width:45px;height:15px;"/>  Total amount
        </apex:outputLink>
    </apex:pageBlock>
        
</apex:pageblock>
</apex:form>
</apex:page>
public class MultiAdding
{
    
    //will hold the account records to be saved
    public List<Account>lstAcct  = new List<Account>();
    
    //list of the inner class
    public List<innerClass> lstInner 
    {   get;set;    }
    
    //will indicate the row to be deleted
    public String selectedRowIndex
    {get;set;}  
    
    //no. of rows added/records in the inner class list
    public Integer count = 1;
    //{get;set;}
    
    
    ////save the records by adding the elements in the inner class list to lstAcct,return to the same page
    public PageReference Save()
    {
        PageReference pr = new PageReference('/apex/MultiAdd');
        
        for(Integer j = 0;j<lstInner.size();j++)
        {
            lstAcct.add(lstInner[j].acct);
        } 
        insert lstAcct;
        pr.setRedirect(True);
        return pr;
    }
        
    //add one more row
    public void Add()
    {   
        count = count+1;
        addMore();      
    }
    
    /*Begin addMore*/
    public void addMore()
    {
        //call to the iner class constructor
        innerClass objInnerClass = new innerClass(count);
        
        //add the record to the inner class list
        lstInner.add(objInnerClass);    
        system.debug('lstInner---->'+lstInner);            
    }/* end addMore*/
    
    /* begin delete */
    public void Del()
    {
        system.debug('selected row index---->'+selectedRowIndex);
        lstInner.remove(Integer.valueOf(selectedRowIndex)-1);
        count = count - 1;
        
    }/*End del*/
    
    
    
    /*Constructor*/
    public MultiAdding(ApexPages.StandardController ctlr)
    {
    
        lstInner = new List<innerClass>();
        addMore();
        selectedRowIndex = '0';
        
    }/*End Constructor*/
        


    /*Inner Class*/
    public class innerClass
    {       
        /*recCount acts as a index for a row. This will be helpful to identify the row to be deleted */
        public String recCount
        {get;set;}
        
        
        public Account acct 
        {get;set;}
        
        /*Inner Class Constructor*/
        public innerClass(Integer intCount)
        {
            recCount = String.valueOf(intCount);        
            
            /*create a new account*/
            acct = new Account();
            
        }/*End Inner class Constructor*/    
    }/*End inner Class*/
}/*End Class*/
Capture

Thanks & Regards
Swetha
pconpcon
To be honest, I would do this via JavaScript and push the data from the page to the with @remoteAction [1].  Might be worth looking into Lightning Components [2][3] to see if you can do it easier with that.  Native visualforce doesn't do this type of dynamic work very well.

[1] https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_js_remoting_example.htm
[2] https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/
[3] https://developer.salesforce.com/trailhead/module/lightning_components
Ashish DevAshish Dev
hi swetha,

You could utilize datatable to generate column dynamically as shown below.

VF Page:
<apex:page StandardController="Account" extensions="MultiAdding" id="thePage">
    
    <apex:form >
        <apex:pageblock id="pb" >
            <apex:pageBlockButtons >
                <apex:commandbutton value="Add" action="{!Add}" rerender="pb1"/>
                <apex:commandbutton value="Save" action="{!Save}"/>
                <apex:commandbutton value="Add Column" action="{!AddColumn}" />
            </apex:pageBlockButtons>
            
            
            <apex:pageblock id="pb1">
                
                <apex:dataTable value="{!lstInner}" var="e1" id="theTable" >
                    <apex:repeat value="{!rptColumn}" var="rc">
                        <apex:column>
                            
                            <apex:commandButton value="X" action="{!Del}" rerender="pb1">
                                <apex:param name="rowToBeDeleted" value="{!e1.recCount}" assignTo="{!selectedRowIndex}"></apex:param>
                            </apex:commandButton>
                            <apex:inputfield value="{!e1.acct.NumberOfEmployees}"/>
                            
                        </apex:column>
                    </apex:repeat>
                </apex:dataTable>
    
                <apex:outputLink style="padding-left: 1cm;">
                    <apex:inputtext style="width:45px;height:15px;"/>  Total amount
                </apex:outputLink>
            </apex:pageBlock>
            
        </apex:pageblock>
    </apex:form>
</apex:page>

ExtCtrl:
 
public class MultiAdding
{
    
    //will hold the account records to be saved
    public List<Account>lstAcct  = new List<Account>();
    
    //list of the inner class
    public List<innerClass> lstInner 
    {   get;set;    }
    
    public List<string> rptColumn {get;set;}
    
    //will indicate the row to be deleted
    public String selectedRowIndex
    {get;set;}  
    
    //no. of rows added/records in the inner class list
    public Integer count = 1;
    //{get;set;}
    
    
    ////save the records by adding the elements in the inner class list to lstAcct,return to the same page
    public PageReference Save()
    {
        PageReference pr = new PageReference('/apex/MultiAdd');
        
        for(Integer j = 0;j<lstInner.size();j++)
        {
            lstAcct.add(lstInner[j].acct);
        } 
        insert lstAcct;
        pr.setRedirect(True);
        return pr;
    }
        
    //add one more row
    public void Add()
    {   
        count = count+1;
        addMore();      
    }
    
    /*Begin addMore*/
    public void addMore()
    {
        //call to the iner class constructor
        innerClass objInnerClass = new innerClass(count);
        
        //add the record to the inner class list
        lstInner.add(objInnerClass);    
        system.debug('lstInner---->'+lstInner);            
    }/* end addMore*/
    
    public void AddColumn()
    {
		rptColumn.add('column 1');        
    }/* end addMore column */
    
    /* begin delete */
    public void Del()
    {
        system.debug('selected row index---->'+selectedRowIndex);
        lstInner.remove(Integer.valueOf(selectedRowIndex)-1);
        count = count - 1;
        
    }/*End del*/
    
    
    
    /*Constructor*/
    public MultiAdding(ApexPages.StandardController ctlr)
    {
    	rptColumn = new List<string>();
        rptColumn.add('column 1');
        lstInner = new List<innerClass>();
        addMore();
        selectedRowIndex = '0';
        
    }/*End Constructor*/
        


    /*Inner Class*/
    public class innerClass
    {       
        /*recCount acts as a index for a row. This will be helpful to identify the row to be deleted */
        public String recCount
        {get;set;}
        
        
        public Account acct 
        {get;set;}
        
        /*Inner Class Constructor*/
        public innerClass(Integer intCount)
        {
            recCount = String.valueOf(intCount);        
            
            /*create a new account*/
            acct = new Account();
            
        }/*End Inner class Constructor*/    
    }/*End inner Class*/
}/*End Class*/