So I am trying to iterate through a list of custom objects and print out the information that I need. The issue is that with this object I cannot guarantee where the information I need is so I made a method in my controller that given the object, it will return a string with the information that I want to print. My problem is trying to combine the repeat, outputText and param components.

Here is the visualforce chunk that I have:

<apex:repeat value="{!relationships}" var="relation">
    <apex:outputText value="{!getOutput}">
        <apex:param value="relation" assignTo="{!relationshipToPrint}" />

and here are the snippits of my apex controller code that are relevant:

public List<Relationship_Detail__c> relationships { get; set; }
public Id recordID { get;set; }
public Relationship_Detail__c relationshipToPrint { get;set; }

public String getOutput(){
    String result = '';
    boolean isPrimary = (relationshipToPrint.First_Contact__c == recordID
            || relationshipToPrint.First_Account__c == recordID);
        if(relationshipToPrint.Second_Contact__c != null){
            result = relationshipToPrint.Second_Contact__r.Name;
            result = relationshipToPrint.Second_Account__r.Name;
        result = result + ' (' + relationshipToPrint.Second_Relationship_Type__r.Name + ')';
        if(relationshipToPrint.First_Contact__c != null){
            result = relationshipToPrint.First_Contact__r.Name;
            result = relationshipToPrint.First_Account__r.Name;
        result = result + ' (' + relationshipToPrint.First_Relationship_Type__r.Name + ')';
    return result;

The function works correctly, however, I am having difficulty passing the current custom object into the relationshipToPrint variable so that it can be used in the method. I hope that this makes some sense and please feel free to ask questions.

  • The usual solution to this is to use a wrapper class. But your solution may work if you change value="relation" to value="{!relation}" so that you are reference the loop var. Also value="{!getOutput}" should probably be value="{!output}" as the "get" part of the name is implied.
    – Keith C
    Jun 16 '14 at 20:55
  • No that doesn't change my output @KeithC. I ran an assert to make sure that relationshipToPrint was not null when I use it in getOutput and it didn't pass. So the param is not setting it before the outputText calls the function Jun 16 '14 at 21:01

The wrapper approach - the normal solution to providing derived values in a table row - would be to return a list of this inner class:

public class Wrapper {
    private MyController c;
    public Relationship_Detail__c sob {get; private set;}
    Wrapper(MyController c, Relationship_Detail__c sob) {
        this.c = c;
        this.sob = sob;
    public String output {
        get {
            Boolean isPrimary = sob.First_Contact__c == c.recordID
                    || sob.First_Account__c == c.recordID;
            if (isPrimary) {
                return (sob.Second_Contact__c != null
                        ? sob.Second_Contact__r.Name
                        : sob.Second_Account__r.Name)
                        + ' (' + sob.Second_Relationship_Type__r.Name + ')';
            } else {
                return (sob.First_Contact__c != null
                        ? sob.First_Contact__r.Name
                        : sob.First_Account__r.Name)
                        + ' (' + sob.First_Relationship_Type__r.Name + ')';

from the list property (wherever that is built):

public List<Wrapper> relationships { get; set; }

so that the Visualforce can just be this:

<apex:repeat value="{!relationships}" var="relation">
    <apex:outputText value="{!relation.output}"/>
  • Looks very straight forward although when I am building the individual wrappers. What am I passing for the MyController? Do I pass it the extension controller and if so how do I do that within the extension? Jun 16 '14 at 21:20
  • Yes you need to change MyController to the class name of your extension and when you create the wrapper use new Wrapper(this, sob) - this will be your controller instance and sob should be one of the queried Relationship_Detail__c objects. Alternatively you could just pass in the recordID in the constructor.
    – Keith C
    Jun 16 '14 at 21:35

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.