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:
<apex:page controller="DynamicTableController"> <apex:pageBlock > <apex:form > <apex:actionFunction name="ObjectFileds" action="{!ObjectFields}"/> <apex:commandButton value="Show Table" action="{!ShowTable}"/> <apex:pageBlockSection > <apex:pageBlockSectionItem > <apex:outputLabel value="Select Object"/> <apex:selectList multiselect="false" size="1" value="{!SelectedObject}" onchange="ObjectFileds();"> <apex:selectOption itemLabel="--None--" itemValue="--None--"/> <apex:selectoptions value="{!supportedObject}" /> </apex:selectlist> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputLabel value="Select Field"/> <apex:selectList multiselect="true" size="5" value="{!SelectedFields}"> <apex:selectOption itemLabel="--None--" itemValue="--None--"/> <apex:selectoptions value="{!fieldLableAPI}" /> </apex:selectlist> </apex:pageBlockSectionItem> <apex:pageBlockTable rendered="{!IF(ObjectList.size > 0 , true , false)}" value="{!ObjectList}" var="rec"> <apex:column value="{!rec.Id}" rendered="{!IF(SelectedFields.size == 0 , true, false)}"/> <apex:repeat value="{!SelectedFields}" var="FieldLable"> <apex:column value="{!rec[FieldLable]}" rendered="{!IF(FieldLable != '--None--' , true, false)}"/> </apex:repeat> </apex:pageBlockTable> <apex:outputPanel rendered="{!IF(ObjectList.size < 1 , true , false)}"> <apex:pageMessage severity="ERROR" summary="No records to display"/> </apex:outputPanel> </apex:pageBlockSection> </apex:form> </apex:pageBlock> </apex:page>
Apex Code (Class):
public class DynamicTableController { //List displayed on UI public List<selectoption> supportedObject {get; set;} //Selected Object public String SelectedObject {get; set;} //Global describe Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe(); Set<String> objectKeys = gd.keySet(); //Field Select List public List<SelectOption> fieldLableAPI {get; set;} //Selected fields to be displayed in table public List<String> SelectedFields {get; set;} //List to maintain dynamic query result public List<sObject> ObjectList {get; set;} //Constructor public DynamicTableController() { //Initialize supportedObject = new List<selectoption>() ; SelectedObject = '' ; fieldLableAPI = new List<SelectOption>() ; SelectedFields = new List<String>() ; ObjectList = new List<sObject>() ; //Get only reference to objects for(Schema.SObjectType item : ProcessInstance.TargetObjectId.getDescribe().getReferenceTo()) { //Excluding custom setting objects if(!item.getDescribe().CustomSetting) { //Adding to list supportedObject.add(new SelectOption(item.getDescribe().getLocalName().toLowerCase() , item.getDescribe().getLabel() )); } } } //Get fields of selected object public void ObjectFields() { if(SelectedObject != '--None--') { //Creating sObject for dynamic selected object Schema.SObjectType systemObjectType = gd.get(SelectedObject); //Fetching field results Schema.DescribeSObjectResult r = systemObjectType.getDescribe(); Map<String, Schema.SObjectField> M = r.fields.getMap(); //Creating picklist of fields for(Schema.SObjectField fieldAPI : M.values()) { fieldLableAPI.add(new SelectOption(fieldAPI.getDescribe().getName() , fieldAPI.getDescribe().getLabel())) ; } } } public void ShowTable() { //Creating dynamic query with selected field String myQuery = 'Select Id ' ; for(String field : SelectedFields) { if(field.toLowerCase() != 'id' && field.toLowerCase() != '--none--') myQuery += ','+ field + ' ' ; } //Limit is 100 for now you can change it according to need myQuery += ' from ' + SelectedObject + ' LIMIT 100' ; //Executing the query and fetching results ObjectList = Database.query(myQuery) ; } }
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..
Nice - I like the use of rendered="{!IF(ObjectList.size > 0 , true , false)}"
ReplyDeleteThank you so much Pat :-)
DeleteWhile selecting the object for first time it is displaying the corresponding fields, but the if a user changes the object the corresponding object field is not displayed.
ReplyDeleteWhat a concept Ankit.... Very Dynamic...
ReplyDeleteThats awesome. Thank You..
ReplyDeleteNice.
ReplyDeleteShould have
fieldLableAPI.clear();
at line 51, so the list of fields will changed after changing the selected object.
it is very useful promt!
DeleteAdd this line below line no :48
ReplyDeletefieldLableAPI = new List() ;
Thanks for your post, Information related to salesforce help are really helpful to resolve our queries.
ReplyDeleteHi
ReplyDeleteI want to store the selected data permanently but after refresh it going to original stage how to overcome this .please guide me
This comment has been removed by the author.
ReplyDeleteHi ForceGuru,
ReplyDeleteThankyou for the code and there is an error in apex code at line 32,
If I kept in comments it runs and to output just a design output...
a link of the screenshot
https://drive.google.com/file/d/0B7KNbYxZdMfMOE4yQTQtb0otTms/edit?usp=sharing
HI getting following error for custom objects
ReplyDeleteVisualforce Error
Help for this Page
System.NullPointerException: Attempt to de-reference a null object
Error is in expression '{!ObjectFields}' in page yeruva_sudha:pbtabledyncolumns
Class.yeruva_sudha.DynamicTableController.ObjectFields: line 56, column 1
hiii for the program mentioned, am getting some error like " Missing required attribute value in in atch at line 25 column 13"
ReplyDeleteI am getting insufficient privileges error where as i am the admin and have access to all objects and records. also i have used with Public. Still i am getting this error.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThank you it helped me :) :)
ReplyDeleteUnsupported type common.api.soap.wsdl.Address encountered.
ReplyDeleteI would like to say thanks for sharing the best information.. Web Development Company in Bangalore | Best Web Design Company in Bangalore | Web Development Company in Bangalore
ReplyDeleteI am Appreciating & Thanking you for a wonderful article. Thanks a lot.
ReplyDeletehttps://araseefoods.com/
Good tasty and healthy food products in Erode and Coimbatore
Food product manufacturers in Erode and Coimbatore
Food product Suppliers in Erode and Coimbatore
Cheap and Best Food products in Erode and Coimbatore
Baji mix flour product Manufacturers in Erode and Coimbatore
Corn flour product Manufacturers in Erode and Coimbatore
Flattened Rice product Manufacturers in Erode and Coimbatore
Gram Flour product Manufacturers in Erode and Coimbatore
Karumbu sakkarai product Manufacturers in Erode and Coimbatore
Maida Flour product Manufacturers in Erode and Coimbatore
Pottu kadalai Flour product Manufacturers in Erode and Coimbatore
Ragi Flour product Manufacturers in Erode and Coimbatore
Rava Manufacturers in Erode and Coimbatore
Semiya Manufacturers in Erode and Coimbatore
Atta Manufacturers in Erode and Coimbatore
Wheat Rava Manufacturers in Erode and Coimbatore
Thank you for excellent article.You made an article that is interesting.
ReplyDeleteBest AWS certification training courses. Build your AWS cloud skills with expert instructor- led classes. Live projects, Hands-on training,24/7 support.
https://onlineidealab.com/aws-certification/
Best Logo Designer in Coimbatore
ReplyDeleteWeb Designers in Coimbatore
Packaging design in coimbatore
Graphic Designers in Coimbatore
Logo Designer in Coimbatore
Logo Design in Coimbatore
Logo Design company in Coimbatore
Logo Design agency in Coimbatore
Logo Design studio in Coimbatore
Best and Quality Graphic designers in Coimbatore
Brochure Designing Company in Coimbatore
Business promotion Company in Coimbatore