Custom Table with filtering and Sorting using LWC (Lightning Web Component)

Custom Table with filtering and Sorting using LWC (Lightning Web Component)

Sample Code:

Apex Class:

public with sharing class AccountController {
 
    @AuraEnabled( cacheable = true )
    public static List< Account > fetchAccounts() {
     
        return [
            SELECT Id, Name, Industry, Rating, Type, AccountNumber, Phone, Active__c, SLA__c
            FROM Account
            LIMIT 10
        ];
         
    }
     
}

Lightning Web Component:

HTML:

<template>
    <div class="slds-box slds-theme--default">
        <div class="slds-text-color_inverse slds-text-heading_large" style="padding:0.5rem;background:#16325c">        
            Accounts
        </div>
        <div class="slds-float_right">        
            <lightning-input type="search" onblur={handleKeyChange} class="slds-m-bottom_small" label="Search" maxlength="70">  
            </lightning-input>  
        </div>
        <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped">
                <thead>
                <tr class="slds-line-height_reset">
                    <th class="" scope="col">
                        <a class="slds-th__action slds-text-link_reset" href="javascript:void(0);" role="button" tabindex="0" onclick={sortRecs} name="Name">
                            Account Name
                        </a>
                    </th>
                    <th class="" scope="col">
                        <a class="slds-th__action slds-text-link_reset" href="javascript:void(0);" role="button" tabindex="0" onclick={sortRecs} name="AccountNumber">
                            Account Number
                        </a>
                    </th>
                    <th class="" scope="col">
                        <a class="slds-th__action slds-text-link_reset" href="javascript:void(0);" role="button" tabindex="0" onclick={sortRecs} name="Industry">
                            Industry
                        </a>
                    </th>
                    <th class="" scope="col">
                        <a class="slds-th__action slds-text-link_reset" href="javascript:void(0);" role="button" tabindex="0" onclick={sortRecs} name="Rating">
                            Rating
                        </a>
                    </th>
                    <th class="" scope="col">
                        <a class="slds-th__action slds-text-link_reset" href="javascript:void(0);" role="button" tabindex="0" onclick={sortRecs} name="Type">
                            Type
                        </a>
                    </th>
                    <th class="" scope="col">
                        <a class="slds-th__action slds-text-link_reset" href="javascript:void(0);" role="button" tabindex="0" onclick={sortRecs} name="Phone">
                            Phone
                        </a>
                    </th>
                    <th class="" scope="col">
                        <a class="slds-th__action slds-text-link_reset" href="javascript:void(0);" role="button" tabindex="0" onclick={sortRecs} name="Active__c">
                            Active
                        </a>
                    </th>
                    <th class="" scope="col">
                        <a class="slds-th__action slds-text-link_reset" href="javascript:void(0);" role="button" tabindex="0" onclick={sortRecs} name="SLA__c">
                            SLA
                        </a>
                    </th>
                </tr>
            </thead>
            <tbody>
                <template iterator:it={records}>
                    <tr class="slds-hint-parent" key = {it.value.Id}>
                        <td data-label="Account Name">
                            <div class="slds-cell-wrap">{it.value.Name}</div>
                        </td>
                        <td data-label="Account Number">
                            <div class="slds-cell-wrap">{it.value.AccountNumber}</div>
                        </td>
                        <td data-label="Industry">
                            <div class="slds-cell-wrap">{it.value.Industry}</div>
                        </td>
                        <td data-label="Rating">
                            <div class="slds-cell-wrap">{it.value.Rating}</div>
                        </td>
                        <td data-label="Type">
                            <div class="slds-cell-wrap">{it.value.Type}</div>
                        </td>
                        <td data-label="Phone">
                            <div class="slds-cell-wrap">{it.value.Phone}</div>
                        </td>
                        <td data-label="Active">
                            <div class="slds-cell-wrap">{it.value.Active__c}</div>
                        </td>
                        <td data-label="SLA">
                            <div class="slds-cell-wrap">{it.value.SLA__c}</div>
                        </td>
                    </tr>
                </template>
            </tbody>
        </table>
    </div>
</template>

JavaScript:

import { LightningElement, wire } from 'lwc';
import fetchAccounts from '@salesforce/apex/AccountController.fetchAccounts';

export default class Sample extends LightningElement {

    records;
    sortedColumn;
    sortedDirection = 'asc';
    initialRecords;

    @wire( fetchAccounts )  
    wiredAccount( { error, data } ) {
        if (data) {

            this.records = data;
            this.initialRecords = data;
            this.error = undefined;

        } else if ( error ) {

            this.error = error;
            this.initialRecords = undefined;
            this.records = undefined;

        }
    }  

    sortRecs( event ) {

        let colName = event.target.name;
        console.log( 'Column Name is ' + colName );
        if ( this.sortedColumn === colName ) {
            this.sortedDirection = ( this.sortedDirection === 'asc' ? 'desc' : 'asc' );
        }
        else {
            this.sortedDirection = 'asc';
        }

        let isReverse = this.sortedDirection === 'asc' ? 1 : -1;

        this.sortedColumn = colName;

        // sort the data
        this.records = JSON.parse( JSON.stringify( this.records ) ).sort( ( a, b ) => {
            a = a[ colName ] ? a[ colName ].toLowerCase() : ''; // Handle null values

            b = b[ colName ] ? b[ colName ].toLowerCase() : '';
            return a > b ? 1 * isReverse : -1 * isReverse;
        });

    }

    handleKeyChange( event ) {  
          
        const searchKey = event.target.value.toLowerCase();  
        console.log( 'Search Key is ' + searchKey );
 
        if ( searchKey ) {  

            this.records = this.initialRecords;
 
             if ( this.records ) {

                let recs = [];
                for ( let rec of this.records ) {

                    console.log( 'Rec is ' + JSON.stringify( rec ) );
                    let valuesArray = Object.values( rec );
                    console.log( 'valuesArray is ' + valuesArray );
 
                    for ( let val of valuesArray ) {
                        
                        if ( val ) {

                            if ( val.toLowerCase().includes( searchKey ) ) {

                                recs.push( rec );
                                break;
                        
                            }

                        }

                    }
                    
                }

                console.log( 'Recs are ' + JSON.stringify( recs ) );
                this.records = recs;

             }
 
        }  else {

            this.records = this.initialRecords;

        }
 
    }  

}

JS-meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>    
    <isExposed>true</isExposed>
     <targets>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

Output:

Sorting based on Custom Field Active__c:

Sorting based on Standard Field Name: 

Filtering Data:

Leave a Reply