To filter or search records in Lightning Datatable, use JavaScript includes(). Doing Apex call and using LIKE operator in the SOQL is not needed as we can filter the records in the Lightning Web Component JavaScript itself.
Sample Code:
Apex Class:
public class AccountController {
@AuraEnabled( cacheable = true )
public static List< Account > fetchAccounts() {
return [
SELECT Id, Name, Industry, Is_Active__c
FROM Account
LIMIT 10
];
}
}
Lightning Web Component:
HTML:
<template>
<lightning-card title="Accounts" icon-name="custom:custom63">
<div class="slds-m-around_medium">
<lightning-input type="search" label="Search Account" onchange={handleSearch}></lightning-input><br/><br/>
<template if:true={availableAccounts}>
<lightning-datatable
key-field="Id"
data={availableAccounts}
columns={columns}
hide-checkbox-column="true"
show-row-number-column="true"
onrowaction={handleRowAction}>
</lightning-datatable>
</template>
<template if:true={error}>
{error}>
</template>
</div>
</lightning-card>
</template>
JavaScript:
import { LightningElement, wire } from 'lwc';
import fetchAccounts from '@salesforce/apex/AccountController.fetchAccounts';
import { NavigationMixin } from 'lightning/navigation';
const actions = [
{ label: 'View', name: 'view' },
{ label: 'Edit', name: 'edit' },
];
const columns = [
{ label: 'Name', fieldName: 'Name' },
{ label: 'Industry', fieldName: 'Industry' },
{ label: 'Is Active?', fieldName: 'Is_Active__c', type: 'boolean' },
{
type: 'action',
typeAttributes: { rowActions: actions },
},
];
export default class LightingDataTableSearch extends NavigationMixin( LightningElement ) {
availableAccounts;
error;
columns = columns;
searchString;
initialRecords;
@wire( fetchAccounts )
wiredAccount( { error, data } ) {
if ( data ) {
this.availableAccounts = data;
this.initialRecords = data;
this.error = undefined;
} else if ( error ) {
this.error = error;
this.availableAccounts = undefined;
}
}
handleRowAction( event ) {
const actionName = event.detail.action.name;
const row = event.detail.row;
switch ( actionName ) {
case 'view':
this[NavigationMixin.Navigate]({
type: 'standard__recordPage',
attributes: {
recordId: row.Id,
actionName: 'view'
}
});
break;
case 'edit':
this[NavigationMixin.Navigate]({
type: 'standard__recordPage',
attributes: {
recordId: row.Id,
objectApiName: 'Account',
actionName: 'edit'
}
});
break;
default:
}
}
handleSearchChange( event ) {
this.searchString = event.detail.value;
console.log( 'Updated Search String is ' + this.searchString );
}
handleSearch( event ) {
const searchKey = event.target.value.toLowerCase();
console.log( 'Search String is ' + searchKey );
if ( searchKey ) {
this.availableAccounts = this.initialRecords;
console.log( 'Account Records are ' + JSON.stringify( this.availableAccounts ) );
if ( this.availableAccounts ) {
let recs = [];
for ( let rec of this.availableAccounts ) {
console.log( 'Rec is ' + JSON.stringify( rec ) );
let valuesArray = Object.values( rec );
console.log( 'valuesArray is ' + JSON.stringify( valuesArray ) );
for ( let val of valuesArray ) {
console.log( 'val is ' + val );
let strVal = String( val );
if ( strVal ) {
if ( strVal.toLowerCase().includes( searchKey ) ) {
recs.push( rec );
break;
}
}
}
}
console.log( 'Matched Accounts are ' + JSON.stringify( recs ) );
this.availableAccounts = recs;
}
} else {
this.availableAccounts = 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: