+ Start a Discussion
Mona VermaMona Verma 

Data bind not working for list used in apex:repeat in vf page

Just trying to implement dynamic add row feature on visualforce page. A page for Team details created on which (detail object) Player records are also capured. User can enter Team details and in Player section add 1 layer details. To add more players, click on Add Player buton. 
But as the Ad player button is clicked, the data from first row vanish. Issue is that list  (list of wraper inner class for player and record count)  used in apex:repeat for Players list on visualforce page is blank in Add() of controller. 


The detailed question with code and screenshot can be referred from url:
https://salesforce.stackexchange.com/q/188872/48317
Best Answer chosen by Mona Verma
Alain CabonAlain Cabon
Hi Mona Verma,

By the way: always copy/paste the complete code of your problem (other developers in this forum would have solved your problem very easily with this complete code yet).

You have probably already solve your problem yourself.

Fortunately, your code is simple so I could guess the missing parts easily of your copy/paste.

I post a first solution because your code is interesting and should be improve again.

Two custom objects : Team and Player and two custom fields : "Is Club Captain" and "Jersey Number" for Player

User-added image

User-added image
 
public with sharing class CreateTeamController {
    
    public Team__c team;
    
    //will hold the player records to be saved
    public List<Player__c> players = new List<Player__c>();
    
    //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 = 0;
    
    public CreateTeamController(ApexPages.StandardController controller) {
        count = count+1;
        this.team = (Team__c)controller.getRecord();
        lstInner = new List<InnerClass>();
        addMore();
        selectedRowIndex = '0';
    }     
    public PageReference cancel() {
        return null;
    }    
    public PageReference save() {
        insert team;
        PageReference ReturnPage = new PageReference('/apex/View_Team?id='+team.ID); 
        
        for(Integer j = 0;j<lstInner.size();j++)
        {
            lstInner[j].player.Team__c = team.Id;
            players.add(lstInner[j].player);
        } 
        insert players;       
        Apexpages.Message msg = new ApexPages.Message(ApexPages.Severity.CONFIRM,'Team Created Successfully.');
        Apexpages.addmessage(msg);
        
        return ReturnPage; 
    }
    
    //add one more row
    public PageReference add()
    {   
        system.debug('before add lstInner---->'+this.lstInner.size());  
        for (InnerClass lt : lstInner) {
            system.debug('player---->'+lt.player.name + ' captain:' + lt.player.Club_Captain__c + ' Jersey__c:' +  lt.player.Jersey__c);
        }
       // system.debug('player---->'+this.lstInner.get(0).player.name); 
        count = count+1;
        addMore(); 
        return null;      
    }
    
    /*Begin addMore*/
    public void addMore()
    {
        system.debug('count::'+count);  
        //call to the inner class constructor
        innerClass objInnerClass = new innerClass(count);
        
        //add the record to the inner class list
        this.lstInner.add(objInnerClass);    
        system.debug('after add lstInner---->'+lstInner.size());            
    }/* end addMore*/
        
    public void Del()
    {
        system.debug('selected row index---->'+selectedRowIndex);
        lstInner.remove(Integer.valueOf(selectedRowIndex)-1);
        count = count - 1;
        
    }
    
    /*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 Player__c player {get;set;}
        
        /*Inner Class Constructor*/
        public InnerClass(Integer intCount)
        {
            recCount = String.valueOf(intCount);        
            
            /*create a new player*/
            player = new Player__c();
            
        }/*End Inner class Constructor*/    
    }/*End inner Class*/ }
 
<apex:page standardcontroller="Team__c"  extensions="CreateTeamController">
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockSection title="Players" id="wtable">    
                <apex:actionRegion >
                    <apex:repeat value="{!lstInner}" var="e1" id="therepeat">            
                        <apex:panelGrid columns="4">                  
                            <apex:panelGrid >          
                                <apex:facet name="header">IsClubCaptain</apex:facet>
                                <apex:inputCheckbox value="{!e1.player.Club_Captain__c}"/> 
                            </apex:panelGrid>             
                            <apex:panelGrid title="Name" >
                                <apex:facet name="header">Name</apex:facet>
                                <apex:inputtext value="{!e1.player.Name}"/>
                            </apex:panelGrid>           
                            <apex:panelGrid >
                                <apex:facet name="header">Jersey Numer</apex:facet>
                                <apex:inputtext value="{!e1.player.Jersey__c}"/>
                            </apex:panelGrid>
                            <apex:panelGrid headerClass="Player">
                                <apex:facet name="header">Del</apex:facet>
                                <apex:commandButton value="X" action="{!Del}" rerender="wtable">
                                    <apex:param name="rowToBeDeleted" value="{!e1.recCount}" assignTo="{!selectedRowIndex}"></apex:param>
                                </apex:commandButton>                           
                            </apex:panelGrid>
                        </apex:panelGrid>                            
                    </apex:repeat>                
                    <apex:commandButton value="Add Player" action="{!add}" rerender="wtable">                  
                    </apex:commandButton>            
                </apex:actionRegion>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Best regards
Alain 

All Answers

Alain CabonAlain Cabon
Hi Mona Verma,

By the way: always copy/paste the complete code of your problem (other developers in this forum would have solved your problem very easily with this complete code yet).

