ABSYZ ABSYZ

  • Home

    Home

  • About us

    Who We Are

  • Our Expertise

    What we Do

  • Our Approach

    How We Do It

  • Products

    What We Made

  • Industries

    Who We Do It For

  • Clients

    Whom We Did It For.

  • Article & Blogs

    What Experts Think

  • Careers

    Join The Team

  • Get In Touch

    Let’s Get Started

ABSYZ

Dynamic Reusable Lightning Table Component

Home / Article & Blogs / Salesforce / Lightning / Dynamic Reusable Lightning Table Component
By Team ABSYZ inLightning, Salesforce

Don’t Repeat Yourself (DRY) is a principle of software development aimed at reducing repetition of software development patterns. Most of the time we will find creating same kind of Component for different object over and over again. To over come this we have created Dynamic reusable lightning component.

Github Link:

https://github.com/gokulrajanoff/dynamic-table-

This component is for displaying the record in a table format, that allow sorting on header fields (without using any extra libraries) and the table is having fixed header and scrolling enabled. This component runs on standard as well as custom object.

To DO :

  1. Create Apex class :(Name It as you Like) -> Copy Paste entire Apex code
  2. Create Lightning Component -> Copy Paste entire component code , don’t forget to change the controller name to your apex , otherwise I am not responsible for the error.
  3. Controller will be automatically calculated, so no problem ,Copy Paste controller.js code , change the action,setparam() -> according to  your object and field to display.
  4. Preview as simple as that.

Overview of this Component:

Apex Class:

Table Class

Method:

Get_Record_For_Table_Input_From_Query(String objectName,String queryFields,String fullQuery)

Return:

Object that can be displayed on Table

objectName

= Name of the Object.

queryFields

= Fields we want to display.

fullQuery

= Full Soql Query.

Call this method and this will return data necessary for the table to be displayed.

Dynamic Reusable Lightning Table Component

Code :

Apex Class :

[sourcecode language=”java” wraplines=”false” collapse=”false”]
public class DynamicTableClass {

@AuraEnabled
public static object Get_Record_For_Table_Input_From_Query(String objectName,String queryFields,String fullQuery)
{
Integer headerindex=0;
TargetTable TargetTable_inst = new TargetTable();
List allListOfRecords = new List();
String Query=fullQuery;
//split all the fields into a list of strings
List fieldList= queryFields.split(‘,’);
//Creating a Dynamic Object Type with Custom object name
String listType = ‘List’;
//Creating a Dynamic Record Type with Custom object name
String EachRecordType = ”+objectName+”;
System.debug(‘listType’+listType);
System.debug(‘EachRecordType’+EachRecordType);
//Creating a generic Sobject to hold data of custom object
List ListOfRecords = (List)Type.forName(listType).newInstance();
SObject IndividualMember = (SObject)Type.forName(EachRecordType).newInstance();
//Execute the Query to get and store the data in Generic object
ListOfRecords = Database.query(Query);
system.debug(ListOfRecords);
//object field map
Map objectFields = Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap();
for(Integer i=0;i<ListOfRecords.size();i++)
{
IndividualMember = ListOfRecords[i];
EachRecord Each_record_nested_List_Of_Fields = new EachRecord();
List temp = new List();
for(String field :fieldList)
{ //record id
if(field==’id’)
{
Each_record_nested_List_Of_Fields.recordId=(Id)IndividualMember.get(field);
}
//if there is any relation like account.name
if(field.containsAny(‘\\.’))
{
List relation = field.split(‘\\.’);
//get the actual value not id in relation
temp.add(IndividualMember.getSobject(relation[0]).get(relation[1]));
}
else
{ //except is store all field and values
if(field!=’id’){
temp.add((IndividualMember.get(field)==null)?”:IndividualMember.get(field));
}
}
}
System.debug(‘i=’+i+’-‘+temp);
Each_record_nested_List_Of_Fields.recordValue=temp;
allListOfRecords.add(Each_record_nested_List_Of_Fields);
}

//prepare header
List

headerList = new List

();for(String field :fieldList)
{
if(field!=’id’){
header h = new header();
h.index=headerindex++;
String s = field;
//removing __c
Integer i=s.lastIndexOf(‘_’);
if(i!=-1)
{
s=s.substring(0,i);
}
//replacing _ with space so we get account_name = account name
s=s.replaceAll(‘_’,’ ‘);
system.debug(‘String’+s);
h.name=s;
h.sorted=2;
headerList.add(h);
}
}
//system.debug(‘Header:’+headerList);
TargetTable_inst.headerList=headerList;
TargetTable_inst.records=ListOfRecords;
TargetTable_inst.ListOfEachRecord=allListOfRecords;
return TargetTable_inst;}
public class header{
@AuraEnabled public String name; //Name of the Field
@AuraEnabled public String api; //Api of the Field
@AuraEnabled public Integer sorted; //Is the FieldSorted
@AuraEnabled public Integer index; //Index of the Field on record
}
public class EachRecord{
@AuraEnabled public Map fieldValuePair; //The field and Its corresponding Value
@AuraEnabled public List recordValue; //Record
@AuraEnabled public Id recordId; //Record Id used for Firing Events
}
public class TargetTable{
@AuraEnabled public List

headerList; //Header wrapper
@AuraEnabled public List records; //actual list of records
@AuraEnabled public List ListOfEachRecord; //curated wrapped list of record facilitated for table
}
}
[/sourcecode]

Lightning Component.cmp:

[sourcecode language=”xml” wraplines=”false” collapse=”false”]
<aura:component controller=”DynamicTableClass” implements=”force:appHostable, flexipage:availableForAllPageTypes, flexipage:availableForRecordHome, force:hasRecordId, forceCommunity:availableForAllPageTypes, force:lightningQuickAction” access=”global” >
<aura:attribute name=”Table_header_Records” type=”object”/>
<aura:attribute name=”Error” type=”boolean” default=”false” description=”use for displaying error in query or backend exception”/>
<aura:attribute name=”Message” type=”boolean” default=”false” description=”use for display no record found message”/>
<aura:handler name=”init” value=”{!this}” action=”{!c.getRecordsForTable}”/>
<aura:attribute name=”showHeaders” type=”Boolean” default=”false”/>
<article class=”slds-card”>
<aura:if isTrue=”{!v.Error}”>
<div class=”slds-text-color–error”>Error In Query Or Backend Exception, check With it </div>
</aura:if>
<aura:if isTrue=”{!v.Message}”>
<div class=”slds-text-color–error”> No Result Found…</div>
</aura:if>
<aura:if isTrue=”{!v.showHeaders}”>
<div class=”slds-center” style=”align:center;”>
<div class=”slds-table–header-fixed_container” style=”height:350px;”>
<div class=”slds-scrollable_y” style=”height:100%;”>
<table class=”slds-table slds-table_bordered slds-table–header-fixed”>
<thead>
<tr class=”slds-text-title–caps”>
<aura:iteration items=”{!v.Table_header_Records.headerList}” var=”h”>
<th scope=”col” onclick=”{!c.sortColumn}” data-value=”{!h.index}”>
<div class=”slds-truncate slds-cell-fixed” title=”{!h.name}”>{!h.name}
<aura:if isTrue=”{! (h.sorted == 0) }”>&nbsp; ▼ </aura:if>
<aura:if isTrue=”{! (h.sorted == 1) }”> &nbsp; ▲ </aura:if>
</div>
</th>
</aura:iteration>
</tr>
</thead>
<tbody>
<aura:iteration items=”{!v.Table_header_Records.ListOfEachRecord}” var=”tar”>
<tr onclick=”{!c.displayfields}” data-value=”{!tar.recordId}”>
<aura:iteration items=”{!tar.recordValue}” var=”value”>
<td>
<a><div class=”slds-truncate”>{!value}</div></a>
</td>
</aura:iteration>
</tr>
</aura:iteration>
</tbody>
</table>
</div></div>
</div>
</aura:if>
</article>
</aura:component>
[/sourcecode]

Lightning Controller.js:

[sourcecode language=”javascript” wraplines=”false” collapse=”false”]
({
getRecordsForTable : function(component, event, helper) {
var action=component.get(“c.displayTable”);
action.setCallback(this,function(response)
{
component.set(“v.Table_header_Records”,response.getReturnValue());
var records = component.get(“v.Table_header_Records”);
console.log(component.get(“v.Table_header_Records”));
if(records==null)
{
component.set(“v.Error”, true);
component.set(“v.showHeaders”,false);
}
if (records!=null && records.ListOfEachRecord.length == 0) {
component.set(“v.Message”, true);
component.set(“v.showHeaders”,false);

} else {
component.set(“v.Message”, false);
component.set(“v.showHeaders”,true);
}
});
$A.enqueueAction(action);
},
sortColumn : function(component, event, helper) {
var ctarget = event.currentTarget;
var Fieldindex = ctarget.dataset.value;
console.log(“selected Field” Fieldindex);
var Wrapedrecords = component.get(“v.Table_header_Records”);
var objectRecord = Wrapedrecords.ListOfEachRecord;
var headerRecord = Wrapedrecords.headerList;
console.log(headerRecord);
for(var i=0;i<headerRecord.length;i ){
console.log(“loop:” headerRecord[i].name ” – ” Fieldindex);
if(headerRecord[i].index==Fieldindex)
{ console.log(“match entered”);
var sorted = headerRecord[i].sorted;
if(sorted==1)
{
//desc
console.log(“descending”);
objectRecord.sort(function(a,b) {
return (a[‘recordValue’][headerRecord[i].index].toString().toLowerCase() < b[‘recordValue’][headerRecord[i].index].toString().toLowerCase() ) ? 1 : ((b[‘recordValue’][headerRecord[i].index].toString().toLowerCase() < a[‘recordValue’][headerRecord[i].index].toString().toLowerCase() ) ? -1 : 0);} );
sorted=0;
}
else if(sorted==0 || sorted==2)
{
console.log(“ascending”);
objectRecord.sort(function(a,b) {return (a[‘recordValue’][headerRecord[i].index].toString().toLowerCase() > b[‘recordValue’][headerRecord[i].index].toString().toLowerCase() ) ? 1 : ((b[‘recordValue’][headerRecord[i].index].toString().toLowerCase() > a[‘recordValue’][headerRecord[i].index].toString().toLowerCase() ) ? -1 : 0);} );
sorted=1;
}
headerRecord[i].sorted=sorted;

}
else{
headerRecord[i].sorted=2;
}
}
Wrapedrecords.records=objectRecord;
Wrapedrecords.headerList=headerRecord;
console.log(Wrapedrecords);
component.set(“v.Table_header_Records”,Wrapedrecords);

}

})
[/sourcecode]

