function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Mike_M_2Mike_M_2 

apex:datatable repeats same row over and over again.

When my datatable displays, the proper number of rows is displayed, but each row has the same data in it. 

My controller code:

 

   public class CampaignDetailLine {
        public String IO_Suffix {get; set;}
        public String Description {get; set;} 
        public String Name {get; set;} 
        public String Size {get; set;} 
        public dateTime ServiceDate {get; set;} 
        public dateTime End_Date {get; set;} 
        public Double UnitPrice {get; set;} 
        public Double Quantity {get; set;} 
        public Double TotalPrice {get; set;} 
      
    }
                 
   public  List<CampaignDetailLine> getIOOpportunity() {
           List<CampaignDetailLine> dtlines = new List<CampaignDetailLine>();
           CampaignDetailLine dtline = new CampaignDetailLine();
           
       Opportunity ioopp = [
            SELECT id, name, amount, Ownerid, owner.id, owner.name,
                   Estimated_Revenue_Start_Date__c ,
                   PO__c ,Estimated_Revenue_End_Date__c,
                   Campaign_Details__c ,Billing_Notes__c ,
                   Invoice_Notes__c,
                   AutoIO__c,
                  (SELECT IO_Suffix__c, Description, PricebookEntry.Name,
                           Size__c, ServiceDate, End_Date__c, UnitPrice,
                           Quantity, TotalPrice   
                     FROM OpportunityLineItems order by IO_Suffix__c )
              FROM Opportunity where id = :opp.id];

        for(OpportunityLineItem o : ioopp.OpportunityLineItems) {         
             dtline.IO_Suffix = o.IO_Suffix__c;
             dtline.Description = o.Description;
             dtline.Name = o.PricebookEntry.Name;
             dtline.Size = o.Size__c;
             dtline.ServiceDate = o.ServiceDate;
             dtline.End_Date = o.End_Date__c;
             dtline.UnitPrice = o.UnitPrice;
             dtline.Quantity = o.Quantity;
             dtline.TotalPrice = o.TotalPrice;  

             dtlines.add(dtline); 
        }
                     system.debug(dtlines[0].IO_Suffix);
                     system.debug(dtlines[1].IO_Suffix);
      return dtlines;
    }

I know from the debug statements that each line of dtlines contains a different value. However, when the page displays, I see two lines, each with the content of dtlines[1].

 

 

 My datable

       <apex:dataTable value="{!IOopportunity}" var="item" id="lineItemTable" 
          columns="9" width="100%" 
          columnClasses="sectionDataLeft,sectionDataLeft,sectionDataLeft,sectionDataLeft,sectionDataRight,sectionDataRight,sectionDataRight" 
          border="1"
          cellpadding="3" >

          <apex:column >
                <apex:facet name="header">Line</apex:facet>
                <apex:outputText value="{!item.IO_Suffix}"/>
            </apex:column>
            <apex:column >
                <apex:facet name="header">Description</apex:facet>
                <apex:outputText value="{!item.Description}"/>
            </apex:column>
            <apex:column >
                <apex:facet name="header">Product</apex:facet>
                <apex:outputText value="{!item.Name}"/>
            </apex:column>
            <apex:column >
                <apex:facet name="header">Size</apex:facet>
                <apex:outputText value="{!item.Size}"/>
            </apex:column>

            <apex:column >
                <apex:facet name="header">Start Date</apex:facet>
                <apex:outputText value="{0,date,M'/'dd'/'yyyy}">
                        <apex:param value="{!item.ServiceDate}" />
               </apex:outputText>
            </apex:column>
            
            <apex:column >
                <apex:facet name="header">End Date</apex:facet>
                <apex:outputText value="{0,date,M'/'dd'/'yyyy}">
                        <apex:param value="{!item.End_Date}" />
               </apex:outputText>
            </apex:column>
          
            <apex:column >
                <apex:facet name="header">CPU</apex:facet>
                <apex:outputText value="{!item.UnitPrice}"/>
            </apex:column>
            <apex:column >
                <apex:facet name="header">Quantity</apex:facet>
                <apex:outputText value="{!item.Quantity}"/>
            </apex:column>
            <apex:column >
                <apex:facet name="header">Line Total</apex:facet>
                <apex:outputText value="{!item.TotalPrice}"/>
            </apex:column>

        </apex:dataTable>
     

 I am using a LIST (instead of just returning a SObject)  because later, I intend on adding more rows to this list. But for now, I just want to get this part working.

 

Any help is greatly appreciated.

 

Mike

 

 

Best Answer chosen by Admin (Salesforce Developers) 
aballardaballard

Your loop that creates the list needs to create a new DTLine for each row.... You are creating a list with the same object added multiple times. 

All Answers

aballardaballard

Your loop that creates the list needs to create a new DTLine for each row.... You are creating a list with the same object added multiple times. 

This was selected as the best answer
Mike_M_2Mike_M_2

I would have thought that since my debug statements each show a different value, that would mean I was loading the list properly. I'm still new to this and still learning. Can you show me how to do as you are suggesting?

Thanks

Mike_M_2Mike_M_2

Worked it out with your help. Thanks. Problem is, I still think in terms of 'copy data' rather than in terms of 'point to data'.

 

Thanks very much!

Mike

 

Mike_M_2Mike_M_2

For future reference, working code now looks like this:

   public  List<CampaignDetailLine> getIOOpportunity() {
           List<CampaignDetailLine> dtlines = new List<CampaignDetailLine>();
           
       Opportunity ioopp = [
            SELECT id, name, amount, Ownerid, owner.id, owner.name,
                   Estimated_Revenue_Start_Date__c ,
                   PO__c ,Estimated_Revenue_End_Date__c,
                   Campaign_Details__c ,Billing_Notes__c ,
                   Invoice_Notes__c,
                   AutoIO__c,
                  (SELECT IO_Suffix__c, Description, PricebookEntry.Name,
                           Size__c, ServiceDate, End_Date__c, UnitPrice,
                           Quantity, TotalPrice   
                     FROM OpportunityLineItems order by IO_Suffix__c )
              FROM Opportunity where id = :opp.id];

        for(OpportunityLineItem o : ioopp.OpportunityLineItems) { 
             CampaignDetailLine dtline = new CampaignDetailLine();        
             dtline.IO_Suffix = o.IO_Suffix__c;
             dtline.Description = o.Description;
             dtline.Name = o.PricebookEntry.Name;
             dtline.Size = o.Size__c;
             dtline.ServiceDate = o.ServiceDate;
             dtline.End_Date = o.End_Date__c;
             dtline.UnitPrice = o.UnitPrice;
             dtline.Quantity = o.Quantity;
             dtline.TotalPrice = o.TotalPrice;  

             dtlines.add(dtline); 
        }
                     system.debug(dtlines[0].IO_Suffix);
                     system.debug(dtlines[1].IO_Suffix);
      return dtlines;
    }