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
SFDCDevQASFDCDevQA 

Error: Unknown property 'VisualforceArrayList.CloseDate'

I'm trying to create a table where the first two rows are opps related to the account and the next row(s) are for creating new opps.  I originally just had the table creating new opps and it worked fine but now we want to see a few existing ones as well to prevent duplicates.  So it must be something to do with my existing opps list...I just can't figure it out.  The controller saves fine but the VF page says Error: Unknown property 'VisualforceArrayList.CloseDate'.  If I remove closedate from the vf page it just gives the same error with the next field.  Somebody please help me figure this out.

Controller:
public class ForecastOpportunitiesController
{
public Account theAcc {get;set;}
public List<ForecastOpportunitiesWrapper> wrappers {get; set;}
public Opportunity[] existingopps {get;set;} { existingopps = new List<Opportunity>(); }
Public string accrecordId {get;set;}
public static Integer toDelIdent {get; set;}
public static Integer addCount {get; set;}

private Integer nextIdent=1;
 
public ForecastOpportunitiesController(ApexPages.StandardsetController controller)

{
  accrecordid = ApexPages.CurrentPage().getparameters().get('id');
 
  // Query current opportunities
  existingopps = [
            select Id, Accountid, Name, Stagename, CloseDate
            from Opportunity
            where Accountid = :accrecordid order by CloseDate DESC Limit 2
        ];
       
  wrappers=new List<ForecastOpportunitiesWrapper>();
  for (Integer idx=0; idx<3; idx++)
  {
   wrappers.add(new ForecastOpportunitiesWrapper(nextIdent++));
  }
}
 
public void delWrapper()
{
  Integer toDelPos=-1;
  for (Integer idx=0; idx<wrappers.size(); idx++)
  {
   if (wrappers[idx].ident==toDelIdent)
   {
    toDelPos=idx;
   }
  }
  
  if (-1!=toDelPos)
  {
   wrappers.remove(toDelPos);
  }
}
 
public void addRows()
{
  for (Integer idx=0; idx<addCount; idx++)
  {
   wrappers.add(new ForecastOpportunitiesWrapper(nextIdent++));
  }
}
 
public PageReference save()
{
  List<Opportunity> opps=new List<Opportunity>();
  for (ForecastOpportunitiesWrapper wrap : wrappers)
  {
   opps.add(wrap.opp);
  }
  
  insert opps;
  
  return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id'));
}

public PageReference onCancel(){

        // If user hits cancel we commit no changes and return them to the Account  
        return new PageReference('/' + ApexPages.currentPage().getParameters().get('Id'));
    }
 
public class ForecastOpportunitiesWrapper
{
  Public string recordId {get;set;}
  public Opportunity opp {get; private set;}
  public Integer ident {get; private set;}
  
  public ForecastOpportunitiesWrapper(Integer inIdent)
  {
   recordid = ApexPages.CurrentPage().getparameters().get('id');
   ident=inIdent;
   opp=new Opportunity(name='Forecast' + ident, Accountid=recordid, stagename='Forecast');
  }
}
}

VF Page:
<apex:page standardController="Opportunity"  recordSetVar="opps" extensions="ForecastOpportunitiesController" tabstyle="Opportunity">
<apex:form >
<apex:pageBlock title="Bulk Opportunity Create">
      <apex:pageBlockTable value="{!existingopps}" var="opps" id="wtable">
         <apex:column headerValue="Close Date">
            <apex:inputField value="{!opps.CloseDate}"/>
         </apex:column>
         <apex:column headerValue="Name">
            <apex:outputtext value="{!opps.Name}"/>
         </apex:column>
         <apex:column headerValue="Quantity">
            <apex:inputField value="{!opps.TotalOpportunityQuantity}" required="true"/>
         </apex:column>
         <apex:column headerValue="Stage">
            <apex:outputtext value="{!opps.StageName}"/>
         </apex:column>
      </apex:pageBlockTable>
   </apex:pageBlock>
   <apex:pageBlock title="Bulk Opportunity Create">
      <apex:pageBlockTable value="{!wrappers}" var="wrapper" id="wtable">
    <!--       <apex:column headerValue="Ident">-->
          <!--    <apex:outputText value="{!wrapper.ident}"/>-->
<!--           </apex:column>-->
         <apex:column headerValue="Close Date">
            <apex:inputField value="{!wrapper.opp.CloseDate}"/>
         </apex:column>
         <apex:column headerValue="Name">
            <apex:outputtext value="{!wrapper.opp.Name}"/>
         </apex:column>
         <apex:column headerValue="Quantity">
            <apex:inputField value="{!wrapper.opp.TotalOpportunityQuantity}" required="true"/>
         </apex:column>
         <apex:column headerValue="Stage">
            <apex:outputtext value="{!wrapper.opp.StageName}"/>
         </apex:column>
   <!--      <apex:column headerValue="Account"> -->
   <!--           <apex:outputtext value="{!wrapper.opp.Accountid}"/> -->
         <!--  </apex:column> -->
<!--          <apex:column headerValue="Action">-->
       <!--       <apex:commandButton value="Delete" action="{!delWrapper}" rerender="wtable">-->
             <!--    <apex:param name="toDelIdent" value="{!wrapper.ident}" assignTo="{!toDelIdent}"/>-->
<!--              </apex:commandButton>-->
      <!--     </apex:column>-->
      </apex:pageBlockTable>
    <apex:commandButton value="Add Row" action="{!addRows}" rerender="wtable">
      <apex:param name="addCount" value="1" assignTo="{!addCount}"/>
      </apex:commandButton>
      <apex:commandButton value="Save" action="{!save}"/>
       <apex:commandButton action="{!onCancel}" value="Cancel" immediate="true"/>
   </apex:pageBlock>
</apex:form>
</apex:page>

Wrapper:
public class ForecastOpportunitiesWrapper
{

Public string recordId {get;set;}
public Opportunity opp {get; private set;}
public Integer ident {get; private set;}
 
public ForecastOpportunitiesWrapper(Integer inIdent)

{
  recordid = ApexPages.CurrentPage().getparameters().get('id');
  ident=inIdent;
  opp=new Opportunity(name='Forecast' + ident, accountid=recordid, stagename='Forecast');
 
  
}
}
bob_buzzardbob_buzzard
It looks like you've confused the page by using opps to refer to two separate properties, and the first one is winning.

In your page declaration you have :

<apex:page standardController="Opportunity"  recordSetVar="opps" extensions="ForecastOpportunitiesController" tabstyle="Opportunity">

which defines 'opps' as the list of records the standard set controller is managing.  However later you you have:

<apex:pageBlockTable value="{!existingopps}" var="opps" id="wtable">
which attempts to redefine 'opps' to be an instance from the existingopps collection.  Judging by the error messages, 'opps' is retaining its first definition as a list of sobjects, which is why you can't access  the closedate (or any other) field from it.

Try changing your recordsetvar to be something like 'oppset' - that should fix it.