+ Start a Discussion
Daniel B ProbertDaniel B Probert 

Render visualforce block is subquery list size > 0

Hi All,

I have a subquery statement and I'm trying to make sure that parent records don't display if they have no child records available.

Query:

List<Training_Module__c> trainingmod;
    public List<Training_Module__c> gettrainingmod() {
        if(trainingmod == null) {
            trainingmod = [SELECT id, Name, Introduction__c,
                (SELECT id, Name, Introduction__c
                    FROM Training_Lessons__r
                    WHERE (Applicable_Country__c includes (:empcountry) and Applicable_Teams__c includes (:empteam) and Status__c=:'Online'))
                FROM Training_Module__c
                WHERE Training_Course__c =:currentpage and Applicable_Country__c includes (:empcountry) and Applicable_Teams__c includes (:empteam) and Status__c=:'Online'];
            }
            return trainingmod;
        }

Now I am displaying this on a page in a repeat 

<apex:repeat var="tm" value="{!trainingmod}" rendered="{!trainingmod.size>0}">
        <table border="0" width="100%">
            <tr>
                <th>Module</th>
                <th>Introduction</th>
            </tr>
            <tr>
                <td width="15%"><apex:outputfield value="{!tm.Name}" /></td>            
                <td colspan="3">{!tm.Introduction__c}</td>           
            </tr>
            <tr>
                <th></th>
                <th>Lesson</th>
                <th>Introduction</th>
            </tr>
            <apex:repeat var="tmsg" value="{!tm.Training_Lessons__r}">
                <tr>
                    <td>&nbsp;</td>
                    <td width="15%"><apex:outputfield value="{!tmsg.Name}" /></td>
                    <td width="55%">{!tmsg.Introduction__c}</td>
                    <td><a href="/apex/TrainingLesson?id={!tmsg.id}"><button type="button">Take Lesson</button></a></td>
                </tr>
            </apex:repeat>

my query is where i have: rendered="{!trainingmod.size>0}" in my apex:repeat

how can i make it only display if training_lesson__r.size>0 i tried rendered="{trainingmod.training_lesson__r.size>0 but get an error

Error: Unknown property 'VisualforceArrayList.training_lesson__r'

any ideas do i have to do this in the apex?

any guidance appreciated.

dan
Best Answer chosen by Daniel B Probert
AshlekhAshlekh
Hi,

You can do this by below code 

First way 

<apex:repeat var="tm" value="{!trainingmod}" rendered="{!trainingmod.size>0}">
   <apex:outPutPanel rendered="{!if(tm.Training_Lessons__r,size()>0)}">
        <table border="0" width="100%">
            <tr>
                <th>Module</th>
                <th>Introduction</th>
            </tr>
            <tr>
                <td width="15%"><apex:outputfield value="{!tm.Name}" /></td>            
                <td colspan="3">{!tm.Introduction__c}</td>           
            </tr>
            <tr>
                <th></th>
                <th>Lesson</th>
                <th>Introduction</th>
            </tr>
            <apex:repeat var="tmsg" value="{!tm.Training_Lessons__r}">
                <tr>
                    <td>&nbsp;</td>
                    <td width="15%"><apex:outputfield value="{!tmsg.Name}" /></td>
                    <td width="55%">{!tmsg.Introduction__c}</td>
                    <td><a href="/apex/TrainingLesson?id={!tmsg.id}"><button type="button">Take Lesson</button></a></td>
                </tr>
	</apex:outputpanel>				
            </apex:repeat>

Second way 

In you controller create a wrapper class and then show by that 

