You need to sign in to do that
Don't have an account?

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>
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>
<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>
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!
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; }