2

The Apex Developer's Guide section on sObject Types has the following:

In this developer's guide, the term sObject refers to any object that can be stored in the Force.com platform database.

A strategy that I use sometimes is to wrap an sObject in a class to display on a VF page and access in a controller. For example:

public class MyController {
    public class AccountWrapper {
        public AccountWrapper(Account a) {
            acct = a;
            selected = false;
        }
        public Account acct { get; set; }
        public Boolean selected { get; set; }
    }

    public List<AccountWrapper> wrappers { get; set; }

    public MyController() {
        wrappers = new List<AccountWrapper>();
        for (Account a : [Select Id, Name From Account Limit 10]) {
            wrappers.add(new AccountWrapper(a));
        }       
    } 
}

Then in the VF inside of some form (the apex:outputField causes problems):

<apex:repeat value="{!wrappers}" var="wrapper">
    <apex:inputCheckbox value="{!wrapper.selected}"/>: 
    <apex:outputField value="{!wrapper.acct}"/><br />
</apex:repeat>

Then back in the Contoller some sort of method with DML, such as:

public PageReference saveTheWrappers() {
    List<Account> accts = new List<Account>();
    for (AccountWrapper wrapper : wrappers) {
        if (wrapper.selected) {
            accts.add(wrapper.acct);
        }
    }
    update accts;

    // or, just to illustrate that acct can be updated while it is wrapped:
    update wrappers.get(0).acct;
}

The problem is that in the VF page I get the following error:

Error: Could not resolve the entity from value binding '{!wrapper.acct}'. can only be used with SObject fields.

Why is it that I can save the wrapped acct as an sObject, but I cannot access it as an sObject from the apex:outputField context?

3

wrapper is not an sObject, so wrapper.acct is not an sObject field. To use outputfield this way, the field will need to be on an sObject. One way to do this is to use a dummy Contact:

public class AccountWrapper {
    ...
    public Contact getcon()
    {
        return new Contact(AccountId = this.acct.Id);
    }
}

Then your outputfield looks like <apex:outputfield value="{!wrapper.con.AccountId}" />.

0
3

You have to specify a particular field on the Account when using apex:outputField like that. For instance, you'll have to to use <apex:outputField value="{!wrapper.acct.Name}" /> or which ever field you're acting on.

If you're trying to set the Account as a lookup field, you'll want to use the relationship of the child object such as <apex:outputField value="{!contact.Account}" />

2
  • Thanks. I'm trying to do the second one, so that I can get the mini-page layout hover link effect. It works when I iterate over a List of Accounts (not wrapped) or output a single Account, or reference the Account as a lookup/master-detail sObject (like you did) but once I put the Account in a wrapper object it doesn't work. Sep 19 '12 at 14:29
  • Can you provide the full VF, and maybe we'll have a better understanding of the requirement. Also, what's the child object in this case? In my example above, I'm using contact, but you could conceivably do the same thing with an account hierarchy (child / parent account). Sep 19 '12 at 14:34
1

I think in this example, {!wrapper.acct} refers to the wrapped object itself, while the apex:outputField tag requires a field on the object. Have you had any luck with something like {!wrapper.acct.name}?

1
  • Yes. That works and is usually what I end up doing, but then I don't get the mini page layout hover effect. Sep 19 '12 at 15:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.