List<Training_Module__c> trainingmod;
List<Training_ModuleClass> trainingmodClass{set;get;}

    public List<Training_Module__c> gettrainingmodnew()
	{
		
        if(trainingmodClass == null) 
		{
			trainingmodClass = new List<Training_ModuleClass>();
			for(Training_Course__c t:   [SELECT id, Name, Introduction__c,(SELECT id, Name, Introduction__c
									FROM Training_Lessons__r WHERE (Applicable_Country__c includes (:empcountry) and Applicable_Teams__c includes (:empteam) and Status__c=:'Online'))
									FROM Training_Module__c WHERE Training_Course__c =:currentpage and Applicable_Country__c includes (:empcountry) and Applicable_Teams__c includes (:empteam) and Status__c=:'Online'])
			{
				trainingmodClass.add(new Training_ModuleClass(t))
			}
				return trainingmod;
        }
	}	
	class Training_ModuleClass
	{
		   public Training_Module__c trainingInstance{set;get;}
		   public List<Training_Lessons__c> ListofTLesson{set;get;}
		   public boolean showBoolean{set;get;}
		   public Training_ModuleClass(Training_Module__c trainingInstance){
		    this.trainingInstance = trainingInstance;
			showBoolean = false;
			if(this.trainingInstance.Training_Lessons__r!= null && this.trainingInstance.Training_Lessons__r.size()>0 )
				showBoolean =true;
				ListofTLesson = this.trainingInstance.Training_Lessons__r;
			}
	}

if use showBoolean property to show the data if ture than show other wise hide

IF it helps you than please mark it as a solution and ENJOY APEX

All Answers

Deepak Kumar ShyoranDeepak Kumar Shyoran
Use child relationship name of lesson__r which might be something like lessons
// I hope training_lessons__r is right chid replationship name
rendered="{trainingmod.training_lessons__r.size>0
If still having exception by using above code then please please confirm your child relationship name for training_lesson__c filed.
AshlekhAshlekh
Hi,

You can do this by below code 

First way 

<apex:repeat var="tm" value="{!trainingmod}" rendered="{!trainingmod.size>0}">
   <apex:outPutPanel rendered="{!if(tm.Training_Lessons__r,size()>0)}">
        <table border="0" width="100%">
            <tr>
                <th>Module</th>
                <th>Introduction</th>
            </tr>
            <tr>
                <td width="15%"><apex:outputfield value="{!tm.Name}" /></td>            
                <td colspan="3">{!tm.Introduction__c}</td>           
            </tr>
            <tr>
                <th></th>
                <th>Lesson</th>
                <th>Introduction</th>
            </tr>
            <apex:repeat var="tmsg" value="{!tm.Training_Lessons__r}">
                <tr>
                    <td>&nbsp;</td>
                    <td width="15%"><apex:outputfield value="{!tmsg.Name}" /></td>
                    <td width="55%">{!tmsg.Introduction__c}</td>
                    <td><a href="/apex/TrainingLesson?id={!tmsg.id}"><button type="button">Take Lesson</button></a></td>
                </tr>
	</apex:outputpanel>				
            </apex:repeat>

Second way 

In you controller create a wrapper class and then show by that 

List<Training_Module__c> trainingmod;
List<Training_ModuleClass> trainingmodClass{set;get;}

    public List<Training_Module__c> gettrainingmodnew()
	{
		
        if(trainingmodClass == null) 
		{
			trainingmodClass = new List<Training_ModuleClass>();
			for(Training_Course__c t:   [SELECT id, Name, Introduction__c,(SELECT id, Name, Introduction__c
									FROM Training_Lessons__r WHERE (Applicable_Country__c includes (:empcountry) and Applicable_Teams__c includes (:empteam) and Status__c=:'Online'))
									FROM Training_Module__c WHERE Training_Course__c =:currentpage and Applicable_Country__c includes (:empcountry) and Applicable_Teams__c includes (:empteam) and Status__c=:'Online'])
			{
				trainingmodClass.add(new Training_ModuleClass(t))
			}
				return trainingmod;
        }
	}	
	class Training_ModuleClass
	{
		   public Training_Module__c trainingInstance{set;get;}
		   public List<Training_Lessons__c> ListofTLesson{set;get;}
		   public boolean showBoolean{set;get;}
		   public Training_ModuleClass(Training_Module__c trainingInstance){
		    this.trainingInstance = trainingInstance;
			showBoolean = false;
			if(this.trainingInstance.Training_Lessons__r!= null && this.trainingInstance.Training_Lessons__r.size()>0 )
				showBoolean =true;
				ListofTLesson = this.trainingInstance.Training_Lessons__r;
			}
	}

if use showBoolean property to show the data if ture than show other wise hide

