Friday, June 4, 2021

Lookup LWC



It's always taken a challenge by the Salesforce developers whenever a lookup component is needed to be added inside a component.

I have built a custom, easy solution on LWC that can be used anywhere.

LookupCMP.html

<template>
    <div class="slds-m-bottom_small slds-m-top_x-large">
        <lightning-card>
            <div class="slds-align_absolute-center">
                <lightning-layout>
                    <lightning-layout-item class="slds-p-left_small">
                        <lightning-icon icon-name="utility:salesforce1">
                        </lightning-icon>
                    </lightning-layout-item>
                    <lightning-layout-item>
                        <p class="slds-p-horizontal_small">
                            <b>Lookup to Account</b>
                        </p>
                    </lightning-layout-item>
                </lightning-layout>
            </div>
        </lightning-card>
    </div>

    <div class="slds-align_absolute-center">
        <lightning-card>
            <lightning-layout>
                <lightning-layout-item class="slds-m-around_small">
                    <lightning-input value={nameVar}
                                        variant="label-hidden"
                                        type="text" 
                                        placeholder="Account Name"
                                        autocomplete="none"
                                        data-field="accountLookup"
                                        onchange={handleAccNameChange}>
                    </lightning-input>
                    <template for:each={accounts} for:item="account" 
                             if:true={isAccountFound}>
                        <div key={account.value} id={account.value}
                            onclick={handleAccountSelection}>
                            <h3 title={account.value}
                                class="slds-border_bottom">
                                    {account.label}
                            </h3>
                        </div>
                    </template>
                </lightning-layout-item> 
                
                <lightning-layout-item class="slds-m-around_small"
                                       if:true={isAccountSelected}>
                    <table>
                        <tbody>
                            <tr>
                                <td><b>Selected Account Name : &nbsp;&nbsp;</b></td>
                                <td>{accountName}</td>
                            </tr>
                            <tr>
                                <td><b>Selected Account Id : &nbsp;&nbsp;</b></td>
                                <td>{accountId}</td>
                            </tr>
                        </tbody>
                    </table>
                </lightning-layout-item>
            </lightning-layout>
        </lightning-card>
    </div>
</template>

LookupCMP.js

import { LightningElementapi } from 'lwc';
import getAccounts from '@salesforce/apex/LookupController.fetchAccounts';

export default class LookupCMP extends LightningElement {
    nameVar = '';
    accounts = [];
    isAccountFound = false;
    accountName = '';
    accountId = '';
    isAccountSelected = false;

    //Onchange handler when Account name is entered by a user
    handleAccNameChange(event) {
        this.isAccountSelected = false;
        this.nameVar = event.target.value;
        this.getAccountsWithName();
    }
    
    //Imperatiev Apex method call for displaying the list of Account with the value entered
    getAccountsWithName() {
        getAccounts( { searchString : this.nameVar } )
        .then(result => {
            this.accounts = [];
            if(result.length > 0) {
                result.forEach(elem => {
                    let accVar = {
                        label : elem.Name,
                        value : elem.Id
                    };
                    this.accounts.push(accVar);
                });
            }
            this.isAccountFound = true;
        })
        .catch(error => {
            this.isAccountFound = false;
        });
    }

    //Handler method when an Account is selected
    handleAccountSelection(event) {
        let accountId = event.target.title;
        this.accounts.forEach(elem => {
            if(elem.value == accountId) {
                this.nameVar = elem.label;
            }
        });
        this.isAccountFound = false;
        this.accountName = this.nameVar;
        this.accountId = accountId;
        this.isAccountSelected = true;
        //Fire a custom event to send the data to a parent component
    }
}

LookupController.cls

//Method for fetching Accounts per the searchString provided
@AuraEnabled
public static List<AccountfetchAccounts(String searchString) {
    List<Accountaccounts = new List<Account>();
    try{
        String keyStr = '';
        if(!String.isBlank(searchString)) {
            keyStr = searchString + '%';
        }
        accounts = [SELECT IdName
                    FROM Account
                    WHERE Name LIKE :keyStr
                    ORDER BY Name
                    LIMIT 10];
        return accounts;
    }catch(exception exc) {
        return accounts;
    }
}