I have a map of String(key) and Wrapper object(value) called TableView. The TableView has public property of list of a wrapper class object called DataViewRow.
The DataView wrapper class has a map of column names and their values (Map of String to Object).
I try to render the columns dynamically based on the Map inside the DataViewRow wrapper object but the headers are not displayed in this case.
It looks like this in the visualforce page:
<apex:pageblocktable value="{!map_tableToData['Adjustments'].Rows}" var="row">
<apex:repeat value="{!row.Values}" var="col">
<apex:column headervalue="{!col}">
{!row.Values[col]}
</apex:column>
</apex:repeat>
</apex:pageblocktable>
TableView class:
public class TableView
{
public TableView(List<DataViewRow> rows)
{
this.Rows = rows;
}
public List<DataViewRow> Rows { get; set; }
}
DataViewRow class:
public virtual class DataViewRow
{
protected DataViewRow() { }
public DataViewRow(List<String> lst_columns, String title)
{
//Intialize a new map.
this.Values = new Map<String,Object>();
for (String columnName : lst_columns)
{
this.Values.put(columnName, null);
}
this.Title = title;
}
public String Title { get; set; }
public Map<String,Object> Values { get; set; }
public Set<String> ColumnNames
{
get
{
return this.Values.keySet();
}
}
public virtual Boolean IsEmptyData()
{
return false;
}
}
The values in the map are populated correctly. I've tried to render the column names in the column value and the values are as expected, but the headers are not displayed at all.
I would appreciate your help.
UPDATE:
It seems that there is a problem binding the map in the repeat and use its key inside the headerValue attribute of the column. I've assigned map_tableToData['Adjustments'].Rows[0].Values.keySet()
to a different property in the controller because it is the same for all the rows in my case.
I would be happy to get any better solution.
Best Answer
Can confirm - you will not get the headers from the Map keys when using the
<apex:repeat>
tag to auto-generate columns from aList<Map>
structure.I have tried it with
<apex:facet>
tags, on both the table and the column; I have tried it with various formulas in thevalue=""
andvar=""
attributes of the<apex:repeat>
tag; I've even tried giving all the headers the same fixed value:<apex:column headervalue="Fred>
. The headers just don't display.This makes sense if you think about it - there is no guarantee that every Map in a
List<Map>
structure will have the same keys, so how does VF know which ones to use as the headers? To get around this, you will have to provide your own headers in a separate property of the VF page controller. These can be the actual keys fromList<Map>[0]
or whatever others you might choose.Sample code is below for situation where I use the first row's key values as the headers.
Relevant controller code:
Relevant page tags:
You could also create a second
Map<string,string>
to obtain custom headers for your columns. The relevant code for that would be:and
Hope this helps!
Doug