8

I am not sure how to word the question; I apologize if the title is not relevant to my problem.

Please pretend the following three classes are inner classes in a controller.

I have a base class with the following characteristics:

abstract class Form {
    public List<Object> objects {get; set;}
    public virtual List<Object> fetchObjects() {};
}

Here is the wrapper class for an sObject:

class Program {
    public Program__c program {get; set;}
    public Program(Program__c program) { this.program = program; }
}

Here is a class that extends the base class

class ProgramForm extends Form {
    public ProgramForm() { objects = fetchObjects(); }
    public override List<Object> fetchObjects() {
        List<Program> programs = new List<Program>();
        for (Program__c p : [select id, name from Program__c]) {
            programs.add(new Program(p));
        }
        return programs;
    }
}

Now, in the visual force,

<apex:dataTable value="{!programForm.objects}" var="program">
    <apex:column> {!program.program['name']} </apex:column>
</apex:dataTable>

throws the following error: Unknown property 'Object.program'

If I remove List<Object> objects member and List<Object> fetchObjects method from the abstract Form class and insert a List<Program> member and List<Program> fetchObjects method in the extended ProgramForm class, I get the desired functionality. This is what I have done but I would rather not for obvious reasons.

How can I tell the visualforce to ignore the datatype and assume it has the appropriate members?

Thank you!

2
  • Have you tried {!program['program']['name']}?
    – jkraybill
    Jun 3, 2013 at 0:16
  • @jkraybill thank you!! In retrospect I'm shocked I didn't think of that .... Post an answer and I'll award it to you. Thanks!!! Jun 4, 2013 at 1:35

4 Answers 4

8

Per my comment, you don't want typed dot-accessors, you want untyped map accessors (https://www.salesforce.com/us/developer/docs/pages/Content/pages_dynamic_vf.htm). i.e.:

{!program['program']['name']}

You also need the return statement per Andre's comment, but it seems that you do already have that.

0

I haven't tried this - but the first thing I would try is to change the var= term to something other than "program". It might just be getting confused by the reuse of the variable name.

0

Your fetchObjects() method is not returning anything. Thus, the objects = fetchObjects(); attribuition is not working. Your code should work as follows:

class ProgramForm extends Form {
  public ProgramForm() {
  objects = fetchObjects();
  public override List<Object> fetchObjects() {
    List<Program> programs = new List<Program>();
    for (Program__c p : [select id, name from Program__c]) {
        programs.add(new Program(p));
    }
    return (List<Object>)programs;
  }
}
1
  • My apologies; I left the return statement (as well as the final } in the constructor statement) out on accident when I wrote it here -- edited. Jun 4, 2013 at 1:34
0

You should be able to make this scenario work using Dynamic Visualforce. It is typically employed when you do not know the object type which you are going to be using when building the VF markup.

Your scenario would have a method on the controller which would have a return type of Component.Apex.Datatable and the code within that method would build the structure of the datatable based on the data which you are going to display within it. For this conversation we will call this method getMyDataTable().

The Visualforce page would then include an <apex:dynamicComponent componentValue="{!MyDatatable}" /> tag within its markup where you would like this datatable to be rendered.

A couple of documents on the topic:

You must log in to answer this question.

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