Dynamic Binding Salesforce Lightning Component(Generic)

Welcome back All, here we will learn about the dynamic field of Lightning Component. As Most of you must be aware of that In Lightning, Component Dynamic component is not available. Recently I was working on one of my projects and implemented the Dynamic binding using the lightning component so I am going to share how I implemented the same so that it may help others.

As we all know that we can use the Dynamic Binding in the VisualForce page but in Lightning Component it is not Possible. 

In this example, We will show the list of Objects in a picklist and when user will select any object it will dynamically show the TOP 15 records in a table.

Output 

OutPut.png

Step1 – Create Apex Class

DynamicBindingDemoController.class

Step2 – Create the Lightning Component

DynamicBindingDemo.cmp

See the comments into the component.

Step3: – Click on Controller from the right and paste the below code for Controller Javascript

DynamicBindingDemoController.js


({
doInit : function(component, event, helper) {
helper.onInit(component, event, helper);
},
doHandleChange : function(component, event, helper) {
helper.onHandleChange(component, event, helper);
},
})

Step4: – Click on Helper from the right and paste the below code for Helper Javascript

DynamicBindingDemoHelper.js


({
onInit : function(component, event, helper) {
/* Call the Apex class method to fetch the List of all object */
var action = component.get('c.listAllObject');
action.setCallback(this, function(response){
var state = response.getState();
if(state === 'SUCCESS' && component.isValid()){
/* set the value to the attribute of the component */
var responseValue = response.getReturnValue();
var lstOptions = [];
for(var i=0; i < responseValue.length; i++){
lstOptions.push({
value : responseValue[i].split('####')[1],
key : responseValue[i].split('####')[0]
});
}
lstOptions.sort();
component.set('v.objectList', lstOptions);

}else{
var errors = response.getError();
$A.log(errors);
if(errors || errors[0].message){
console(errors[0].message);
}
}
});
$A.enqueueAction(action);
},
onHandleChange : function(component, event, helper){
/* Call this method whenever user will select the Obejct
* and show the Dynamic Content */
var selObject = component.find('selectObject').get('v.value');
var action = component.get('c.listAllFields');
if(selObject!=null && selObject!='' && selObject!=undefined){
action.setParams({
"objectName" : selObject
});
action.setCallback(this, function(response){
var state = response.getState();
if( state === 'SUCCESS' && component.isValid()){
//component.find("dynamicBody").set("v.body",[]);
component.find('sfdcDiv').set("v.body",[]);
var responseValue = response.getReturnValue();
var objectValue = responseValue.sObjectData;
var fieldList = responseValue.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);
//Get the count of columns.
var columnCount = sObjectDataTableHeader.length;
//Create a HTML Table element.
var table = document.createElement("TABLE");
//table.border = "1";
//Add the header row.
var row = table.insertRow(-1);
for (var i = 0; i < columnCount; i++) {
var headerCell = document.createElement("TH");
headerCell.innerHTML = sObjectDataTableHeader[i];
headerCell.className='hearderClass';
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];
component.set('v.isSending' , false);

}
}
}else{

}
}else{
var errors = response.getError();
$A.log('Error Details '+errors);
if( errors || errors[0].message){
console.log('Error Details '+errors[0].message);
}
}
});
$A.enqueueAction(action);
}else{
component.set('v.isSending' , false);
}
},
})

See the comments.

Step5: – Create Lightning Application

DynamicBindingDemoApplication.app

<aura:application access=”Global” extends=”force:slds” >
<c:DynamicBindingDemo />
</aura:application>

Click on Preview to see the output of the component.

Happy learning 🙂

Sharing is caring 🙂 😉

Resource:- 

OPFOCOUS Blog

Complete Code

 

 

 

Advertisements

