function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Surya.236Surya.236 

How to create a dynamic data table in salesforce. with dynamic table header??

Khan AnasKhan Anas (Salesforce Developers) 
Hi,

Greetings to you!

Below is the sample code to display a dynamic table, which I have tested in my org and it is working fine. Kindly modify the code as per your requirement.

1. LIGHTNING CODE:

Application:
<aura:application extends="force:slds">
    <c:SchemaRecord_Task />
</aura:application>

Component:
<aura:component controller="SchemaRecord_TaskSvrController"
                implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" 
                access="global" >
    
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    
    <aura:attribute name="PageHeading" type="String" default="Schema Class In Lightning to Query all Objects"/>
    <aura:attribute name="pickl" type="List" />
    <aura:attribute name="selectedValue" type="String" />
    
    <div class="slds-m-top--xx-large">
        <div class="slds-page-header">
            <div class="slds-align--absolute-center">
                <div class="slds-text-heading--large">       
                    {!v.PageHeading}
                </div>
            </div>
        </div>
    </div>
    <br/> <br/>
    
    <div class = "slds-size--3-of-8">
        <lightning:select aura:id="selectid" label="Select Object" name="obj" value="{!v.selectedValue}">
            <option value="" text="- None -" />
            <aura:iteration items="{!v.pickl}" var="per">
                <option value="{!per}" text="{!per}" />
            </aura:iteration>
        </lightning:select>
        <br/>
        <lightning:button label="Search" onclick="{!c.doSearch}"/>
    </div>
    <br/>
    
    <!-- division that will show the dynamic content --> 
    <div class="slds-scrollable_x"> 
        <table class="slds-table slds-table--bordered slds-max-medium-table--stacked-horizontal slds-table_col-bordered">
            <tbody id='sfdctable' />
        </table>
    </div>
    
</aura:component>

Controller:
({
	doInit : function(component, event, helper) {
        var action = component.get("c.objectNames");
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {           
                var allValues = response.getReturnValue();
                component.set("v.pickl", allValues);
            }        	         
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                 errors[0].message);
                    }
                } 
                else {
                    console.log("Unknown Error");
                }
            }
        });
        $A.enqueueAction(action);
	},
    
    doSearch : function(component, event, helper) {
        var pickselected = component.find("selectid").get("v.value");
        console.log('pickselected--->' + pickselected);
		component.set('v.selectedValue', pickselected);
        var selected = component.get('v.selectedValue');
        console.log('Selected--->' + selected);
        var action = component.get("c.objectRecords");
        action.setParams({selectedObject : selected});
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {  
                //component.find('sfdcDiv').set("v.body",[]);
                var allValues = response.getReturnValue();
            	console.log('allValues--->' + allValues);
                var objectValue = allValues.sObjectData;
                console.log('objectValue--->' + objectValue);
                var fieldList = allValues.fieldList;
                console.log('fieldList--->' + fieldList);
                
                /* Create Dynamic Table */
                var sObjectDataTableHeader = [];
                // Create table Header
                for (var i=0; i<fieldList.length; i++) {
                	sObjectDataTableHeader.push(fieldList[i].label);
                }
                console.log('sObjectDataTableHeader--->>' + sObjectDataTableHeader);
                //Get the count of columns.
                var columnCount = sObjectDataTableHeader.length;
                //Create a HTML Table element.
                var table = document.createElement("TABLE");
                //table.border='2';
                //Add the header row.
                var row = table.insertRow(-1);
                for (var i=0; i<columnCount; i++) {
                	var headerCell = document.createElement("TH");
                    //headerCell.width='75';
                    headerCell.innerHTML = sObjectDataTableHeader[i];
                    headerCell.className='headerClass';
                    row.appendChild(headerCell);
                }
                var dvTable = document.getElementById("sfdctable");
                dvTable.innerHTML = "";
                dvTable.appendChild(table);
                
                /* Create Dynamic Table End */    
                if(objectValue.length){
                	for(var j=0; j<objectValue.length; j++){
                    	// Dynamic table Row
                        row = table.insertRow(-1);
                        // Dynamic Table Row End
                        for (var i=0; i<fieldList.length; i++) {
                        	// Dynamic table Row
                            var cell = row.insertCell(-1);
                            cell.innerHTML = objectValue[j][fieldList[i].apiName]; 
                        }
                    }
                }
            }        	         
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                 errors[0].message);
                    }
                } 
                else {
                    console.log("Unknown Error");
                }
            }
        });
        $A.enqueueAction(action);
    }
})

CSS:
.THIS {
}

.THIS.slds-size--3-of-8 {
    margin-left: 475px;
}

.THIS.headerClass {
    width: 200px;
}

Apex:
public class SchemaRecord_TaskSvrController {
	
    @AuraEnabled
    public static List<String> objectNames(){
        List<Schema.SObjectType> gd = Schema.getGlobalDescribe().Values();    
        List<String> options = new List<String>();
        for(SObjectType f : gd){
            options.add(f.getDescribe().getName());
            options.sort();        
        }
        return options;
    }
    
