Tweet |
One issue that crops up repeatedly on the SalesForce Developer Discussion Boards is how to rotate a table. E.g. if I have a table that displays account information one account per row:
how can I rotate this to display one account per column:
First, to create a class to model the data that is being passed back to the
page. In this case the class wraps a row of data, thus row 1 contains the name
of each account, row2 contains the street address etc.
As each cell in the table is a text field, our class can simply wrap a list of
String primitives. The class implementation is shown below:
public class RowWrapper { // the values (cells) making up this row public List<String> values {get; set;} // constructor public RowWrapper() { values=new List<String>(); } // append a value (cell) to the row public void addValue(String value) { values.add(value); } }
The next step is to write an extension to the Account standard controller that transforms a list of Accounts into a list of RowWrapper classes.
// retrieves the list of accounts backing the page public List<Account> getAccounts() { if (null==accs) { accs=[select id, Name, BillingStreet, BillingCity, BillingPostalCode from Account where BillingCity != null and BillingPostalCode!=null limit 3]; } return accs; } // retrieves the list of row wrappers public List<RowWrapper> getRowWrappers() { if (null==rows) { rows=new List<RowWrapper>(); // create a row for each field - there are 4 of these, Name, Street, City and PostCode for (Integer idx=0; idx<4; idx++) { rows.add(new RowWrapper()); } // iterate the accounts and populate the rows for (Integer idx=0; idx<getAccounts().size(); idx++) { rows[0].addValue(getAccounts()[idx].Name); rows[1].addValue(getAccounts()[idx].BillingStreet); rows[2].addValue(getAccounts()[idx].BillingCity); rows[3].addValue(getAccounts()[idx].BillingPostalCode); } } return rows; }
The final step is to create a VisualForce page to iterate the RowWrapper list
and output the table:
<table class="list" border="0" cellpadding="0" cellspacing="0"> <tr class="headerRow "> <apex:repeat value="{!headWrap.values}" var="heading"> <th class="headerRow "> {!heading} </th> </apex:repeat> </tr> <apex:repeat value="{!rowWrappers}" var="row"> <tr> <apex:repeat value="{!row.values}" var="value"> <td> {!value} </td> </apex:repeat> </tr> </apex:repeat> </table>
The page and controller can be downloaded here. Simply unzip into the src directory of your Force.com project in the IDE.
great Bob - neat
ReplyDeleteBob, Great A+ stuff as usual. You are truly an asset to the SFDC development community.
ReplyDeleteThanks again for your time in both developing and posting this.
Hi Bob, your code was helpful for beginner like me. Wanted to know if it is possible to make this grid editable and add update logic on this. If possible, can you provide some pointers on how to do that. in my case i have 3 columns, 1 column displays data in account within salesforce, second and third column displays similar data extracted from 2 external systems. Client is using the page to compare values in 3 different systems. I have got the logic working based on your code above. But wanted to know if i get a requirement to update the columns, how would i do it.
ReplyDeleteThanks,
Arvin
Basically you'd turn the markup that outputs the values - {!value}, into apex:inputText tags. One problem would be that as the RowWrapper just contains a list of strings, you wouldn't get the enhanced functionality that you would with inputfields (e.g. date picker, lookup etc).
DeleteThanks Bob. I got it working.
DeleteHi Bob.. Possible to add an additional column in the first position to label the rows and identify the values? You did not rotate the header row.
ReplyDeleteHi,
ReplyDeleteActually my object is like String strtemp='Mahesh__'+strFieldName+'__c';
How to use this like as object in my apex class?
Please help me......
Hi Bob,
ReplyDeleteWhat if I don't want to change the type of data to string. Is that possible with wrapper class. I want to display Date and status(of type checkbox) horizontally.
Thank you Bob
ReplyDeleteSo what the heck is headWrap or did you mean to write headWarp? I ask because it's a bit of a headwarp to get your headwrap
ReplyDeleteNow I "get" it
ReplyDeleteHi Bob,
ReplyDeleteI was wondering if you can help me. I have a requirement to create a grid table. I have a custom object that has 3 fields. Year, Product type and Status. I would like a grid table with Year being header and Product as row header with status editable for each product type for each year. Only 5 years will show up and only 5 product type will show up on the grid. No duplicate product type for the same year exist but there are records for different years.
How I can display in multiple page block table depend upone criteria that to be rendered.help!!
ReplyDeleteThanks Bob, it helped :)
ReplyDeletetanx
ReplyDelete