8

In a custom Visualforce page with a standard controller, how can I check and conditionally render related lists based on availability of records in the related list?

1
  • is there a reason you can't use a controller extension?
    – Phil B
    Commented Jan 23, 2013 at 20:52

2 Answers 2

4

Ideally one would like to write a rendered expression like so {!IF(Text__c.Test_Children_r.size > 0, TRUE, FALSE)}. However this results in an error as Visualforce is expecting a field name from the child object. Shame. So failing this, you then have two options, the first of which is preferred, as the second option, while it works is strictly speaking unsupported according to the docs.

Apex extension controller option

This example uses a controller property to expose the count. It also avoids having to perform the SOQL query itself by letting the standard controller know in advance that this information is required (typically driven by field references in the page).

public with sharing class ConditionalRelatedList 
{
    private ApexPages.StandardController standardController;

    public ConditionalRelatedList(ApexPages.StandardController standardController)
    {   
        this.standardController = standardController;
        this.standardController.addFields(new List<String> { 'Test_Children__r' });
    }

    public Integer getChildCount()
    {
        return ((Test__c) standardController.getRecord()).Test_Children__r.size();
    }
}

You can then refer to the count in the rendered attribute as follows.

<apex:page standardController="Test__c" extensions="ConditionalRelatedList">
    <apex:detail relatedList="false" />
    <apex:relatedList list="Test_Children__r" rendered="{!IF(childCount > 0, TRUE, FALSE)}" />
</apex:page>

Visualforce only option

NOTE: This option does work, but is technically unsupported, see the warnings about reassigning apex:variables within apex:repeat here.

<apex:page standardController="Test__c">
    <apex:detail relatedList="false" />
    <apex:variable var="count" value="{!0}" />
    <apex:repeat value="{!Test__c.Test_Children__r}" var="row">
        <apex:variable var="count" value="{!count+1}" />
    </apex:repeat>
    <apex:relatedList list="Test_Children__r" rendered="{!IF(count > 0, TRUE, FALSE)}" />
</apex:page>
5
  • 2
    Nice answer! The second option is probably the better solution because, although the first solution does work in this case, according to the apex:variable documentation the apex:variable does not support reassignment inside of an iteration component and the result of doing so, e.g., incrementing the apex:variable as a counter, is unsupported and undefined. Commented Jan 24, 2013 at 0:15
  • Thanks Peter, good reference, I've updated my answer to clarify this. Thanks! Commented Jan 24, 2013 at 0:26
  • Heh, annoyed I missed this question since I used that second trick only yesterday!
    – Matt Lacey
    Commented Jan 24, 2013 at 5:49
  • Found one more solutions that works using custom components here: boards.developerforce.com/t5/Visualforce-Development/…
    – Ganesh
    Commented Jan 27, 2013 at 5:53
  • 3
    BTW, you can simplify your rendered attribute formula to just {!(count > 0)} instead of {!IF(count > 0, TRUE, FALSE)}.
    – tomlogic
    Commented Feb 1, 2013 at 20:49
9

This question prompted me to do some more research on this, and I came up with an alternative, though still unsupported, VisualForce only solution:

<apex:variable var="v" value="'{!Account.Contacts}'"/>
<apex:variable var="v2" value="'[]'"/>

<apex:outputText value="Contacts!" rendered="{!v == v2}"/>

It's a bit more concise than the apex:variable method, and doesn't involve changing the values assigned to a variable. That said, it's relying on an empty array always being represented as '[]', though I think we're on relatively safe ground with that assumption.

4
  • What is the reason behind doing your quotes like that? "'Account.Contacts'". Single quotes encased in double
    – EricSSH
    Commented Jul 13, 2015 at 15:37
  • 2
    It's so that instead of v being assigned an empty array value, it's assigned the string value '[]' which let's us do the comparison with v2.
    – Matt Lacey
    Commented Jul 14, 2015 at 5:08
  • Yes, this is a perfect little work-around! Commented Sep 13, 2016 at 11:06
  • Nice! Love this solution.
    – Allen Mann
    Commented Mar 10, 2017 at 19:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .