function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
MarkL.ax269MarkL.ax269 

dynamic tables

I've searched a lot of similar posts but can't come up with the solution I need.  I need to present a table to the user where the number of columns and rows is unknown until runtime.  I could create something that has all potential columns and just render them based on content, but there are potentially hundreds of possible columns and that number can grow - typically there are only a dozen or so that should be displayed.  I can almost get there with something like below, but <apex:Repeat> won't take a param, and what I end up with is repeating ALL records on every row, rather than just the values for that record.  Any idea how I can tackle this?

 

<apex:outputPanel id="cPanel">
<table>
<tr>
<th>Contact</th>
<apex:Repeat value="{!taskSubjects}" var="subject">
<th><apex:outputText value="{!subject}"/></th>
</apex:Repeat>
</tr>
<apex:Repeat value="{!contacts}" var="contact">
<tr>
<td><apex:outputText value="{!contact.Name}"/></td>
<apex:Repeat value="{!cTasks}" var="ct">
<apex:param name="cid" value="{!ct.WhoId}"/>
<td><apex:outputText value="{!ct.ActivityDate}"/></td>
</apex:Repeat>
</tr>
</apex:Repeat>
</table>
</apex:outputPanel>

 

 

 

Message Edited by MarkL on 02-26-2009 09:24 AM
Message Edited by MarkL on 02-26-2009 09:26 AM
MarkL.ax269MarkL.ax269

Very close.  Changing the nested repeat tag works in that now it only displays that row's content.  Problem is the TD tags are rendered no matter what, so I end up with infilled blank cells if the text isn't rendered and the data is pushed outside the table headers.

 

<apex:Repeat value="{!cTasks}" var="ct">
<td><apex:outputText value="{!ct.ActivityDate}" rendered="{!If(ct.WhoId=contact.Id,'true','false')}"/></td>
</apex:Repeat>

 

 What I really need is something like one of these.  The first doesn't work because tags aren't allowed in the value attribute, the second doesn't exist, and for some reason the repeat breaks if there's an outputPanel inside it.

<apex:outputText value="<td>{!ct.ActivityDate}</td>" rendered="{!If(ct.WhoId=contact.Id,'true','false')}"/>

<apex:outputHtml value="<td>"/>
<apex:outputText value="{!ct.ActivityDate}" rendered="{!If(ct.WhoId=contact.Id,'true','false')}"/>
<apex:outputHtml value="</td>"/>

<apex:outputPanel rendered="{!If(ct.WhoId=contact.Id,'true','false')}">
<td><apex:outputText value="{!ct.ActivityDate}"/></td>
</apex:outputPanel>

 


 


 

Message Edited by MarkL on 02-26-2009 10:30 AM
Message Edited by MarkL on 02-26-2009 10:34 AM
Ron HessRon Hess

When I need this type of control, I normally write a wrapper class and create a method that returns the innerHTML that I want.

 

it's a bit clumsy and inelegant, but here goes:

 

 

public class wrap_task { Task tsk { get; set; } String formatedRow { get; private set; } public wrap_task( Task t) { tsk = t; formatedRow = '<tr><td>'+tsk.ActivityDate+'</td></tr>'; } }

 

Now, in VF you can do this

 

 

<table><tbody><apex:Repeat value="{!wrap_Tasks}" var="wt"> {!wt.formatedRow} </apex:Repeat></tbody></table>

 

 

if there is a better way, please post your solution!

 

 

MarkL.ax269MarkL.ax269

Great suggestion!  And it sure seems like it should work, but for some reason I can't get the cells rendered.  I verified that the Repeat is calling my getter method, and the objects returned all contain the expected values encapsulated in TD tags.  But for some reason all I'm getting is a blank table.  All the header columns are there and all the appropriate rows, but the data cells are not even rendered.

VF Page: <table border="1"> <tr> <th>Contact</th> <apex:Repeat value="{!taskSubjects}" var="subject"> <th><apex:outputText value="{!subject}"/></th> </apex:Repeat> </tr> <apex:Repeat value="{!contacts}" var="contact"> <tr> <td><apex:outputText value="{!contact.Name}"/></td> <apex:Repeat value="{!wrap_tasks}" var="wt"> {!wt.value} </apex:Repeat> </tr> </apex:Repeat> </table> Class and getter method: public class wrap_task { public Task theTask { get; private set; } public String value { get; private set; } public wrap_task(Task t) { theTask = t; value = '<td>' + theTask.ActivityDate + '</td>'; } } public list<wrap_task> getwrap_tasks() { for (wrap_task wt : this.wrap_tasks) { System.debug(wt.value); } return this.wrap_tasks; }