Dynamic lookup in LWC
I am sharing code , how to create custom lookup filter in Lightning Web Component
DynamicLookupController.cls
public with sharing class DynamicLookupController {
@AuraEnabled(cacheable=true)
public static List<sobject> findRecords(String searchKey, String objectName) {
string searchText = '\'' + String.escapeSingleQuotes(searchKey) + '%\'';
return Database.query('SELECT Id, Name FROM ' +objectName+ ' WHERE Name LIKE '+searchText+' LIMIT 6');
}
}
dynamicLookUp.html
<template>
<div class="slds-form-element">
<label class="slds-form-element__label" for="combobox-id-2">{lookupLabel}</label>
<div class="slds-form-element__control">
<div class="slds-combobox_container">
<div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open" aria-expanded="true" aria-haspopup="listbox" role="combobox">
<template if:true={selectedValue}>
<div data-key="pilldiv" class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_left-right" role="none">
<span class="slds-icon_container slds-icon-standard-account slds-combobox__input-entity-icon" title="object">
<div class="slds-icon slds-icon_small" aria-hidden="true">
<lightning-icon icon-name={iconName} size="small"></lightning-icon>
</div>
<span class="slds-assistive-text">Record</span>
</span>
<input type="text" class="slds-input slds-combobox__input slds-combobox__input-value" id="combobox-id-5" aria-controls="listbox-id-5" role="textbox" placeholder="Select an Option" readonly value={selectedValue} />
<button class="slds-button slds-button_icon slds-input__icon slds-input__icon_right" onclick={removeRecordOnLookup}
title="Remove selected option">
<span class="slds-button__icon" aria-hidden="true" >
<lightning-icon icon-name="utility:close"
size="xx-Small" class="slds-icon slds-icon slds-icon_x-small slds-icon-text-default" aria-hidden="true"></lightning-icon>
</span>
<span class="slds-assistive-text">Remove selected record</span>
</button>
</div>
</template>
<template if:false={selectedValue}>
<div data-key="searchdiv" class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right" role="none">
<input type="text" onfocusout={onLeave} value={searchKey} onkeyup={handleKeyChange} onchange={handleKeyChange} class="slds-input slds-combobox__input slds-has-focus" id="combobox-id-2" aria-autocomplete="list" aria-controls="listbox-id-2" role="textbox" placeholder="Search..." />
<span class="slds-icon_container slds-icon-utility-search slds-input__icon slds-input__icon_right">
<lightning-icon icon-name="utility:search" size="xx-Small" class="slds-icon slds-icon slds-icon_x-small slds-icon-text-default" aria-hidden="true"></lightning-icon>
</span>
</div>
<template if:true={recordsList}>
<div id="listbox-id-2-venu" data-key="dropdownresult" class="slds-show slds-dropdown slds-dropdown_length-with-icon-7 slds-dropdown_fluid" role="listbox">
<ul class="slds-listbox slds-listbox_vertical" role="presentation" >
<template if:true={message}>
<center> {message}</center>
</template>
<template for:each={recordsList} for:item="record">
<li id={record.Id} key={record.Id} onclick={onRecordSelection} role="presentation" class="slds-listbox__item">
<div data-key={record.Id} data-name={record.Name} class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option">
<span class="slds-media__figure slds-listbox__option-icon">
<span class="slds-icon_container">
<lightning-icon icon-name={iconName} size="small"></lightning-icon>
</span>
</span>
<span class="slds-media__body">
<span data-key={record.Id} data-name={record.Name} class="slds-listbox__option-text slds-listbox__option-text_entity">{record.Name} </span>
</span>
</div>
</li>
</template>
</ul>
</div>
</template>
</template>
</div>
</div>
</div>
</div>
</template>
dynamicLookUp.js
import { LightningElement, track, wire, api } from "lwc";
import findRecords from "@salesforce/apex/DynamicLookupController.findRecords";
export default class DynamicLookUp extends LightningElement {
@track recordsList;
@track searchKey = "";
@api selectedValue;
@api selectedRecordId;
@api objectApiName;
@api iconName;
@api lookupLabel;
@track message;
onLeave(event) {
setTimeout(() => {
this.searchKey = "";
this.recordsList = null;
}, 300);
}
onRecordSelection(event) {
this.selectedRecordId = event.target.dataset.key;
this.selectedValue = event.target.dataset.name;
this.searchKey = "";
this.onSeletedRecordUpdate();
}
handleKeyChange(event) {
const searchKey = event.target.value;
this.searchKey = searchKey;
this.getLookupResult();
}
removeRecordOnLookup(event) {
this.searchKey = "";
this.selectedValue = null;
this.selectedRecordId = null;
this.recordsList = null;
this.onSeletedRecordUpdate();
}
getLookupResult() {
findRecords({ searchKey: this.searchKey, objectName : this.objectApiName })
.then((result) => {
if (result.length===0) {
this.recordsList = [];
this.message = "No Records Found";
} else {
this.recordsList = result;
this.message = "";
}
this.error = undefined;
})
.catch((error) => {
this.error = error;
this.recordsList = undefined;
});
}
onSeletedRecordUpdate(){
const passEventr = new CustomEvent('recordselection', {
detail: { selectedRecordId: this.selectedRecordId, selectedValue: this.selectedValue }
});
this.dispatchEvent(passEventr);
}
}
dynamicLookUp.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>54.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>
Now i am using a new component that’s will display selected record details
lookupContainer.html
<template>
<div class="slds-box">
<c-dynamic-Look-up lookup-label="Account" object-api-name="account" icon-name="standard:account"
onrecordselection={onAccountSelection}></c-dynamic-Look-up>
</div>
<div class="slds-box">
Selected Account Name : {accountName}
Selected Account Id : {accountRecordId}
</div>
</template>
lookupContainer.js
import { LightningElement, track } from 'lwc';
export default class LookupContainer extends LightningElement {
@track accountName;
@track accountRecordId;
onAccountSelection(event){
this.accountName = event.detail.selectedValue;
this.accountRecordId = event.detail.selectedRecordId;
}
}
lookupContainer.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>54.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__RecordPage</target>
</targets>
</LightningComponentBundle>