    @AuraEnabled
    public static DynamicBindingWrapper objectRecords(String selectedObject){
        DynamicBindingWrapper dynamicData = new DynamicBindingWrapper();
        List<fieldDataWrapper> wrapperList =  new List<fieldDataWrapper>();
        List<String> fields = new List<String>();
        Map<String , Schema.SObjectType> globalDescription = Schema.getGlobalDescribe();
        Schema.sObjectType objType = globalDescription.get(selectedObject); 
        Schema.DescribeSObjectResult r1 = objType.getDescribe(); 
        
        Map<String , Schema.SObjectField> mapFieldList = r1.fields.getMap();  

        for(Schema.SObjectField field : mapFieldList.values())  {  
            Schema.DescribeFieldResult fieldResult = field.getDescribe();  
            
            if(fieldResult.isAccessible())  {  
                fields.add(fieldResult.getName());
            }
            fieldDataWrapper wrapper = new fieldDataWrapper();
            wrapper.label = field.getDescribe().getLabel();
            wrapper.apiName = field.getDescribe().getName();
            wrapperList.add(wrapper);
        }
        Integer i = 0;
        String fieldsToFetch = '';
        for(String temp:fields){       
            Integer len = fields.size();
            if(i==len-1){
                  fieldsToFetch = fieldsToFetch + temp;
            }
            else{
                  fieldsToFetch = fieldsToFetch + temp + ',';
            }
            i++;
        }
        String sql = ' SELECT ' + fieldsToFetch + ' FROM ' + selectedObject + ' ORDER BY CreatedDate DESC LIMIT 5';
        List<Sobject> objRecords = new List<Sobject>();
        objRecords = Database.Query(sql);
        System.debug('objRecords--->' + objRecords);
        if(objRecords!=null && objRecords.size()>0){
        	dynamicData.sObjectData = objRecords;
        }
        else{
            dynamicData.sObjectData = new List<sObject>();
        }
        dynamicData.fieldList = wrapperList;
        System.debug('dynamicData.sObjectData--->' + dynamicData.sObjectData);
        System.debug('dynamicData.fieldList--->' + dynamicData.fieldList);
        System.debug('dynamicData--->' + dynamicData);
        return dynamicData;
        } 
    
    //Class to store the dynamic data and list of related fields
    public class DynamicBindingWrapper{
        @AuraEnabled
        public List<sObject> sObjectData {get; set;}
        @AuraEnabled
        public List<fieldDataWrapper> fieldList {get; set;}
    }
    
    //Class to store the field information
    public class fieldDataWrapper{
        @AuraEnabled
        public String label {get; set;}
        @AuraEnabled
        public String apiName {get; set;}
    }
}


2. VISUALFORCE CODE:

Visualforce:
<apex:page controller="ObjectPicklistController1">
  <apex:form >
     <apex:pageBlock > 
     <apex:pagemessages />
         <apex:pageBlockSection >
              <apex:outputLabel value="Object Names :"/>
              <apex:selectList value="{!selectedObject}" size="1">
                  <apex:selectOption itemLabel="--None--" itemValue="--None--"/>
                  <apex:selectOptions value="{!objectNames}"/>
              </apex:selectList>
         </apex:pageBlockSection>
         <apex:pageblockButtons >
             <apex:commandButton value="Fetch Records" action="{!fetchFields}" reRender="flds"/>
         </apex:pageblockButtons>
    </apex:pageBlock>
    <apex:pageblock id="flds" title="Last 5 Records">
    <apex:pagemessages />
        <apex:pageblockTable value="{!objFields}" var="fd">
            <apex:repeat value="{!result}" var="res">
                <apex:column value="{!fd[res]}" />
            </apex:repeat>
        </apex:pageblockTable>
    </apex:pageblock>    
  </apex:form>
</apex:page>

Controller:
public class ObjectPicklistController1 {

    public String selectedObject {get;set;}
    public List<sObject> objFields {get;set;} 
    public List<String> result {get;set;}
    
    public ObjectPicklistController1(){ 
        selectedObject = 'none';
    }
    
    public List<SelectOption> getobjectNames(){
        List<Schema.SObjectType> gd = Schema.getGlobalDescribe().Values();    
        List<SelectOption> options = new List<SelectOption>();
        for(Schema.SObjectType f : gd){
            options.add(new SelectOption(f.getDescribe().getName(),f.getDescribe().getName()));
            options.sort();        
        }
        return options;
    }
  
    public void fetchFields(){ 
        result = new List<String>();
        Map<String , Schema.SObjectType> globalDescription = Schema.getGlobalDescribe();
        Schema.sObjectType objType = globalDescription.get(selectedObject);   
        Schema.DescribeSObjectResult r1 = objType.getDescribe(); 
        
        Map<String , Schema.SObjectField> mapFieldList = r1.fields.getMap();  

        for(Schema.SObjectField field : mapFieldList.values()){  
            Schema.DescribeFieldResult fieldResult = field.getDescribe();  
            
            if(fieldResult.isAccessible()){  
                result.add(fieldResult.getName());
            }  
        }
        Integer i = 0;
        String fieldsToFetch = '';
        for(String temp:result){       
            Integer len = result.size();
            if(i==len-1){
                  fieldsToFetch = fieldsToFetch + temp;
            }
            else{
                  fieldsToFetch = fieldsToFetch + temp + ',';
            }
            i++;
        }
        try{
            String sql = ' SELECT ' + fieldsToFetch + ' FROM ' + selectedObject + ' ORDER BY CreatedDate DESC LIMIT 5';
            objFields = Database.Query(sql);
        }
        catch(Exception e){
            ApexPages.addMessages(e);
        }
    }   
}

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas
Surya.236Surya.236
Hi Khan , Thanks for your immediate reply i will let you know soon does it worked or not.
Shruti TandonShruti Tandon
Hey ,
can you help me customise the columns that i am displaying,i have made a custom setting named:General which has two fields,Objectname and Apiname,and the records have the list of fields  i want to show,problem is i cant figure out how to query it in my table header.it would be a great help !