IF it helps you than please mark it as a solution and ENJOY APEX
AshlekhAshlekh
Hi,

You can do this by below code 

First way 

<apex:repeat var="tm" value="{!trainingmod}" rendered="{!trainingmod.size>0}">
   <apex:outPutPanel rendered="{!if(tm.Training_Lessons__r,size()>0)}">
        <table border="0" width="100%">
            <tr>
                <th>Module</th>
                <th>Introduction</th>
            </tr>
            <tr>
                <td width="15%"><apex:outputfield value="{!tm.Name}" /></td>            
                <td colspan="3">{!tm.Introduction__c}</td>           
            </tr>
            <tr>
                <th></th>
                <th>Lesson</th>
                <th>Introduction</th>
            </tr>
            <apex:repeat var="tmsg" value="{!tm.Training_Lessons__r}">
                <tr>
                    <td>&nbsp;</td>
                    <td width="15%"><apex:outputfield value="{!tmsg.Name}" /></td>
                    <td width="55%">{!tmsg.Introduction__c}</td>
                    <td><a href="/apex/TrainingLesson?id={!tmsg.id}"><button type="button">Take Lesson</button></a></td>
                </tr>
	</apex:outputpanel>				
            </apex:repeat>

Second way 

In you controller create a wrapper class and then show by that 

List<Training_Module__c> trainingmod;
List<Training_ModuleClass> trainingmodClass{set;get;}

    public List<Training_Module__c> gettrainingmodnew()
	{
		
        if(trainingmodClass == null) 
		{
			trainingmodClass = new List<Training_ModuleClass>();
			for(Training_Course__c t:   [SELECT id, Name, Introduction__c,(SELECT id, Name, Introduction__c
									FROM Training_Lessons__r WHERE (Applicable_Country__c includes (:empcountry) and Applicable_Teams__c includes (:empteam) and Status__c=:'Online'))
									FROM Training_Module__c WHERE Training_Course__c =:currentpage and Applicable_Country__c includes (:empcountry) and Applicable_Teams__c includes (:empteam) and Status__c=:'Online'])
			{
				trainingmodClass.add(new Training_ModuleClass(t))
			}
				return trainingmod;
        }
	}	
	class Training_ModuleClass
	{
		   public Training_Module__c trainingInstance{set;get;}
		   public List<Training_Lessons__c> ListofTLesson{set;get;}
		   public boolean showBoolean{set;get;}
		   public Training_ModuleClass(Training_Module__c trainingInstance){
		    this.trainingInstance = trainingInstance;
			showBoolean = false;
			if(this.trainingInstance.Training_Lessons__r!= null && this.trainingInstance.Training_Lessons__r.size()>0 )
				showBoolean =true;
				ListofTLesson = this.trainingInstance.Training_Lessons__r;
			}
	}

if use showBoolean property to show the data if ture than show other wise hide

IF it helps you than please mark it as a solution and ENJOY APEX
This was selected as the best answer
James LoghryJames Loghry
You stated you tried rendered="{trainingmod.training_lesson__r.size>0".  This has two typos according to your example above.  You should be using the variable "tm" not trainingmod and "training_lessons__r" instead of "training_lesson__r".  Simple fixes.

Furthermore, I don't always trust the greater than or less than in rendered attributes.  I've seen some erroneous results with those comparisons.  Instead, I would use the isEmpty method.  For example:  rendered="{!IF(tm.training_lesson__r.empty,false,true)}"  which says "render only if the list is not empty".

Additionally, do you really need to check for whether or not to render the rows in your visualforce page?  I ask this, because if your list is empty, then no rows will be rendered the way your page is currently written.  In otherwords, the rendered attribute is a moot point in your above example.
Daniel B ProbertDaniel B Probert
hi d-horse thanks for the code when i try that i get:

Error: Compile Error: expecting a semi-colon, found '}' at line 27 column 12

so when i add ; on line 27 i now get the error:

Error: Compile Error: Constructor not defined: [TrainingCourseDetailExtension.Training_ModuleClass].<Constructor>(SOBJECT:Training_Course__c) at line 26 column 38

any ideas?