Sample Code:
Apex Class:
public with sharing class AccountController {
@AuraEnabled( cacheable = true )
public static List< Account > fetchAccounts( String searchKey ) {
String strKey = '%' + searchKey + '%';
System.debug( 'strKey is ' + strKey );
return [
SELECT Id, Name, Industry,
( SELECT Id, FirstName, LastName FROM Contacts ),
( SELECT Id, Name, Stagename FROM Opportunities )
FROM Account
WHERE Name LIKE: strKey LIMIT 10
];
}
}
Lightning Web Component:
HTML:
<template>
<lightning-card title="Search Accounts" icon-name="custom:custom63">
<div class="slds-m-around_medium">
<lightning-input type="search" onchange={handleKeyChange} class="slds-m-bottom_small" label="Search">
</lightning-input><br/>
<lightning-button variant="brand" label="Search" onclick={handleSearch}></lightning-button>
<template if:true={gridData}>
<lightning-tree-grid
columns={gridColumns}
data={gridData}
key-field="Id"
hide-checkbox-column=true>
</lightning-tree-grid>
</template>
<template if:true={error}>
{error}>
</template>
</div>
</lightning-card>
</template>
JavaScript:
import { LightningElement } from 'lwc';
import fetchAccounts from '@salesforce/apex/AccountController.fetchAccounts';
export default class accountSearchLWC extends LightningElement {
gridColumns = [ {
type: 'text',
fieldName: 'Name',
label: 'Name'
},
{
type: 'text',
fieldName: 'Industry',
label: 'Industry'
},
{
type: 'text',
fieldName: 'FirstName',
label: 'FirstName'
},
{
type: 'text',
fieldName: 'LastName',
label: 'LastName'
},
{
type: 'text',
fieldName: 'OpptyName',
label: 'Opportunity Name'
},
{
type: 'text',
fieldName: 'StageName',
label: 'Opportunity Status'
} ];
gridData;
error;
searchKey;
handleKeyChange( event ) {
this.searchKey = event.target.value;
}
handleSearch() {
console.log( 'Search Key is ' + this.searchKey );
if ( this.searchKey ) {
fetchAccounts( { searchKey: this.searchKey } )
.then( result => {
console.log( 'Retrieved data is ' + JSON.stringify( result ) );
let tempData = JSON.parse( JSON.stringify( result ) );
for ( let i = 0; i < tempData.length; i++ ) {
let cons = tempData[ i ][ "Contacts" ];
delete tempData[ i ][ "Contacts" ];
let childRecords = cons ? cons : [];
let opps = tempData[ i ][ "Opportunities" ];
for ( let opp in opps ) {
opps[ opp ].OpptyName = opps [ opp ].Name;
delete opps [ opp ].Name;
childRecords.push( opps[ opp ] );
}
delete tempData[ i ][ "Opportunities" ];
console.log( 'Child Records ' + JSON.stringify( childRecords ) );
tempData[ i ]._children = childRecords;
}
console.log( 'Final Data ' + JSON.stringify( tempData ) );
this.gridData = tempData;
} )
.catch( error => {
this.error = error;
} );
} else {
this.gridData = undefined;
}
}
}
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: