Dynamic Table And Filter Using Lightning Aura Components
Lightning Auro components

Dynamic Table And Filter Using Lightning Aura Components

Sharing is caring!

Do you want to know how to use a dynamic label for a field using Lightning Aura Components? Or how can you create a dynamic table with variable columns? If your answer is in the affirmative, then this blog on Dynamic Table And Filter Using Lightning Aura Components is a must-read for you.

Dynamic lightning table components help you to display records in the table format easily. 

This component has three key attributes:

1. Object – Specify the object’s API name from where you need to retrieve the data and records.

2. Fields – Specify the list of columns you would like to preview in the table. You have to mention the API name of the object fields.

3. pageSize – Specify the number of records you would like to display on a page.

In this blog post, I will explain how to use Dynamic Table And Filter in Salesforce Lightning. Before moving further, let us first discuss what is Dynamic Table and Filter in Salesforce.

Dynamic Table: Dynamic table is that table where we have to update the range of data repeatedly.

Dynamic Filter: Dynamic filter is where you can make dynamic UI according to the table column field and apply filters according to your required field.

ScreenShots of Dynamic Table and filter are attached below for understanding the flow of code.

Screenshot 1: Shows the Name and Date filed only in the column.

Screenshot 2: Apply dynamically filter and create UI only for Name and Date field.

Screenshot 3: Update the dynamically filed in a column.

Screenshot 4: Now, you can see dynamically column fields are updated.

Screenshot 5: Dynamically apply filters and  UI are updated according to column fields. 

To Call DynamicTable And Filter Component

*ObjApiName, selectedFields and  fieldApiValues pass these values according to your requirements. 

<c:DynamicDataTableComp ObjApiName=”{! v.ObjApiName}” selectedFields=”{! v.selectedFields}” fieldApiValues=”{! v.fieldApiValues}”/> 

 <c:FilterComponent DynamicTableValue = “{!v.selectedFields}”  ObjApi = “{! v.ObjApiName}” />

Create a DynamicDataTableComp in your Developer Console.

component [DynamicDataTableComp.cmp]

<aura:component description=”DynamicDataTableComp” 

                controller=”DynamicDataTableController”     implements=”force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction” access=”global” >

    <aura:attribute name=”ObjApiName” type=”String”/>

    <aura:attribute name=”PathName” type=”String”/>

    <aura:attribute name=”selectedFields” type=”list”/>

    <aura:attribute name=”fieldApiValues” type=”list”/>

    <aura:attribute name=”searchResult” type=”list”/>

    <aura:attribute name=”recordList” type=”list”/>

    <aura:attribute name=”recordListByPage” type=”list”/>

    <aura:attribute name=”isPagination” type=”Boolean” default=”false” /> 

    <aura:attribute name=”PageSize” type=”Integer” default=”10″/>

    <aura:attribute name=”isShowSpinner” type=”Boolean” default=”false” />

    <aura:handler name=”PaginationList” event=”c:PaginationEvent” action=”{!c.handlePaginationEvent}”/>

    <aura:handler event=”c:PageSizeToDynamicDataTable” action=”{!c.handlePageSizeEvent}”/>

    <aura:handler  event=”c:FilterHide” action=”{!c.FilterDynamicListMethod}”/>        

    <aura:handler name=”init” value=”this” action=”{!c.doInit}”/>

    <aura:registerEvent name=”sampleCmpEvent” type=”c:MakePillsEvent” />

    <aura:registerEvent name=”RecordListEvent” type=”c:PaginationEventForSearchKey”/>

    <!– SPINNER –>

    <aura:if isTrue='{!v.isShowSpinner}’>

        <lightning:spinner alternativeText=”Loading” size=”large” />

    </aura:if>

    <div class=”dynamicdiv”>

        <table class=”dynamicTable slds-table slds-table_cell-buffer”>

            <tr class=”tableHeading”>

                <aura:iteration items=”{!v.selectedFields}” var=”labels”>

                    <th>{! labels.label}</th>

                </aura:iteration>

            </tr>

            <aura:iteration items=”{!v.recordListByPage}” var=”columnList”>

                <tr>

                    <aura:iteration items=”{!columnList}” var=”columnValue”>

                        <aura:if isTrue=”{!(columnValue.Key == ‘name’)}”>

                            <td>

                                <div>

                                    <a onclick=”{!c.viewRecord}” name=”{!columnValue.Id+columnValue.Value}” class=”AuditRecCss”>{!columnValue.Value}</a>

                                </div>

                            </td>

                            <aura:set attribute=”else”>

                                <td>

                                    {! columnValue.Value} 

                                </td>

                            </aura:set>

                        </aura:if> 

                    </aura:iteration>

                </tr>

            </aura:iteration>

        </table>

    </div>

    <aura:if isTrue=”{! v.isPagination}”>

        <div class=”ForDesktopView slds-border_top” >

            <c:PaginationComp RecordList=”{!v.recordList}”/>

        </div>

    </aura:if>