You have probably already solve your problem yourself.

Fortunately, your code is simple so I could guess the missing parts easily of your copy/paste.

I post a first solution because your code is interesting and should be improve again.

Two custom objects : Team and Player and two custom fields : "Is Club Captain" and "Jersey Number" for Player

User-added image

User-added image
 
public with sharing class CreateTeamController {
    
    public Team__c team;
    
    //will hold the player records to be saved
    public List<Player__c> players = new List<Player__c>();
    
    //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 = 0;
    
    public CreateTeamController(ApexPages.StandardController controller) {
        count = count+1;
        this.team = (Team__c)controller.getRecord();
        lstInner = new List<InnerClass>();
        addMore();
        selectedRowIndex = '0';
    }     
    public PageReference cancel() {
        return null;
    }    
    public PageReference save() {
        insert team;
        PageReference ReturnPage = new PageReference('/apex/View_Team?id='+team.ID); 
        
        for(Integer j = 0;j<lstInner.size();j++)
        {
            lstInner[j].player.Team__c = team.Id;
            players.add(lstInner[j].player);
        } 
        insert players;       
        Apexpages.Message msg = new ApexPages.Message(ApexPages.Severity.CONFIRM,'Team Created Successfully.');
        Apexpages.addmessage(msg);
        
        return ReturnPage; 
    }
    
    //add one more row
    public PageReference add()
    {   
        system.debug('before add lstInner---->'+this.lstInner.size());  
        for (InnerClass lt : lstInner) {
            system.debug('player---->'+lt.player.name + ' captain:' + lt.player.Club_Captain__c + ' Jersey__c:' +  lt.player.Jersey__c);
        }
       // system.debug('player---->'+this.lstInner.get(0).player.name); 
        count = count+1;
        addMore(); 
        return null;      
    }
    
    /*Begin addMore*/
    public void addMore()
    {
        system.debug('count::'+count);  
        //call to the inner class constructor
        innerClass objInnerClass = new innerClass(count);
        
        //add the record to the inner class list
        this.lstInner.add(objInnerClass);    
        system.debug('after add lstInner---->'+lstInner.size());            
    }/* end addMore*/
        
    public void Del()
    {
        system.debug('selected row index---->'+selectedRowIndex);
        lstInner.remove(Integer.valueOf(selectedRowIndex)-1);
        count = count - 1;
        
    }
    
    /*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 Player__c player {get;set;}
        
        /*Inner Class Constructor*/
        public InnerClass(Integer intCount)
        {
            recCount = String.valueOf(intCount);        
            
            /*create a new player*/
            player = new Player__c();
            
        }/*End Inner class Constructor*/    
    }/*End inner Class*/ }
 
<apex:page standardcontroller="Team__c"  extensions="CreateTeamController">
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockSection title="Players" id="wtable">    
                <apex:actionRegion >
                    <apex:repeat value="{!lstInner}" var="e1" id="therepeat">            
                        <apex:panelGrid columns="4">                  
                            <apex:panelGrid >          
                                <apex:facet name="header">IsClubCaptain</apex:facet>
                                <apex:inputCheckbox value="{!e1.player.Club_Captain__c}"/> 
                            </apex:panelGrid>             
                            <apex:panelGrid title="Name" >
                                <apex:facet name="header">Name</apex:facet>
                                <apex:inputtext value="{!e1.player.Name}"/>
                            </apex:panelGrid>           
                            <apex:panelGrid >
                                <apex:facet name="header">Jersey Numer</apex:facet>
                                <apex:inputtext value="{!e1.player.Jersey__c}"/>
                            </apex:panelGrid>
                            <apex:panelGrid headerClass="Player">
                                <apex:facet name="header">Del</apex:facet>
                                <apex:commandButton value="X" action="{!Del}" rerender="wtable">
                                    <apex:param name="rowToBeDeleted" value="{!e1.recCount}" assignTo="{!selectedRowIndex}"></apex:param>
                                </apex:commandButton>                           
                            </apex:panelGrid>
                        </apex:panelGrid>                            
                    </apex:repeat>                
                    <apex:commandButton value="Add Player" action="{!add}" rerender="wtable">                  
                    </apex:commandButton>            
                </apex:actionRegion>
            </apex:pageBlockSection>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Best regards
Alain 
This was selected as the best answer
Mona VermaMona Verma
Thanks Alain for your guidance. Only one mistake of misplacing aex:actionRegion took lot of time. But I am hapy that I am learning. 
Alain CabonAlain Cabon
Hi Mona,

Your first use of <apex:actionRegion> seems correct according the documentation but that doesn't work here.

We could wait for a complete explaination (bug/issue?) from another developer who already experienced this problem here.

As it lacks the upper part of your form in your copy/paste, it would be interesting to know if this first change works for the entire form.

By the way, if this change solved your first problem and helped you, you could close the question (best practice here).

Regards
Alain
Mona VermaMona Verma
Yes Alain, this change worked for my complete form as the upper part of form is nothing but form to capture (Master) Team details and below that players section to capture players one by one.
It also solved one additional problem. Earlier, when I clicked on Add player button, the new Player row was getting added beside existing row instead of newline. But now it is solved. Everytime I click on Add Player, row gets added to new line.

I can close this question now. Thanks again.