0

I need to use an OutputField on a Visualforce page, to filter a different SOQL query.

I have two unrelated objects - Account and Label...

The idea is that on the page load, the label of the Account Name field is filtered to that of the country that the account resides.

Im not sure how to build the controller to retrieve the country, or whether the field has to pass from the VF page?

One way of doing this would be to pass through the field in the URL. I would rather not do it this way.

I have added the code, leaving in the url passthrough, so as to help anyone else that might want to do it this way. Just concatenate the relevant fields (the url would look something like this - /apex/vfpage?id=a1FN0000000cEaw&country=Australia)

Any help would be appreciated

Thanks

VF:

<apex:page controller="fieldPassController" >

<apex:form >
<apex:repeat value="{!thisAccount}" var="thisAcc">
    <apex:outputField value="{!thisAcc.Country__c}"/>

    <apex:repeat value="{!label}" var="lab">
        <apex:outputField value="{!lab.Name}"/>
    </apex:repeat>

    <apex:inputField value="{!thisAcc.Name}" />
</apex:repeat>
</apex:form>

</apex:page>

Controller:

public class fieldPassController {

public list <account> thisAccount {get;set;}
public list <labels__c> label {get;set;}
public Id thisAccountID = ApexPages.currentPage().getParameters().get('Id');
//public string thisAccountCountry = ApexPages.currentPage().getParameters().get('Country');
//public string thisAccountCountry = thisAccount.Country__c;

    public fieldPassController() {

        thisAccount = [
            SELECT
                Country__c,
                id,
                name

            FROM Account
            WHERE id = :thisAccountID];

        label = [
            SELECT
                Country__c,
                id,
                name

            FROM Labels__c
            //WHERE Country__c = :thisAccountCountry
            ];
    }
}
  • there is some confusion here -- is the page supposed to show only one (1) Account and its corresponding label? Or a list of accounts and their country-driven labels? If the former, then thisAccount should not be declared as a list type. If the latter, then the controller queries aren't right – cropredy Jun 16 '16 at 3:59
  • @cropredy The former, its one account (retrieved by the url id) – TheMikeyBoosh Jun 16 '16 at 4:14
1

In your controller, uncomment the WHERE part of the Labels__c SOQL query and change it to:

WHERE Country__c = :thisAccount[0].Country__c

This works because you've already queried for the account and stored the result in thisAccount. Then you don't need to pass the country as a URL param.

Also, if this page is only for one account, you don't actually need to do repeats in the Visualforce page. You could just store the results of the query in a single SObject, though I would still store them in a List initially (see SOQL return type: List<sObject> vs. sObject).

  • Thanks for your reply. Unfortunately I had tried this before, it failed with the response: Error: fieldPassController Compile Error: Initial term of field expression must be a concrete SObject: List<Account> at line 27 column 37 – TheMikeyBoosh Jun 16 '16 at 2:46
  • Sorry, I forgot that thisAccount was actually a List. Try changing the where clause to WHERE Country__c = :thisAccount[0].Country__c. I'll update my answer above. – Robert Watson Jun 16 '16 at 5:16
  • Thanks, but there is a resulting error - System.ListException: List index out of bounds: 0 Class.fieldPassController.<init>: line 26, column 1 – TheMikeyBoosh Jun 16 '16 at 5:21
  • Then that suggests to me that the account is not getting queried successfully. Add a System.debug(thisAccount); after you query for the account and determine that it's being returned successfully in the debug logs. See sfdc99.com/2014/02/22/debug-your-code-with-system-debug – Robert Watson Jun 16 '16 at 17:27
  • Thanks! this is working. One last thing, there are two solutions to this post, can you tell me the difference? What you have supllied works a treat, I wonder why they vary so much? Thanks in advance! – TheMikeyBoosh Jun 17 '16 at 0:24
1

OK, Here is a framework solution given that I understand the problem space - 1 account with one country label

Custom controller

public class FieldPassController {

  public class AccountWrapper {
    public Account a {get;set;}
    public String  ctryLabel {
        get {
            return [select id, name from Labels__c
                      where country__c = :this.a.country__c][0].name;
        } 
        private set;    
    }
    public AccountWrapper(Account a) {this.a = a;}
  }


  public AccountWrapper aW {
    get {
        if (this.aW == null) 
            this.aW = new AccountWrapper([select id, country__c, name from Account
                                            where id = :ApexPages.currentPage().getParameters().get('Id')]);
        return this.aW;                                 
    }
    set;
  }
}

VF page

<apex:page controller="FieldPassController">

    <apex:pageMessages />
    <apex:form>
        <apex:outputText value="{!aW.ctryLabel}"/>
        <apex:inputField value="{!aW.a.name}"/>
    </apex:form>
</apex:page>

Essence of solution is to let the getters in the controller fetch the values into a convenient package (the inner AccountWrapper class). When the VF page does its GET processing, it will reference the getter for this merge field {!aW. ...}. This in turn fetches the account from the page parameter, and creates the wrapper class instance.

When the VF page needs {!aW.ctryLabel}, the AccountWrapper is already constructed and there's a value for the Account.Country__c. This in turn is used by the getter for ctryLabel to query from the Labels__c table.

I omitted error handling (such as Accounts without Countrys or countrys not in Labels or the ID URL param not being a valid Account)

  • Thanks, however there is an error - Error: FieldPassController2 Compile Error: Non-void method might not return a value or might have statement after a return statement. at line 27... – TheMikeyBoosh Jun 16 '16 at 5:16
  • my bad -- fixed in code above – cropredy Jun 16 '16 at 14:52
  • Thanks, however the following error occurs - Error: Could not resolve the entity from <apex:outputField> value binding '{!aW.ctryLabel}'. <apex:outputField> can only be used with SObjects, or objects that are Visualforce field component resolvable. – TheMikeyBoosh Jun 16 '16 at 23:38
  • aargh -- I changed it to apex:outputText – cropredy Jun 17 '16 at 0:01
  • One last thing - There is another method of doing this (see Roberts post), do you know what the difference between the two answers is, as they both work! Thanks for your time! – TheMikeyBoosh Jun 17 '16 at 0:25

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.