Application :

[sourcecode language=”xml” wraplines=”false” collapse=”false”]
<aura:application extends=”force:slds”>
<center><h1>Table1</h1></center>
<c:testDynamicComponent ></c:testDynamicComponent>
<br/>
<center><h1>Table2</h1></center>
<c:DynamicTablecomponent ></c:DynamicTablecomponent>
</aura:application>
[/sourcecode]

Output:

Dynamic Reusable Lightning Table Component output

Clicking on the Column will sort the column:

Screen Shot 2018-04-25 at 6.55.48 PM

Note:

Place we need to modify code to make it run on different object

[sourcecode language=”javascript” wraplines=”false” collapse=”false”]
var action=component.get(“c.Get_Record_For_Table_Input_From_Query”);
action.setParams({“objectName”:”contact”,”queryFields”:”name,title,phone,email”,”fullQuery”:”select name,title,phone,email from contact”});
[/sourcecode]

Or we can call this method DynamicTableClass.Get_Record_For_Table_Input_From_Query(objectName, queryFields, fullQuery) from other apex class.

Similarly we can create Different component that will display records from different object by just modifying the parameter passed to Get_Record_For_Table_Input_From_Query() function.

Dynamic Reusable different Component

Other Features:

  1. On Click of a row, a Controller function will be called , we can get the record id of that row by

[sourcecode language=”javascript” wraplines=”false” collapse=”false”]
var ctarget = event.currentTarget;
var RecordID = ctarget.dataset.value;
[/sourcecode]

we can use the Record Id to fire events or else do something as you wish :D.

2. Sorting Done Client side without extra libraries , so no headache in creating static resource fields. And its fast , no server calls.

3.Scrollable View , so we can see may records at a time , we can adjust the height of table according to your wish.

Dynamic Reusable Lightning Table ComponentLightning componentLightning Table Componentreusable table
145
Like this post
26 Posts
Team ABSYZ

Search Posts

Archives

Categories

Recent posts

All About The OmniStudio FlexCards

All About The OmniStudio FlexCards

Boost Customer Experience With Repeater Widget in CRM Analytics

Boost Customer Experience With Repeater Widget in CRM Analytics

Enhance Insights Using Custom Tooltips In CRM Analytics

Enhance Insights Using Custom Tooltips In CRM Analytics

Net zero as a Service In CPG Industry

Net zero as a Service In CPG Industry

How Do We Import an External Library into Salesforce Lightning?

How Do We Import an External Library into Salesforce Lightning?

  • Previous PostSalesforce to Salesforce Integration
  • Next PostGrouped Bar Graph In Lightning Using Strike Bar Graph Component Extension

Related Posts

All About The OmniStudio FlexCards
OmniStudio Salesforce

All About The OmniStudio FlexCards

Boost Customer Experience With Repeater Widget in CRM Analytics
CRM Analytics Salesforce

Boost Customer Experience With Repeater Widget in CRM Analytics

Enhance Insights Using Custom Tooltips In CRM Analytics
CRM Analytics Salesforce

Enhance Insights Using Custom Tooltips In CRM Analytics

How Do We Import an External Library into Salesforce Lightning?
Lightning Salesforce

How Do We Import an External Library into Salesforce Lightning?

2 Comments

  1. Radhika Shet
    Reply
    3 May 2018

    Great work..really helpful!!

    Reply
  2. ben olsen
    Reply
    10 April 2019

    I am working on using this ( this is so good for many things). In your git comments you note to just go to DynamicTableapp.app, and change the query. I can’t find this, can you give some more direction on this. Do i have to still copy all the code? ( in a sandbox and then deploy?) change that code then it will work?

    Reply

Leave a Reply (Cancel reply)

Your email address will not be published. Required fields are marked *

*
*

ABSYZ Logo

INDIA | USA | UAE

  • About us
  • Article & Blogs
  • Careers
  • Get In Touch
  • Our Expertise
  • Our Approach
  • Products
  • Industries
  • Clients
  • White Papers

Copyright ©2022 Absyz Inc. All Rights Reserved.

youngsoft
Copy
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “ACCEPT ALL”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent. Privacy Policy
Cookie SettingsREJECT ALLACCEPT ALL
Manage consent

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled

Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.

CookieDurationDescription
cookielawinfo-checkbox-analytics11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional11 monthsThe cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance11 monthsThis cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy11 monthsThe cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.

Functional

Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.

Performance

Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.

Analytics

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.

Advertisement

Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.

Others

Other uncategorized cookies are those that are being analyzed and have not been classified into a category as yet.

SAVE & ACCEPT