Skip to main content

Nested Accordion in Salesforce LWC



Are you new to LWC ? Are you wondering how to loop in and make a nested accordion in LWC.?
No worries. You are are at the right place.

Today in this blog we will go through this simple requirement. We will see how we can loop and use lightning-accordion in our code.

Use Case:
Use case is very Simple . We need to Print all Contacts which are related to a particular account . We have done this several times using different methods. But in this blog we will see how we can use map to get Account Name as Key and the related contacts as the Value.

It will have learn following in this blog:
  • How to create Key map to pull all the Account Records which has atleast one Contact in key:value fashion.
  • How to use Wire service to pull data.
  • How to use Lightning Accordion.
Let us jump into code now.

Solution:
Apex Controller

In this Apex Class we are fetching all Contact records and the Account Name to which it is associated. We are then creating a map of Type Map<String, List<Contact>>. This will contain Account name as String and List<Contact> will have contact records.

And finally we are returning “JSON.serialize(lstaccContWrapper);”
This means we are returning JSON in String type.

NestedAccordionController.cls
public without sharing class NestedAccordionController {
    public NestedAccordionController() {

    }

    @AuraEnabled(Cacheable = true)
    public static String fetchAccContactRecords(){ 
        List<Contact> contactRecords = new list<Contact>();
        contactRecords = [SELECT Id,Name,Account.Name,Phone                           
                            FROM Contact];

        List<AccountContactWrapper> lstaccContWrapper = new List<AccountContactWrapper>();
        Map<StringList<Contact>> mapAccNameContactRec = new Map<StringList<Contact>>();

        for (Contact con: contactRecords) {                                         
            if(String.isNotBlank(con.Account.Name)) {
                String mapKey = con.Account.Name;
                if(!mapAccNameContactRec.containsKey(mapKey)) {
                    mapAccNameContactRec.put(mapKey, new List<Contact>());
                }
                mapAccNameContactRec.get(mapKey).add(con);
            }
        }

        System.debug('mapAccNameContactRec '+mapAccNameContactRec);

        for(String name : mapAccNameContactRec?.keySet()) {
            lstaccContWrapper.add(new AccountContactWrapper(name, mapAccNameContactRec.get(name)));
        }
        return JSON.serialize(lstaccContWrapper);
    }

    public class AccountContactWrapper {
        @AuraEnabled 
        public String Name   { getset; }
        @AuraEnabled 
        public List<Contact> Contacts   { getset; }

        public AccountContactWrapper(String Name,List<Contact> Contacts )
        {
            this.Name = Name;
            this.Contacts = Contacts;
        }
    }
}

In this HTML file we are using for:each to iterate over each record one by one.

nestedAccordion.html
<template>
    <div>
    <template if:true={Accounts}>   
        <div class="slds-m-around_small" style="background-color: lightcoral;">
        <h3><b>List of Accounts and its related Contacts:</b></h3> 
        </div>   <br />
            <lightning-accordion allow-multiple-sections-open ="true">
                <template for:each={Accounts} for:item="acc">
                    <div key={acc.Name} class="slds-m-around_small" style="background-color: rgb(224, 169, 169);">
                     <lightning-accordion-section name={acc.Name} label={acc.Name}>
                        <lightning-accordion allow-multiple-sections-open ="true">
                                <template for:each={acc.Contacts} for:item="con">
                                    <lightning-accordion-section key={con.Name} name={con.Name} label={con.Name}>
                                        <div >
                                           <b>Contact Name: </b> {con.Name}<br />
                                           <b>Contact Phone: </b> {con.Phone}
                                        </div>
                                    </lightning-accordion-section>
                                </template>
                        </lightning-accordion>
                     </lightning-accordion-section>
                     </div>
                </template>               
            </lightning-accordion>
    </template>
  </div>
</template>

Here in the JS file ,we are using @wire service to fetch records from Apex since we are not performing any DML or manipulating any data in Apex

nestedAccordion.js
import { LightningElement,wire } from 'lwc';
import fetchAccContactRecords from '@salesforce/apex/NestedAccordionController.fetchAccContactRecords'
export default class NestedAccordion extends LightningElement {

    Accounts;
    errors;


  @wire(fetchAccContactRecords)
  wiredRecords({error, data}){            
      if ( data ) {
          this.Accounts = JSON.parse(data);
          this.errors = undefined;
      }
      else if( error ) {
          this.Accounts = undefined;
          this.errors = error;
      }
  }
}
Now, In our meta file we are exposing our LWC component in different targets.
 
nestedAccordion.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Nested Accordion Example</masterLabel>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
        <target>lightning__RecordPage</target>
    </targets>
</LightningComponentBundle>

Final Output:



Thanks for reading.!!
#HappyCoding :)


Comments

Popular posts from this blog

How to update Field Level Security in bulk ?

Assign Field Level Security(FLS) in Salesforce Demo:- In this blog we will see the easy way to update Field Level Security(FLS) for Permission sets/Profiles in bulk. I have created a tool to make the Admins job a little easier. Before jumping to tool let us see the different standard approach we follow to update FLS in Salesforce.                     As an admin we usually update FLS from salesforce setup/UI. If we are working on a new Application with many Permission sets and Objects with 100+ fields it can be very time consuming task. Using this tool we can assign FLS in just few mins. Let us take an example. Suppose we have a new application and we have created 20 Permission sets and 8 Profiles . Now there are 10 Objects in all and in each object we have 15 fields for which we need to update FLS for above Permission sets and Profiles. Let us first see the different approach to assign FLS in Salesforce. We have two ways in which we can update FLS for a particular field.  1 .To upd

How to create custom polymorphic field using LWC ?

How to create custom polymorphic field using LWC ? In this blog we will see how we can make polymorphic lookup field using LWC. What is Polymorphic field? A polymorphic field is one where related object might be one of the several different types of objects. There can be a use case where a customer wants to connect one object with multiple objects- i.e, relationships between objects or relate a child object to multiple parents's ojects. For example, in task Object we have three such polymorphic fields. The WhoId(Name) relationship of Task can be with Contact or a Lead. Assigned To field can be a User or a Queue. Similarly, a WhatId(Related To) relationship field of Task can be with many other objects like Accounts, Opportunities etc. In Salesforce, currently we do not have any OOTB option or may be we can say we do not have a datatype for polymorphic field which we can create but if required we can create a custom component to facilitate the same functionality. So let's get

How to use Hyperlink in Custom Toast Notification message using LWC

  Use Hyperlink in Custom Toast Notification message using LWC   We all know that a component can send a toast notification that pops up to alert users of a success, error, or warning. A toast can also simply provide information to the user. But what if we need a hyperlink on the message to navigate to the records on the message body. Yes, we can put Links as well on the message body as we can see in Standard Notification Toasts. This is very simple just we need to remember few things. We should know how to use Navigation Services by using NavigationMixin.GenerateUrl method. Let us see the functionality in this blog. To display a toast notification in Lightning Experience or Experience Builder sites we import ShowToastEvent from the lightning/platformShowToastEvent module. We use this ShowToastEvent to provide feedback to a user following an action, such as after a record is created. Now in this blog we will see how to add hyperlink in the message of the Show Toast event and navig