Sample Code:
Apex Class:
public with sharing class AccountController {
@AuraEnabled( cacheable = true )
public static List< AccountWrapper > fetchAccounts() {
List< AccountWrapper > listWrap = new List< AccountWrapper >();
for ( Account objAcc : [ SELECT Id, Name, Industry, AccountNumber, Rating, Type,
( SELECT Id, FirstName, LastName, Email FROM Contacts )
FROM Account
LIMIT 10 ] ) {
AccountWrapper objWrap = new AccountWrapper( true, objAcc, objAcc.Contacts.size() > 0 ? true : false );
listWrap.add( objWrap );
}
return listWrap;
}
public class AccountWrapper {
@AuraEnabled
public Boolean hideBool;
@AuraEnabled
public Boolean contactBool;
@AuraEnabled
public Account objAccount;
public AccountWrapper( Boolean hideBool, Account objAccount, Boolean contactBool ) {
this.hideBool = hideBool;
this.objAccount = objAccount;
this.contactBool = contactBool;
}
}
}
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 style="padding:2px;">
<lightning-button variant="brand" label="Expand All" onclick={expandAll} class="slds-m-left_x-small"></lightning-button>
<lightning-button variant="brand" label="Collapse All" onclick={collapseAll} class="slds-m-left_x-small"></lightning-button>
</div>
<table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped">
<thead>
<tr class="slds-line-height_reset">
<th>
Account Name
</th>
<th>
Account Number
</th>
<th>
Industry
</th>
<th>
Rating
</th>
<th>
Type
</th>
</tr>
</thead>
<tbody>
<template iterator:it={records}>
<tr class="slds-hint-parent" key={it.value.objAccount.Id} style="cursor: pointer;">
<td data-label="Account Name">
<a href="#" onclick={hideAndShow} data-record-id={it.index} style="display:block;text-decoration:none;color:black;">
{it.value.objAccount.Name}
</a>
</td>
<td data-label="Account Number">
<a href="#" onclick={hideAndShow} data-record-id={it.index} style="display:block;text-decoration:none;color:black;">
{it.value.objAccount.AccountNumber}
</a>
</td>
<td data-label="Industry">
<a href="#" onclick={hideAndShow} data-record-id={it.index} style="display:block;text-decoration:none;color:black;">
{it.value.objAccount.Industry}
</a>
</td>
<td data-label="Rating">
<a href="#" onclick={hideAndShow} data-record-id={it.index} style="display:block;text-decoration:none;color:black;">
{it.value.objAccount.Rating}
</a>
</td>
<td data-label="Type">
<a href="#" onclick={hideAndShow} data-record-id={it.index} style="display:block;text-decoration:none;color:black;">
{it.value.objAccount.Type}
</a>
</td>
</tr>
<template if:false={it.value.hideBool} key={it.value.objAccount.Id} style="padding: 5px;">
<tr key={it.value.objAccount.Id}>
<td colspan="5">
<template if:true={it.value.contactBool}>
<b key={it.value.objAccount.Id}>Contacts found for this Account are below:</b>
<template iterator:it={it.value.objAccount.Contacts}>
<div style="padding:1px;" key={it.value.Id}>
Name: {it.value.FirstName} {it.value.LastName}<br/>
Email: {it.value.Email}
</div>
</template>
</template>
<template if:false={it.value.contactBool}>
<b key={it.value.objAccount.Id}>No Contacts found for this Account!!!</b>
</template>
</td>
</tr>
</template>
</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;
error;
@wire( fetchAccounts )
wiredAccount( { error, data } ) {
if (data) {
console.log( 'Fetched Data ' + JSON.stringify( data ) );
this.records = data;
} else if ( error ) {
this.error = error;
this.records = undefined;
}
}
hideAndShow( event ) {
let indx = event.target.dataset.recordId;
console.log( 'Index is ' + indx );
if ( this.records ) {
let recs = JSON.parse( JSON.stringify( this.records ) );
let currVal = recs[ indx ].hideBool;
console.log( 'Current Val ' + currVal );
recs[ indx ].hideBool = !currVal;
this.records = recs;
console.log( 'After Change ' + this.records[ indx ].hideBool );
}
}
expandAll() {
if ( this.records ) {
let recs = JSON.parse( JSON.stringify( this.records ) );
for ( let rec of recs ) {
rec.hideBool = false;
}
this.records = recs;
}
}
collapseAll() {
if ( this.records ) {
let recs = JSON.parse( JSON.stringify( this.records ) );
for ( let rec of recs ) {
rec.hideBool = true;
}
this.records = recs;
}
}
}
Output: