1

Is it possible to reference a child field in a grid when using a standard controller from an object? Or do I have to create a custom controller? If I do have to create a custom controller then do I return a list based off of a SOQL statement of both objects?

It'd be nice to be able to reference a child field in the grid then I wouldn't have to base the pageblocktable on a custom controller and could use the standardcontroller from the master object.

Here is my controller:

public class DecomController {

     public App__c app {get;set;} 
     public Decommission__c decom {get;set;}

     public DecomController() {
        app = new App__c(); 
        decom = new Decommission__c(); 
    }

    public list<App__c> getList(){
        return [SELECT Name, Agency_Acronym__c, Application_Business_Contact__c, Application_Technical_Contact__c, App_Number__c, (SELECT decommission_status__c, bucketed_status__C, FTE_Position_Support_After_STAR__c, FTE_Position_Support_Prior_to_STAR__c,  total_fte_wages__c  FROM Decommission_Candidate__r) FROM App__c];
    }

    public App__c getApp(){     
        return app;       
    }
    public Decommission__c getDecom(){
        return decom; 
    }

    public void save() {  
        insert app;
        decom.AppID__c = app.id;
        insert decom; 
    }
 }

Here is the visualforce grid attempting to call it and use both fields

<apex:page Controller="DecomController">
    <apex:form >
        <apex:pageBlock title="Available Apps" id="apps">
         <apex:pageBlockTable value="{!list}" var="a">
            <apex:column value="{! a.Name }"/>
            <apex:column value="{! a.App_Number__c }"/>
            <apex:column value="{! a.Agency_Acronym__c }"/>
            <apex:column value="{! a.Bucketed_Status__c }"/>         
        </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>
4

You can indeed reference a child in pure Visualforce. Note that if you want just one record, you don't get to choose which one will be displayed (it will probably be the oldest record, but no guarantees are given).

Here's how you could remove the extra variable by way of using the query:

<apex:page Controller="DecomController">
    <apex:form >
        <apex:pageBlock title="Available Apps" id="apps">
         <apex:pageBlockTable value="{!list}" var="a">
            <apex:column value="{! a.Name }"/>
            <apex:column value="{! a.App_Number__c }"/>
            <apex:column value="{! a.Agency_Acronym__c }"/>
            <apex:column>
                <apex:repeat rows="1" value="{! a.Decommission_Candidate__r }" var="candidate" />
                    {!candidate.bucketed_status__c}
                </apex:repeat>
            </apex:column>
        </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Note that this example restricts the list to a size of one (as I stated earlier), but you could also choose to show all of the options.

Since I don't have your tables available to me, I've written a generic "Accounts and Contact" page you can start from:

<apex:page standardController="Account" recordSetVar="records">
    <apex:pageBlock>
        <apex:pageBlockTable value="{!records}" var="record">
            <apex:column value="{!record.Name}" />
            <apex:column>
                <apex:repeat rows="1" value="{!record.Contacts}" var="contactRecord">
                    {!contactRecord.Name}
                </apex:repeat>
            </apex:column>
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>

With a little more ingenuity, you could technically choose a contact by way of using an apex:variable or two, and a apex:outputText that will render only on certain conditions. However, if you start going too far down that path, you'll eventually run in to view state limits or other problems. If you know there will only be a limited amount of data, this might work for you.

| improve this answer | |
  • It's actually a 1:1 relationship. We have apps that need to be in a portfolio and apps that need to be decommissioned. In the timeline the decommissioning happens first so not every app will be in a portfolio apps that might be partially decommissioned would have been. So basically I'm using the 1:1 to partition off data that in the future will not be useful. I may restructure all of this but it's a great learning exercise and your comment helped immensely – tjcinnamon Feb 27 '16 at 14:31
1

You can't reference the "child" field directly since it's a one to many relationship from App__c to Decommission_Candidate__c. You could have any number of Decommission_Candidate__c records that look up to a single App__c record. The VF PageBlockTable sees Decommission_Candidate__r as a list of sObject records and can't set the output since there'a a list to choose from first.

Is there one specific Decommission_Candidate__c record you're trying to show a field value for in your table? If so you could add a WHERE clause on your inner soql statement to filter by. Something like:

SELECT Name, Agency_Acronym__c, Application_Business_Contact__c, Application_Technical_Contact__c, App_Number__c, (SELECT decommission_status__c, bucketed_status__C, FTE_Position_Support_After_STAR__c,FTE_Position_Support_Prior_to_STAR__c,  total_fte_wages__c FROM Decommission_Candidates__r WHERE Some_Field__c = "SomeValue" LIMIT 1) FROM App__c 

Then, you could reference the field in your table like:

app.Decommission_Candidates__r[0].Bucketed_Status__c
| improve this answer | |
  • It's actually a 1:1 relationship (long story). However, I'm very in intrigued by that second part. Where would I use that last line? app.Decommission_Candidates__r[0].Bucketed_Status__c In the visualforce page of the pageblocktable? That looks like apex formatting but it would be great if that were possible. – tjcinnamon Feb 27 '16 at 14:33

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.