0

Hi i have been trying my hand at a custom lookup. So far i have it working perfectly fine, for one object. I am trying to make it as polymorphic as possible. Is there anyway to add columns to the table dynamically? So far i have yet to see anything that would help me. The apex:repeat seems like it would but i am unsure on how to use it. THe documentation doesn't feel suffice on it.

EDIT:

Yeah i am just looking for if you can take data from the controller and feed it to the table on runtime as oppose to having the pageblocktable set up prior to loading the content. Since I am using SObject, it says SObject.Name doesn't exist because of it. I am trying to make it so that this one table will load data for whatever the objectType is.

4
  • 3
    Your question is a bit unclear. Do you need a "polymorphic lookup" similar to the fact OwnerId can point to User or Queue, Activity's WhatId can point to Account or some custom objects? Or is your question about something very specific in a visualforce page you're struggling with? If you want to show all fields on an object in repeat or pageblocktable you should read about "dynamic apex", "describe" operations and maybe fieldsets... What are you trying to achieve?
    – eyescream
    May 5, 2014 at 20:41
  • What table are you speaking of?
    – dphil
    May 5, 2014 at 20:47
  • Sounds like you're asking about three separate things here... May 5, 2014 at 20:52
  • The easiest way to do this, is to have 2 separate lists. 1 list of SObjects, and then another List of Strings which dynamically grabs the fields you need. You can then place an <apex:repeat> (contains list of strings) inside of an <apex:pageBlockTable> (contains your list of SObjects) to dynamically build columns.
    – dphil
    May 6, 2014 at 14:05

1 Answer 1

2

As others have comment what you are asking is not entirely clear. Here are two things you might be asking about...

Lookup fields are presently tied to a specific SObject type. So if you want an SObject to have lookup fields to several SObject types you will have to add multiple lookup fields.

If only one of them is ever populated, with controller code like this:

public with sharing MyController {
    ....
    public CustomObject__c sob {get; private set;}
    public String[] lookupFields {
        get {
            return new String [] {'A__c', 'B__c', 'C__c', 'D__c'};
        }
    }
}

the page can just present the populated field like this:

<apex:repeat values="{!lookupFields}" var="f">
    <apex:inputField value="{!sob[f]}" rendered="{!sob[f] != null}"
</apex:repeat>

The same technique - using field name strings - can be used to present a set of table columns dynamically:

public with sharing MyController {
    ....
    public CustomObject__c[] sobs {get; private set;}
    public String[] columns {
        get {
            return new String [] {'A__c', 'B__c', 'C__c', 'D__c'};
        }
    }
}

with the page containing this:

<apex:pageBlockTable value="{!sobs}" var="sob" >
    <apex:repeat value="{!columns}" var="c">
        <apex:column value="{!sob[c]}"/>
    </apex:repeat>
</apex:pageBlockTable>

PS

Here is a fairly complicated example of conditionally rendering different columns depending on the field name:

<apex:repeat var="f" value="{!fields}">
    <apex:column rendered="{! f == 'Name'}">
        <apex:facet name="header">Return To Work Name</apex:facet>
        <apex:outputLink value="/{!item.Id}?saveURL={!currentPageUrl}">
            {!item.Name}
        </apex:outputLink>
    </apex:column>
    <apex:column rendered="{! f != 'Id' && f != 'Name' && f != 'Attachments__c' && f != 'Earnings__c'
                && f != 'EarningsPerWeek__c' && f != 'EarningsPerMonth__c'}" value="{!item[f]}"/>
    <apex:column rendered="{! f == 'Earnings__c'}" value="{!item.Earnings__c}" headerClass="textalignright" styleClass="textalignright" />
    <apex:column rendered="{! f == 'EarningsPerWeek__c'}" value="{!item.EarningsPerWeek__c}" headerClass="textalignright" styleClass="textalignright"/>
    <apex:column rendered="{! f == 'EarningsPerMonth__c'}" value="{!item.EarningsPerMonth__c}" headerClass="textalignright" styleClass="textalignright"/>
    <apex:column rendered="{! f == 'Attachments__c'}" value="{!item.Attachments__c}" headerClass="textalignright" styleClass="textalignright"/>
</apex:repeat>
3
  • This works great, i am just trying to isolate the first column now because unfortunately it needs a commandlink. Gonna have to find a workaround for that thanks
    – James
    May 6, 2014 at 15:13
  • @James Added a bit of Visualforce from a page I have that uses the field name to decide how to output the field. This allows the controller to put the fields in any order too. Note that for very long tables performance may become a problem as expressions like these in Visualforce are reputed to be relatively slow to evaluate. I haven't seen the problem with say 20 rows in a table.
    – Keith C
    May 6, 2014 at 15:25
  • Thanks the snippet you added was exactly what i needed, Manipulating the rendering helped me separate columns from each other.
    – James
    May 6, 2014 at 17:26

You must log in to answer this question.

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