[SalesForce] getting “Error: Unknown property ‘Opportunity_Package__cStandardController.Opp_Package_Rel__c’ ” from this Visualforce page

I am currently in the process of making a system for easily adding packages from a list into our Opportunities.

This visualforce page needs to be accessible to use as a list button, but ever since I've added the recordSetVar on the apex:page tag I've been unable to have the lookup for the opportunity resolve on the visualforce page.

the lookup field I'm trying to resolve is {!Opportunity_Package__c.Opp_Package_Rel__c}

When putting this into a apex:inputField I get:

Error: Could not resolve the entity from <apex:inputField> value binding '{!Opportunity_Package_c.Opp_Package_Rel__c}'. <apex:inputField> can only be used with SObjects, or objects that are Visualforce field component resolvable.

And when I put it in an apex:inputText to try and just resolve an ID I get:

Error: Unknown property 'Opportunity_Package__cStandardController.Opp_Package_Rel__c'

Visualforce page code:

<apex:page standardController="Opportunity_Package__c" extensions="MetadataPackageEditor" recordSetVar="Opportunity_Package__c">
  <apex:form >
      <span>Opportunity </span>
      <apex:outputText value="{!Opp_Package_Rel__c}"/>
      <apex:pageBlock title="Select Package(s)">
      <apex:pageMessages />

      <table style="width:100%;">
          <tbody>
              <tr>
                  <th style="border-bottom: medium solid black; border-right: medium solid black;">Select </th>
                  <th style="border-bottom: medium solid black; border-right: medium solid black;">Package</th>
                  <th style="border-bottom: medium solid black; border-right: medium solid black;">Products</th>
                  <th style="border-bottom: medium solid black; border-right: medium solid black;">PPU Discount</th>
                  <th style="border-bottom: medium solid black; border-right: medium solid black;">Expiration Date</th>
              </tr>

              <apex:repeat value="{!packageMap}" var="oppPackage">
              <tr>
                  <td style="border-bottom: thin solid black; border-right: thin solid black;"><apex:inputCheckbox /></td>
                  <td style="border-bottom: thin solid black; border-right: thin solid black;"><apex:outputField value="{!packageMap[oppPackage].Name}" /></td>
                  <td style="border-bottom: thin solid black; border-right: thin solid black;"><apex:outputField value="{!packageMap[oppPackage].Products__c}"/></td>
                  <td style="border-bottom: thin solid black; border-right: thin solid black;"><apex:outputField value="{!packageMap[oppPackage].PPU_Discount__c}" /></td>
                  <td style="border-bottom: thin solid black; border-right: thin solid black;"><apex:outputField value="{!packageMap[oppPackage].Expiration_Date__c}"/></td>
              </tr>
              </apex:repeat>
          </tbody>
      </table>
      <apex:commandButton value="Add Packages"/>
      <apex:commandButton action="{!cancel}" value="Cancel"/>
      </apex:pageBlock>
  </apex:form>
</apex:page>

Best Answer

There are two standard controllers, one gives you access to a single sObject, the other gives you a list.

When your page only used the attribute standardController, you had the single-object controller in your page. This requires you to pass in an ID value if you want to see a record, it queries for you, and you then have access to a single sobject instance by the exact API name of that object.

<apex:page standardController="My_Object__c">

I can now bind to an instance (you could also say a record) from that object by name, so the following is allowed:

<apex:inputField value="{!My_Object__c.name}"/>

But if you want the controller that is a list of data, that one is actually called "Standard List Controller" or StandardSetController, depending on the docs. The way you make your page use that one is using the recordSetVar attribute on your page.

When you do that, you transmogrify the way the controller works, and you no longer have access to a single record any more, and the list will be populated based on the last used List View by that user.

<apex:page standardController="My_Object__c" recordSetVar="mylist">

  <apex:outputField value="{!My_Object__c.name}"/> <--this is not allowed

  <apex:dataList value="{!mylist}" var="item"> <-- this is allowed
    <apex:outputField value="{!item.Name} <-- so is this
  </apes:dataList>

So it's an either or scenario. Either your page uses standardController and you have access to the one record, or it uses standardController + recordSetVar and you have access to the list of records.

But given you already are using an extension, if you need a list of Opportunity_Package__c records in your page, rather than trying to use recordSetVar like you're doing, I would suggest you just create a new property in your extension and bind to that.

public List<Opportunity_Package__c> listOfOppPacks {get;set;}

Then you can just populate it yourself when you need to.

Related Topic