Wednesday, 29 October 2014

Page Block Table With Dynamic Columns In Salesforce

This is something extensively used, but every time I need to look for some easy code.

So here is the solution (apologies as I've not covered the negative cases in code, and I hope you all are smart enough to take care of that). Requirement is to build the dynamic page block table with dynamic columns, but this is not it. It should be so dynamic that user can select the object and it's fields by himself and nothing should be hard-coded. So first of all I've provided a picklist with all objects (not all objects... why? Take a look at it Please Remove The System Objects From My sObject List)

Visualforce Page Code:
 
  1. <apex:page controller="DynamicTableController">  
  2. <apex:pageBlock >  
  3.     <apex:form >  
  4.         <apex:actionFunction name="ObjectFileds" action="{!ObjectFields}"/>  
  5.           
  6.         <apex:commandButton  value="Show Table" action="{!ShowTable}"/>  
  7.           
  8.         <apex:pageBlockSection >  
  9.             <apex:pageBlockSectionItem >  
  10.                 <apex:outputLabel value="Select Object"/>  
  11.                 <apex:selectList multiselect="false" size="1" value="{!SelectedObject}" onchange="ObjectFileds();">  
  12.                     <apex:selectOption itemLabel="--None--" itemValue="--None--"/>  
  13.                     <apex:selectoptions value="{!supportedObject}" />  
  14.                 </apex:selectlist>  
  15.             </apex:pageBlockSectionItem>  
  16.               
  17.             <apex:pageBlockSectionItem >  
  18.                 <apex:outputLabel value="Select Field"/>  
  19.                 <apex:selectList multiselect="true" size="5" value="{!SelectedFields}">  
  20.                     <apex:selectOption itemLabel="--None--" itemValue="--None--"/>  
  21.                     <apex:selectoptions value="{!fieldLableAPI}" />  
  22.                 </apex:selectlist>  
  23.             </apex:pageBlockSectionItem>  
  24.               
  25.             <apex:pageBlockTable rendered="{!IF(ObjectList.size > 0 , true , false)}" value="{!ObjectList}" var="rec">  
  26.                 <apex:column value="{!rec.Id}" rendered="{!IF(SelectedFields.size == 0 , true, false)}"/>  
  27.                 <apex:repeat value="{!SelectedFields}" var="FieldLable">  
  28.                     <apex:column value="{!rec[FieldLable]}" rendered="{!IF(FieldLable != '--None--' , true, false)}"/>  
  29.                 </apex:repeat>  
  30.             </apex:pageBlockTable>  
  31.               
  32.             <apex:outputPanel rendered="{!IF(ObjectList.size < 1 , true , false)}">  
  33.                 <apex:pageMessage severity="ERROR" summary="No records to display"/>  
  34.             </apex:outputPanel>  
  35.               
  36.         </apex:pageBlockSection>  
  37.           
  38.     </apex:form>  
  39. </apex:pageBlock>  
  40. </apex:page>  


Apex Code (Class):
 
  1. public class DynamicTableController  
  2. {  
  3.     //List displayed on UI  
  4.     public List<selectoption> supportedObject {get; set;}  
  5.       
  6.     //Selected Object  
  7.     public String SelectedObject {get; set;}  
  8.       
  9.     //Global describe  
  10.     Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();  
  11.     Set<String> objectKeys = gd.keySet();  
  12.       
  13.     //Field Select List  
  14.     public List<SelectOption> fieldLableAPI {get; set;}  
  15.       
  16.     //Selected fields to be displayed in table  
  17.     public List<String> SelectedFields {get; set;}  
  18.       
  19.     //List to maintain dynamic query result  
  20.     public List<sObject> ObjectList {get; set;}  
  21.       
  22.       
  23.     //Constructor  
  24.     public DynamicTableController()  
  25.     {  
  26.         //Initialize  
  27.         supportedObject = new List<selectoption>() ;  
  28.         SelectedObject = '' ;  
  29.         fieldLableAPI = new List<SelectOption>() ;  
  30.         SelectedFields = new List<String>() ;  
  31.         ObjectList = new List<sObject>() ;  
  32.           
  33.         //Get only reference to objects  
  34.         for(Schema.SObjectType item : ProcessInstance.TargetObjectId.getDescribe().getReferenceTo())  
  35.         {  
  36.             //Excluding custom setting objects  
  37.             if(!item.getDescribe().CustomSetting)  
  38.             {  
  39.                 //Adding to list  
  40.                 supportedObject.add(new SelectOption(item.getDescribe().getLocalName().toLowerCase() , item.getDescribe().getLabel() ));  
  41.             }  
  42.         }  
  43.           
  44.     }  
  45.       
  46.     //Get fields of selected object  
  47.     public void ObjectFields()  
  48.     {  
  49.         if(SelectedObject != '--None--')  
  50.         {  
  51.             //Creating sObject for dynamic selected object  
  52.             Schema.SObjectType systemObjectType = gd.get(SelectedObject);  
  53.             //Fetching field results  
  54.             Schema.DescribeSObjectResult r = systemObjectType.getDescribe();  
  55.                   
  56.             Map<String, Schema.SObjectField> M = r.fields.getMap();  
  57.             //Creating picklist of fields  
  58.             for(Schema.SObjectField fieldAPI : M.values())  
  59.             {  
  60.                 fieldLableAPI.add(new SelectOption(fieldAPI.getDescribe().getName() , fieldAPI.getDescribe().getLabel())) ;  
  61.             }  
  62.         }  
  63.     }  
  64.       
  65.     public void ShowTable()  
  66.     {  
  67.         //Creating dynamic query with selected field  
  68.         String myQuery = 'Select Id ' ;  
  69.           
  70.         for(String field : SelectedFields)  
  71.         {  
  72.             if(field.toLowerCase() != 'id' && field.toLowerCase() != '--none--')  
  73.             myQuery += ','+ field + ' ' ;  
  74.         }  
  75.           
  76.         //Limit is 100 for now you can change it according to need  
  77.         myQuery += ' from ' + SelectedObject + ' LIMIT 100' ;  
  78.           
  79.         //Executing the query and fetching results  
  80.         ObjectList = Database.query(myQuery) ;  
  81.     }  
  82. }  

Once user selects any object from the first picklist, filed picklist will be populated with all the field labels related to that object. Note, it's a multi-select picklist so user can select multiple fields. Once fields are selected and "Show Table" is clicked, page block table will display the field values (selected in field picklist) of all records (limit is 100 right now, you can change it according to your need).

There are some extra checks that needs to be implemented in code like "isQueryable" etc..

No comments:

Post a Comment