</aura:component>

js controller [DynamicDataTableComp.js]

({

    doInit: function(component, event, helper) {

        component.set(‘v.isShowSpinner’,true);

        helper.doInit_helper(component, event, helper);

    },

    viewRecord : function(c,e,h){

        h.viewRecord_helper(c, e, h);

    },

    handlePaginationEvent : function(c, e) {

        let RecordByPage = e.getParam(“RecordByPage”);

        c.set(“v.recordListByPage”, RecordByPage);

    },

    handlePageSizeEvent : function(c, e, h){

        var fieldApiValues = c.get(‘v.fieldApiValues’);

        var searchResult = c.get(‘v.searchResult’);

        let pageSize = e.getParam(“pageSize”);

        if(!$A.util.isUndefinedOrNull(pageSize)){

            c.set(“v.PageSize”, pageSize);

        }else{

            c.set(“v.PageSize”, 10) 

        }

        c.set(“v.isPagination”, false);

        h.makeWrapper_Helper(c,e,h,searchResult,fieldApiValues);

    },

    FilterDynamicListMethod : function(c, e, h){

        // alert(‘YesFire’);

        let FilterDynamicList = e.getParam(“FilterDynamicList”);

        var fieldApiValues = c.get(‘v.fieldApiValues’);

        //console.log(‘FilterDynamicListinDataTabel ‘ + JSON.stringify(FilterDynamicList));

        h.makeWrapper_Helper(c,e,h,FilterDynamicList,fieldApiValues);

    }

})

js Helper [DynamicDataTableCompHelper.js]

({

    doInit_helper : function(component, event, helper) {

        try{

            var objApiName = component.get(‘v.ObjApiName’);

            var fieldApiValues = component.get(‘v.fieldApiValues’);

            console.log(‘fieldApiValues:::’+JSON.stringify(fieldApiValues));

            var action = component.get(“c.fetchObjectRecords”);

            action.setParams({

                ‘objApiName’: objApiName,

                ‘fieldApiValues’: fieldApiValues

            });

            action.setCallback(this, function(response) {

                var state = response.getState(); 

                console.log(‘state:::’+state);

                if (state === “SUCCESS”) {

                    var storeResponse = response.getReturnValue();

                    component.set(“v.searchResult”, storeResponse);

                    //console.log(‘result:::’+JSON.stringify(component.get(“v.searchResult”)));

                    helper.makeWrapper_Helper(component,event,helper,storeResponse,fieldApiValues);

                }

            });

            $A.enqueueAction(action);

        }catch(ex){

            console.log(‘error in code:::’+ex);

            component.set(‘v.isShowSpinner’,false);

        }

    },

    makeWrapper_Helper : function(component,event,helper,storeResponse, fieldApiValues){

    component.set(“v.searchResult”, storeResponse);

        var mainList = [];

        for(let i=0; i<storeResponse.length; i++){

            let newList = [];

            let indexObj = {};

            indexObj.Key = ‘Index’;

            indexObj.Value = i+1;

            newList.push(indexObj);

            //console.log(‘storeResponse[i]:::’+JSON.stringify(storeResponse[i]));

            let AllRowListMap = new Map(Object.entries(storeResponse[i]));

            console.log(‘AllRowListMap:::’+Array.from(AllRowListMap.entries()));

            let newCustomMap = new Map();

            let count = 0;

            for(let m=0; m<fieldApiValues.length; m++){

                let mapKey = Array.from(AllRowListMap.keys())[count];

                if(!$A.util.isUndefinedOrNull(mapKey)){

                    //console.log(‘mapKey:::>>>’+mapKey);

                    //console.log(‘fieldApiValues:::>>>’+fieldApiValues[m]);

                    if(mapKey.toLowerCase() == fieldApiValues[m]){

                        // console.log(‘key matched>>>>’);

                        //console.log(‘value in map :::’+AllRowListMap.get(mapKey));

                        newCustomMap.set(fieldApiValues[m],AllRowListMap.get(mapKey));

                        count++;

                    }else{

                        newCustomMap.set(fieldApiValues[m],”);

                        if(count == 0){

                            count = 0;

                        }

                    }

                }else{

                    let flag = false;

                    let mapKeynew = Array.from(AllRowListMap.keys())[m-1];

                    let mapValue = AllRowListMap.get(mapKeynew);

                    //console.log(‘mapValue::>>>’+mapValue);

                    //console.log(‘all values in map::::’+Array.from(AllRowListMap.values()));

                    for(let mapValueObj in Array.from(AllRowListMap.values())){

                        //console.log(‘individual value:::’+AllRowListMap.values()[mapValueObj]);

                        if(Array.from(AllRowListMap.values()).includes(mapValue)){

                            flag = true;

                        }

                    }

                    if(true){

                        newCustomMap.set(fieldApiValues[m],”);

                    }else{

                        newCustomMap.set(fieldApiValues[m],mapValue);

                    }

                }

            }

            //console.log(‘newCustomMap:::’+Array.from(newCustomMap.entries()));

            for(let mapObj in Array.from(newCustomMap.entries())){

                let listMapObj = {};

                listMapObj.Key = Array.from(newCustomMap.keys())[mapObj];

                listMapObj.Value = newCustomMap.get(listMapObj.Key);

                listMapObj.Id = storeResponse[i].Id;

                newList.push(listMapObj);

            }

            mainList.push(newList);

        }

        //console.log(‘mainList:::’+JSON.stringify(mainList));

        component.set(‘v.recordList’, mainList);

        component.set(‘v.isPagination’, true);

        component.set(‘v.isShowSpinner’,false);

        var myEvent = $A.get(“e.c:PaginationEventForSearchKey”);

        myEvent.setParams({

            “RecordList”: mainList,

            “pageSize”: component.get(“v.PageSize”)

        });

        myEvent.fire();

    },

    viewRecord_helper: function(c, e, h){

        try{

            let Name = e.currentTarget.name;

            console.log(‘Name::: ‘+Name);

            let idObj = Name.substring(0,18);

            let recordName = Name.substring(18);

            let recordList = c.get(‘v.recordList’);

            let PathName = c.get(‘v.PathName’);

            if(!$A.util.isUndefinedOrNull(recordList) && !$A.util.isEmpty(recordList)){

                for(let i=0;i<recordList.length;i++){

                    let selectedRecord = recordList[i];

                    console.log(‘selectedRecord length::::’+selectedRecord.length);

                    for(let z=0;z<selectedRecord.length;z++){

                        if(selectedRecord[z].Value === recordName){

                            let indexValue = selectedRecord[0].Value;

                            let finalName = indexValue+’: ‘+recordName+’ ‘+idObj;

                            // console.log(‘matched:::::::’);

                            var cmpEvent = c.getEvent(“sampleCmpEvent”);

                            cmpEvent.setParams({

                                “message” : finalName,

                                ‘PathName’ : PathName,

                                ‘obName’  : c.get(‘v.ObjApiName’)

                            });

                            cmpEvent.fire();

                        }

                    } 

                }

            }

        }catch(ex){

            console.log(‘ERROR—>’+ex);

            c.set(‘v.isShowSpinner’,false);

        }

    }

})