10 thoughts on “Dynamic Binding Salesforce Lightning Component(Generic)

  1. Dubasi December 1, 2018 / 5:30 pm

    Hi Amit,

    I implemented this code and it is working fine, but in my requirement there is one more level in the middle between objects and records. I need to choose the fields as well and display the data of those selected fields only. I created one multi select picklist to display respective fields of each object but I am unable to display data of those fields. Can you please suggest how to achieve this requirement.

    I tried with passing the fields to my apex controller and make a query only for selected fields but I am getting Internal Salesforce.com Error. Can you please help me to find out the solution as I am very new to salesforce and this requirement has become little urgent for me now.

    Like

    • Amit Singh December 3, 2018 / 3:56 pm

      Please check the Debug log in Salesforce Server side there you will get more details about the Error.

      Like

  2. Chinu November 22, 2018 / 10:21 am

    Hi Amit,

    Thanks for your Post. It helped me to show all objects in a picklist format. Now my requirement is to show the related field as well. So could you help me.

    Helper:
    onHandleChange : function(component, event, helper){
    /* Call this method whenever user will select the Obejct
    * and show the Dynamic Content */
    var selObject = component.find(‘selectObject’).get(‘v.value’);
    var action = component.get(‘c.listAllFields’);
    if(selObject!=null && selObject!=” && selObject!=undefined){
    action.setParams({
    “objectName” : selObject
    });
    action.setCallback(this, function(response){
    var state = response.getState();
    if( state === ‘SUCCESS’ && component.isValid()){
    //component.find(“dynamicBody”).set(“v.body”,[]);
    component.find(‘sfdcDiv’).set(“v.body”,[]);
    var responseValue = response.getReturnValue();

                    var lstOptions = [];
                for(var i=0; i < responseValue.length; i++){
                    lstOptions.push({
                        value : responseValue[i].split('####')[1],
                        key : responseValue[i].split('####')[0]
                    });
                }
                lstOptions.sort();
                component.set('v.AllLabels', lstOptions);
    

    console.log(selObject);
    }else{
    var errors = response.getError();
    $A.log(‘Error Details ‘+errors);
    if( errors || errors[0].message){
    console.log(‘Error Details ‘+errors[0].message);
    }
    }
    });
    } $A.enqueueAction(action);
    },

    Apex:
    @AuraEnabled
    public static List listAllFields(String objectName){

    List<string> AllLabels = new List<string>();   
    

    Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    Schema.SObjectType leadSchema = schemaMap.get(objectName);
    Map<String, Schema.SObjectField> fieldMap = leadSchema.getDescribe().fields.getMap();

    for (String fieldName: fieldMap.keySet()) {
    AllLabels.add(fieldMap.get(fieldName).getDescribe().getLabel());
    }
    return AllLabels;
    }

    Like

    • Amit Singh November 25, 2018 / 3:17 pm

      From Apex you are returning only the Label of the Fields, not the API and in JavaScript, you are splitting by 4# so your javaScript is failing in that statement. So what you need to do is to send both Label and API Name from apex by connecting with ####. Take reference from other methods.

      Like

      • Chinu November 28, 2018 / 11:13 am

        Hi Amit,

        Thanks It is working fine now.
        I am facing one more problem now. While displaying the record after selecting objects and fields it is showing “Internal Salesforce.com Error” and in Helper I am getting ERROR for state while call back.

        APEX:
        @AuraEnabled
        public static List getRecords(string objectName, string FieldName)
        {
        List records = new List();

        system.debug(‘the progress name is ‘+records);

            // Create Dynamic Query Start ..
            String theQuery = 'SELECT ';
                   system.debug('the Query name is '+theQuery);
        
            // Insert field name variable into Query
            theQuery += FieldName + ',' ;
                   system.debug('the field name is '+FieldName);
        
            // Trim last comma
            theQuery = theQuery.subString(0, theQuery.length() - 1);
            // Finalize query string
            theQuery += ' FROM '+objectName;
            // Query End ..
            System.debug('theQuery = '+theQuery);           
        
        
            Object o = Database.Query(theQuery);
        
            String returnValue = String.valueOf(o);
        
                    records.add(returnValue);
                    System.debug('the return value = '+returnValue);
        
            return records;
        

        }

        HELPER:
        onmyHandleChange : function(component, event, helper){
        /* Call this method whenever user will select the Obejct
        * and show the Dynamic Content */
        var selObject = component.find(‘selectObject’).get(‘v.value’);
        var selField = component.find(‘selectField’).get(‘v.value’);
        var action = component.get(‘c.getRecords’);

        console.log(‘selObject – ‘+selObject);
        console.log(‘selField – ‘+selField);

                action.setParams({
                    "objectName" : selObject,
                    "FieldName" : selField  
                });
                action.setCallback(this, function(response){
                    var state = response.getState();
        

        console.log(‘state ‘+state);

                       if(component.isValid() && (state === 'SUCCESS' || state === 'DRAFT')){
                        var RecordsSetList = response.getReturnValue();
        
                           component.set('v.progress', RecordsSetList);        
        

        console.log(‘RecordsSetList – ‘+RecordsSetList);

               }else if(state==='INCOMPLETE'){
                    console.log('User is Offline System does not support drafts '
                               + JSON.stringify(response.getError()));
                }else if(state ==='ERROR'){
        
                }else{
        
                }
            });
            action.setStorable();
            $A.enqueueAction(action);
        

        console.log(‘action – ‘+action);
        },

        Could you please help me in this?
        I checked the Apex class and it is working fine in Anonymous window.

        Like

      • Amit Singh November 28, 2018 / 3:16 pm

        Please check if you are getting any Error on Salesforce APEX side. Turn the debug log on and see what is the exact Error.

        Regards,
        SFDCPanther

        Like

  3. Khan April 18, 2018 / 12:14 pm

    Hi Amit,

    Thanks for your post on Dynamic Binding Salesforce Lightning Component(Generic). It helps me to create a generic table to fetch object’s record. But I have one query. In table if I want to give some spacing between columns then what should I do. I am using className in css for width but it didn’t help. I am unable to find the solution for the same. Please help me with it. I will be highly obliged for your help. Thanks!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s