Apex controller [DynamicDataTableController.apxc]

public class DynamicDataTableController {

    @AuraEnabled

    public static List<SObject> fetchObjectRecords(String objApiName, List<String> fieldApiValues) {

        System.debug(‘fieldApiValues:::’+fieldApiValues);

        System.debug(‘objApiName:::’+objApiName);

        List <SObject> allRecords = new List <SObject> ();

        String query = ‘SELECT ‘;

        for(Integer i=0; i<fieldApiValues.size(); i++){

            query += fieldApiValues[i] +’ ,’;

        }

        query = query.removeEnd(‘,’);

        query += ‘ FROM ‘ + objApiName + ‘ LIMIT 50000’;

        System.debug(‘qq:::’ + query);

        allRecords = Database.query(query);

        System.debug(‘allRecords:::’+allRecords);

        return allRecords;

    }

}

Create a FilterComponent in your Developer Console.

component [FilterComponent.cmp]

<aura:component controller=”FilterApex”  implements=”force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction” access=”global” >

    <aura:attribute name=”DynamicTableValue” type=”List” />

    <aura:attribute name=”ObjApi” type=”String” />

    <aura:attribute name=”FilteFileds” type=”List” />

    <aura:attribute name=”FilterPopup” type=”Boolean” default = “true” />

    <aura:registerEvent name=”HandelFilter” type=”c:FilterHide”/>

    <aura:handler name=”init” value=”{!this}” action=”{!c.doInit}”/>

    <aura:if isTrue='{!v.FilterPopup}’>

        <section role=”dialog” tabindex=”-1″ aria-labelledby=”modal-heading-01″ aria-modal=”true” aria-describedby=”modal-content-id-1″ class=”slds-modal slds-fade-in-open” style=”box-shadow: 0px 1px 7px 2px lightgrey;”>

            <div class=”slds-modal__container”>

                <!– ###### MODAL BOX HEADER Start ######–>

                <header class=”slds-modal__header”>

                    <lightning:buttonIcon iconName=”utility:close”

                                          onclick=”{! c.closeModel }”

                                          alternativeText=”close”

                                          variant=”bare-inverse”

                                          class=”slds-modal__close”/>

                    <h2 id=”modal-heading-01″ class=”slds-text-heading_medium slds-hyphenate”>Apply Filter</h2>

                </header>

                <!–###### MODAL BOX BODY Part Start######–>

                <div class=”slds-modal__content slds-p-around_medium” id=”modal-content-id-1″>

                    <aura:iteration items=”{!v.FilteFileds}” var=”field”>

                        <aura:if isTrue=”{!field.type == ‘picklist’}” >

                            <lightning:combobox aura:id=”ComboID” name=”progress” label=”{!field.label}” options=”{!field.PickValue}”/>

                            <aura:set attribute=”else”>

                                <lightning:input aura:id=”ComboID” type = “{!field.type}” label=”{!field.label}” value=”{!field.Value}”/>

                            </aura:set>

                        </aura:if>

                    </aura:iteration>

                </div>

                <!–###### MODAL BOX FOOTER Part Start ######–>

                <footer class=”slds-modal__footer”>

                    <lightning:button variant=”Neutral” 

                                      label=”Cancel”

                                      onclick=”{! c.ClosedPopup }” />

                    <lightning:button variant=”brand” 

                                      label=”Apply”

                                      onclick=”{! c.ApplyFilterMethod }”/>

                </footer>

            </div>

        </section>

        <div class=”slds-backdrop slds-backdrop_open”></div>

    </aura:if>

</aura:component>

js controller [FilterComponentController.js]

({

    doInit : function(c, e, h) {

        try{

            var DynamicTableValueVirtual = c.get(‘v.DynamicTableValue’);

            var DynamicTableValue =[];

            //   DynamicTableValue.splice(0,1);

             console.log(‘DynamicTableValueVirtual ‘+ JSON.stringify(DynamicTableValueVirtual));

            for(var i = 1;i<DynamicTableValueVirtual.length;i++){

                var DynamicTableValueObj = {}; 

                DynamicTableValueObj = DynamicTableValueVirtual[i];

                DynamicTableValue.push(DynamicTableValueObj);

            }

           console.log(‘DynamicTableValue ‘+ JSON.stringify(DynamicTableValue));

            var ObjApi = c.get(‘v.ObjApi’);

            var action = c.get(“c.fieldType”);

            action.setParams({

                “ObjApi” :  ObjApi,

                “DynamicTableValue”: JSON.stringify(DynamicTableValue)

            });

            action.setCallback(this, function(response) {

                var state = response.getState();

                console.log(‘state is +===>>>>’+state);

                var result = response.getReturnValue();

                console.log(‘result ‘ +JSON.stringify(result));

                c.set(“v.FilteFileds”, result)

            });

            $A.enqueueAction(action);

        }

        catch(er){

            console.log(‘er ‘ + er);

        }

    },

    closeModel :function(c,e,h){

        var appEvent = $A.get(“e.c:FilterHide”);

        appEvent.fire();

    },

    ClosedPopup : function(c,e,h){

        var appEvent = $A.get(“e.c:FilterHide”);

        appEvent.fire();

    },

    ApplyFilterMethod : function(c,e,h){

        try{

            console.log(‘Apply Filter’);

            var finalDynamicList = [];

            var DynamicTableValueFilter = c.get(‘v.DynamicTableValue’);

            console.log(‘DynamicTableValueFilter ‘ + JSON.stringify(DynamicTableValueFilter));

            var flag = false;

            var UIValue = c.find(“ComboID”);

            console.log(‘UIValue ‘ + UIValue);

            if(UIValue.length>1){

            for(var k = 0 ;k<UIValue.length;k++){

                console.log(‘UIValue ‘ + UIValue[k].get(‘v.value’));

                if(UIValue[k].get(‘v.value’) != undefined){

                    flag = true;

                }

            }

            }

            else{

                console.log(‘length ‘ +UIValue.get(‘v.value’));

                let SingleUiValue = UIValue.get(‘v.value’);

                  console.log(‘SingleUiValue ‘ +SingleUiValue);

                  if(SingleUiValue != undefined){

                    flag = true;

                } 

            }

            if(flag){

                console.log(‘DynamicTableValueFilter ‘ + JSON.stringify(DynamicTableValueFilter));

                console.log(‘DynamicTableValueFilter.length ‘+ DynamicTableValueFilter.length);

                // DynamicTableValueFilter.splice(0,1);

                let DynamicTableValue = [];

                for(var i = 1;i<DynamicTableValueFilter.length;i++){

                    var DynamicTableValueObj = {}; 

                    DynamicTableValueObj = DynamicTableValueFilter[i];

                    DynamicTableValue.push(DynamicTableValueObj);

                }

                var fieldApivalue = [];

                for(var i = 0 ;i<DynamicTableValue.length;i++){

                    console.log(‘Yes In forloop’);

                    var mapValue;

                    if(UIValue.length >1){

                        mapValue =  UIValue[i].get(‘v.value’);

                    }else{

                         mapValue =  UIValue.get(‘v.value’);

                    }

                    console.log(‘Value is mapValue out if ‘ + mapValue);

                    var AllRowListMap = {};

                    if(mapValue != undefined){

                        console.log(‘Value is undefined ‘ + i);

                        console.log(‘Value is mapValue ‘ + mapValue);

                        AllRowListMap.label= DynamicTableValue[i].value;

                        AllRowListMap.value = mapValue;

                        finalDynamicList.push(AllRowListMap);

                    }

                    fieldApivalue.push(DynamicTableValue[i].value);

                }

                console.log(‘fieldApivalue ‘ + fieldApivalue);

                console.log(‘finalDynamicList ‘ + JSON.stringify(finalDynamicList));

                var ObjApi = c.get(‘v.ObjApi’);

                var action = c.get(“c.filterMethod”);

                action.setParams({

                    “ObjApi”: ObjApi,

                    “finalDynamicList” : JSON.stringify(finalDynamicList),

                    “fieldApivalue” : fieldApivalue

                });

                action.setCallback(this, function(response) {

                    var state = response.getState();

                    console.log(‘state is +===>>>>’+state);

                    var result = response.getReturnValue();

                    console.log(‘result ‘ +JSON.stringify(result));

                    if(result.length == 0){

                        var title = ‘Sorry’;

                        var message = ‘No records found’

                        var type = ‘error’

                        h.showToast(c,e,h,title,message,type);

                    }else{

                        //  c.set(“v.ActionItemRecord”, finalActionItemsList)

                        //  var cmpEvent = c.getEvent(“HandelFilter”);

                        var appEvent = $A.get(“e.c:FilterHide”);

                        appEvent.setParams({“FilterDynamicList” : result});

                        appEvent.fire();

                    }

                });

                $A.enqueueAction(action);

            }else{

                var UIValue = c.find(“ComboID”);

                if(UIValue.length >1){

                for(var i = 0 ;i<UIValue.length;i++){

                    UIValue[i].setCustomValidity(‘Please select atleast one field’); //do not get any message

                    UIValue[i].reportValidity();

                }

                }else{

                      UIValue.setCustomValidity(‘Please select field’); //do not get any message

                    UIValue.reportValidity();

                }

            }

        }

        catch(Ex){

            console.log(Ex);

        }

    },

})

Create these all events  in your Developer Console.

lightning Event [PaginationEvent.evt]

<aura:event type=”COMPONENT”>

    <aura:attribute name=”RecordByPage” type=”List”/>

</aura:event>

lightning Event [PageSizeToDynamicDataTable.evt]

<aura:event type=”APPLICATION”>

    <!–aura:attribute name=”RecordList” type=”List”/–>

    <aura:attribute name=”pageSize” type=”Integer”/>

</aura:event>

lightning Event [PaginationEventForSearchKey.evt]

<aura:event type=”APPLICATION”>

    <aura:attribute name=”RecordList” type=”List”/>

    <aura:attribute name=”pageSize” type=”Integer”/>

</aura:event>

lightning Event [FilterHide.evt]

<aura:event type=”APPLICATION” description=”Event template” >

    <aura:attribute name=”FilterDynamicList” type=”List” />

</aura:event>

*  Please register the event and pass the list before implementing the components.

If you are looking to explore the best of Salesforce products, services, and capabilities, contact one of the world’s leading Salesforce development companies and Salesforce Implementation Partners by choosing Cloud Analogy. Our teams of certified Salesforce developers, Salesforce administrators, and Salesforce consultants have rich expertise when it comes to assisting small, medium, and big-sized enterprises.

Our certified experts and consultants would help you realize your business’s true potential and help you with configurations, Salesforce data migrations, third-party integrations, and web-service, and other framework integrations.

Select the industry’s leading Salesforce Consulting Partner, choose Cloud Analogy now!

Deepali

Deepali Kulshrestha

Salesforce Certified Developer | Delivery Management Head
Deepali, a certified Salesforce Advanced Administrator and Salesforce Developer and CSPO Certified at Cloud Analogy, is a successful name in the industry circles when it comes to the delivery of successful projects with end-to-end testing. Deepali is a globally-renowned industry stalwart when it comes to managing Operations & Delivery Planning in driving Business Performance Management.

Hire the best Salesforce Development Company. Choose certified Salesforce Developers from Cloud Analogy now.

Close Menu