How to create Custom Reusable Lookup in LWC?

36
3559

Hi Developer, As we all know that LWC is a completely new way to develop the Lightning component and there is a very limited no of resources to learn LWC.

So, here is this tutorial we are going to learn how we can create a Custom Reusable Lookup based on user input.

Setp1:- Create search Component

This component is the one, that enables the search functionality. Use the below code for HTML markup and JavaScript.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<template>
<div class="slds-grid slds-wrap">
<div class="slds-col slds-size_4-of-4">
<div>
<!-- Create an Input Field where user can enter text to find the Records-->
<lightning-input variant="label-hidden" label="Search Record" value={searchKey} type="search" onchange={handleChange} placeholder="type text here"> </lightning-input>
</div>
</div>
</div>
</template>
<template> <div class="slds-grid slds-wrap"> <div class="slds-col slds-size_4-of-4"> <div> <!-- Create an Input Field where user can enter text to find the Records--> <lightning-input variant="label-hidden" label="Search Record" value={searchKey} type="search" onchange={handleChange} placeholder="type text here"> </lightning-input> </div> </div> </div> </template>
<template>
   <div class="slds-grid slds-wrap">
      <div class="slds-col slds-size_4-of-4">
         <div>
            <!-- Create an Input Field where user can enter text to find the Records--> 
            <lightning-input variant="label-hidden" label="Search Record" value={searchKey} type="search" onchange={handleChange} placeholder="type text here"> </lightning-input>
         </div>
      </div>
   </div>
</template>

search.js

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { LightningElement, track } from 'lwc';
export default class Search extends LightningElement {
@track searchKey;
handleChange(event) {
/* eslint-disable no-console */ //console.log('Search Event Started ');
const searchKey = event.target.value; /* eslint-disable no-console */
event.preventDefault();
const searchEvent = new CustomEvent( 'change', {
detail : searchKey
} ); this.dispatchEvent(searchEvent);
}
}
import { LightningElement, track } from 'lwc'; export default class Search extends LightningElement { @track searchKey; handleChange(event) { /* eslint-disable no-console */ //console.log('Search Event Started '); const searchKey = event.target.value; /* eslint-disable no-console */ event.preventDefault(); const searchEvent = new CustomEvent( 'change', { detail : searchKey } ); this.dispatchEvent(searchEvent); } }
import { LightningElement, track } from 'lwc';
export default class Search extends LightningElement {
    @track searchKey;
    handleChange(event) {
    	/* eslint-disable no-console */ //console.log('Search Event Started '); 
    	const searchKey = event.target.value; /* eslint-disable no-console */ 
    	event.preventDefault(); 
    	const searchEvent = new CustomEvent( 'change', { 
    	    detail : searchKey 
    	    
    	} ); this.dispatchEvent(searchEvent); 
    } 
}

 

Step2: – Create recordList component

In this component, we will display the list of all the records which will be returned matching the entered text. Here is the code for the HTML markup & JavaScript Class.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<template>
<!--<a href="JavaScript:Void(0)" style="text-decoration:none;" onclick={handleSelect}> <lightning-layout> <lightning-layout-item> <lightning-icon icon-name={iconname} size="small"></lightning-icon> </lightning-layout-item> <lightning-layout-item> {record.Name} </lightning-layout-item> </lightning-layout> </a> -->
<div >
<div class="slds-grid slds-wrap slds-dropdown_length-with-icon-7 slds-dropdown_fluid slds-p-left_small" >
<div class="slds-col slds-size_4-of-4 ">
<ul class="slds-listbox slds-listbox_vertical" role="presentation">
<li role="presentation" class="slds-listbox__item">
<div class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option" onclick={handleSelect}>
<span class="slds-media__figure slds-listbox__option-icon">
<lightning-icon icon-name={iconname} size="small"></lightning-icon>
</span>
<span class="slds-media__body" style="padding-top: 9px;font-weight: 600;"> <span class="slds-listbox__option-text slds-listbox__option-text_entity"> {record.Name} </span> </span>
</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<template> <!--<a href="JavaScript:Void(0)" style="text-decoration:none;" onclick={handleSelect}> <lightning-layout> <lightning-layout-item> <lightning-icon icon-name={iconname} size="small"></lightning-icon> </lightning-layout-item> <lightning-layout-item> {record.Name} </lightning-layout-item> </lightning-layout> </a> --> <div > <div class="slds-grid slds-wrap slds-dropdown_length-with-icon-7 slds-dropdown_fluid slds-p-left_small" > <div class="slds-col slds-size_4-of-4 "> <ul class="slds-listbox slds-listbox_vertical" role="presentation"> <li role="presentation" class="slds-listbox__item"> <div class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option" onclick={handleSelect}> <span class="slds-media__figure slds-listbox__option-icon"> <lightning-icon icon-name={iconname} size="small"></lightning-icon> </span> <span class="slds-media__body" style="padding-top: 9px;font-weight: 600;"> <span class="slds-listbox__option-text slds-listbox__option-text_entity"> {record.Name} </span> </span> </div> </li> </ul> </div> </div> </div> </template>
<template>
   <!--<a href="JavaScript:Void(0)" style="text-decoration:none;" onclick={handleSelect}> <lightning-layout> <lightning-layout-item> <lightning-icon icon-name={iconname} size="small"></lightning-icon>    </lightning-layout-item> <lightning-layout-item> {record.Name} </lightning-layout-item> </lightning-layout> </a> --> 
   <div >
      <div class="slds-grid slds-wrap slds-dropdown_length-with-icon-7 slds-dropdown_fluid slds-p-left_small" >
         <div class="slds-col slds-size_4-of-4 ">
            <ul class="slds-listbox slds-listbox_vertical" role="presentation">
               <li role="presentation" class="slds-listbox__item">
                  <div class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option" onclick={handleSelect}>
                     <span class="slds-media__figure slds-listbox__option-icon">
                        <lightning-icon icon-name={iconname} size="small"></lightning-icon>
                     </span>
                     <span class="slds-media__body" style="padding-top: 9px;font-weight: 600;"> <span class="slds-listbox__option-text slds-listbox__option-text_entity"> {record.Name} </span> </span> 
                  </div>
               </li>
            </ul>
         </div>
      </div>
   </div>
</template>

recordList.js

import { LightningElement, api } from 'lwc';

export default class RecordList extends LightningElement {
    @api record;
    @api fieldname;
    @api iconname;

    handleSelect(event){
        event.preventDefault();
        const selectedRecord = new CustomEvent(
            "select",
            {
                detail : this.record.Id
            }
        );
        /* eslint-disable no-console */
        //console.log( this.record.Id);
        /* fire the event to be handled on the Parent Component */
        this.dispatchEvent(selectedRecord);
    }
}

Step3: – Create customLookup Component

The main component will contain both the component searchComponent and recordList component and also, be responsible for calling the apex method.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<template>
<template if:false={selectedRecord}>
<div class="slds-p-around_x-small">
<c-search
onchange={handleOnchange}>
</c-search>
</div>
</template>
<div >
<template if:true={error}>
<template if:true={error.details}>
<template if:true={error.details.body}>
{error.details.body.message}
</template>
</template>
</template>
</div>
<div>
<template if:false={selectedRecord}>
<template if:true={records}>
<template for:each={records} for:item="record">
<c-record-list key={record.Id} record={record}
onselect={handleSelect} iconname={iconname}
fieldname={searchfield}>
</c-record-list>
</template>
</template>
</template>
<template if:false={selectedRecord}>
</template>
</div>
<div class="slds-p-around_x-small">
<template if:true={selectedRecord}>
<div class="slds-form-element">
<label if:false={showLabel} class="slds-form-element__label" for="combobox-id-5" id="combobox-label-id-32">{objectName}</label>
<div class="slds-form-element__control">
<div class="slds-combobox_container slds-has-selection">
<div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click">
<div 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={objectName}>
<svg class="slds-icon slds-icon_small" aria-hidden="true">
<use xlink:href={iconUrl}></use>
</svg>
</span>
<button type="button" class="slds-input_faux slds-combobox__input slds-combobox__input-value" aria-labelledby="combobox-label-id-32 combobox-id-5-selected-value" id="combobox-id-5-selected-value" aria-controls="listbox-id-5" aria-expanded="false"
aria-haspopup="listbox">
<span class="slds-truncate" id="combobox-value-id-19">
{selectedRecord.Name}
</span>
</button>
<button onclick={handleRemove} class="slds-button slds-button_icon slds-input__icon slds-input__icon_right" title="Remove selected option">
<svg class="slds-button__icon" aria-hidden="true">
<use xlink:href="/apexpages/slds/latest/assets/icons/utility-sprite/svg/symbols.svg#close"></use>
</svg>
<span class="slds-assistive-text">Remove selected option</span>
</button>
</div>
</div>
</div>
</div>
</div>
</template>
</div>
</template>
<template> <template if:false={selectedRecord}> <div class="slds-p-around_x-small"> <c-search onchange={handleOnchange}> </c-search> </div> </template> <div > <template if:true={error}> <template if:true={error.details}> <template if:true={error.details.body}> {error.details.body.message} </template> </template> </template> </div> <div> <template if:false={selectedRecord}> <template if:true={records}> <template for:each={records} for:item="record"> <c-record-list key={record.Id} record={record} onselect={handleSelect} iconname={iconname} fieldname={searchfield}> </c-record-list> </template> </template> </template> <template if:false={selectedRecord}> </template> </div> <div class="slds-p-around_x-small"> <template if:true={selectedRecord}> <div class="slds-form-element"> <label if:false={showLabel} class="slds-form-element__label" for="combobox-id-5" id="combobox-label-id-32">{objectName}</label> <div class="slds-form-element__control"> <div class="slds-combobox_container slds-has-selection"> <div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click"> <div 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={objectName}> <svg class="slds-icon slds-icon_small" aria-hidden="true"> <use xlink:href={iconUrl}></use> </svg> </span> <button type="button" class="slds-input_faux slds-combobox__input slds-combobox__input-value" aria-labelledby="combobox-label-id-32 combobox-id-5-selected-value" id="combobox-id-5-selected-value" aria-controls="listbox-id-5" aria-expanded="false" aria-haspopup="listbox"> <span class="slds-truncate" id="combobox-value-id-19"> {selectedRecord.Name} </span> </button> <button onclick={handleRemove} class="slds-button slds-button_icon slds-input__icon slds-input__icon_right" title="Remove selected option"> <svg class="slds-button__icon" aria-hidden="true"> <use xlink:href="/apexpages/slds/latest/assets/icons/utility-sprite/svg/symbols.svg#close"></use> </svg> <span class="slds-assistive-text">Remove selected option</span> </button> </div> </div> </div> </div> </div> </template> </div> </template>
<template>
    <template if:false={selectedRecord}>
        <div class="slds-p-around_x-small">
            <c-search 
                onchange={handleOnchange}>
            </c-search>
        </div>
    </template>
    <div >
        <template if:true={error}>
            <template if:true={error.details}>
                <template if:true={error.details.body}>
                    {error.details.body.message}
                </template>
            </template>
        </template>
    </div>
    <div>
        <template if:false={selectedRecord}>
            <template if:true={records}>
                <template for:each={records} for:item="record">
                    <c-record-list key={record.Id} record={record} 
                        onselect={handleSelect} iconname={iconname}
                        fieldname={searchfield}>
                    </c-record-list>
                </template>
            </template>
        </template>
        <template if:false={selectedRecord}>
        </template>
    </div>
    <div class="slds-p-around_x-small">
        <template if:true={selectedRecord}>

            <div class="slds-form-element">
                <label if:false={showLabel} class="slds-form-element__label" for="combobox-id-5" id="combobox-label-id-32">{objectName}</label>
                <div class="slds-form-element__control">
                    <div class="slds-combobox_container slds-has-selection">
                        <div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click">
                            <div 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={objectName}>
                                    <svg class="slds-icon slds-icon_small" aria-hidden="true">
                                        <use xlink:href={iconUrl}></use>
                                    </svg>
                                </span>
                                <button type="button" class="slds-input_faux slds-combobox__input slds-combobox__input-value" aria-labelledby="combobox-label-id-32 combobox-id-5-selected-value" id="combobox-id-5-selected-value" aria-controls="listbox-id-5" aria-expanded="false"
                                    aria-haspopup="listbox">
                                    <span class="slds-truncate" id="combobox-value-id-19">
                                        {selectedRecord.Name}
                                    </span>
                                </button>
                                <button onclick={handleRemove} class="slds-button slds-button_icon slds-input__icon slds-input__icon_right" title="Remove selected option">
                                    <svg class="slds-button__icon" aria-hidden="true">
                                        <use xlink:href="/apexpages/slds/latest/assets/icons/utility-sprite/svg/symbols.svg#close"></use>
                                    </svg>
                                    <span class="slds-assistive-text">Remove selected option</span>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </template>
    </div>
</template>

customLookup.js

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { LightningElement, track, api } from 'lwc';
import findRecords from '@salesforce/apex/CustomLookupController.findRecords';
export default class CustomLookup extends LightningElement {
@track records;
@track error;
@track selectedRecord;
@api index;
@api relationshipfield;
@api iconname = "standard:account";
@api objectName = 'Account';
@api searchfield = 'Name';
@api showLabel = false;
iconUrl;
ICON_URL = '/apexpages/slds/latest/assets/icons/{0}-sprite/svg/symbols.svg#{1}';
connectedCallback() {
this.iconUrl = '';
let icons = this.iconname.split(':');
this.iconUrl = this.ICON_URL.replace('{0}', icons[0]);
this.iconUrl = this.iconUrl.replace('{1}', icons[1]);
console.log(this.iconUrl);
}
handleOnchange(event) {
//event.preventDefault();
const searchKey = event.detail.value;
findRecords({
searchKey: searchKey,
objectName: this.objectName,
searchField: this.searchfield
})
.then(result => {
this.records = result;
for (let i = 0; i < this.records.length; i++) {
const rec = this.records[i];
this.records[i].Name = rec[this.searchfield];
}
this.error = undefined;
//console.log(' records ', this.records);
})
.catch(error => {
this.error = error;
this.records = undefined;
});
}
handleSelect(event) {
const selectedRecordId = event.detail;
/* eslint-disable no-console*/
this.selectedRecord = this.records.find(record => record.Id === selectedRecordId);
/* fire the event with the value of RecordId for the Selected RecordId */
const selectedRecordEvent = new CustomEvent(
"selectedrec",
{
//detail : selectedRecordId
detail: { recordId: selectedRecordId, index: this.index, relationshipfield: this.relationshipfield }
}
);
this.dispatchEvent(selectedRecordEvent);
}
handleRemove(event) {
event.preventDefault();
this.selectedRecord = undefined;
this.records = undefined;
this.error = undefined;
/* fire the event with the value of undefined for the Selected RecordId */
const selectedRecordEvent = new CustomEvent(
"selectedrec",
{
detail: { recordId: undefined, index: this.index, relationshipfield: this.relationshipfield }
}
);
this.dispatchEvent(selectedRecordEvent);
}
}
import { LightningElement, track, api } from 'lwc'; import findRecords from '@salesforce/apex/CustomLookupController.findRecords'; export default class CustomLookup extends LightningElement { @track records; @track error; @track selectedRecord; @api index; @api relationshipfield; @api iconname = "standard:account"; @api objectName = 'Account'; @api searchfield = 'Name'; @api showLabel = false; iconUrl; ICON_URL = '/apexpages/slds/latest/assets/icons/{0}-sprite/svg/symbols.svg#{1}'; connectedCallback() { this.iconUrl = ''; let icons = this.iconname.split(':'); this.iconUrl = this.ICON_URL.replace('{0}', icons[0]); this.iconUrl = this.iconUrl.replace('{1}', icons[1]); console.log(this.iconUrl); } handleOnchange(event) { //event.preventDefault(); const searchKey = event.detail.value; findRecords({ searchKey: searchKey, objectName: this.objectName, searchField: this.searchfield }) .then(result => { this.records = result; for (let i = 0; i < this.records.length; i++) { const rec = this.records[i]; this.records[i].Name = rec[this.searchfield]; } this.error = undefined; //console.log(' records ', this.records); }) .catch(error => { this.error = error; this.records = undefined; }); } handleSelect(event) { const selectedRecordId = event.detail; /* eslint-disable no-console*/ this.selectedRecord = this.records.find(record => record.Id === selectedRecordId); /* fire the event with the value of RecordId for the Selected RecordId */ const selectedRecordEvent = new CustomEvent( "selectedrec", { //detail : selectedRecordId detail: { recordId: selectedRecordId, index: this.index, relationshipfield: this.relationshipfield } } ); this.dispatchEvent(selectedRecordEvent); } handleRemove(event) { event.preventDefault(); this.selectedRecord = undefined; this.records = undefined; this.error = undefined; /* fire the event with the value of undefined for the Selected RecordId */ const selectedRecordEvent = new CustomEvent( "selectedrec", { detail: { recordId: undefined, index: this.index, relationshipfield: this.relationshipfield } } ); this.dispatchEvent(selectedRecordEvent); } }
import { LightningElement, track, api } from 'lwc';
import findRecords from '@salesforce/apex/CustomLookupController.findRecords';
export default class CustomLookup extends LightningElement {
    @track records;
    @track error;
    @track selectedRecord;
    @api index;
    @api relationshipfield;
    @api iconname = "standard:account";
    @api objectName = 'Account';
    @api searchfield = 'Name';
    @api showLabel = false;
    iconUrl;

    ICON_URL = '/apexpages/slds/latest/assets/icons/{0}-sprite/svg/symbols.svg#{1}';

    connectedCallback() {
        this.iconUrl = '';
        let icons = this.iconname.split(':');
        this.iconUrl = this.ICON_URL.replace('{0}', icons[0]);
        this.iconUrl = this.iconUrl.replace('{1}', icons[1]);
        console.log(this.iconUrl);
    }

    handleOnchange(event) {
        //event.preventDefault();
        const searchKey = event.detail.value;
        findRecords({
            searchKey: searchKey,
            objectName: this.objectName,
            searchField: this.searchfield
        })
            .then(result => {
                this.records = result;
                for (let i = 0; i < this.records.length; i++) {
                    const rec = this.records[i];
                    this.records[i].Name = rec[this.searchfield];
                }
                this.error = undefined;
                //console.log(' records ', this.records);
            })
            .catch(error => {
                this.error = error;
                this.records = undefined;
            });
    }
    handleSelect(event) {
        const selectedRecordId = event.detail;
        /* eslint-disable no-console*/
        this.selectedRecord = this.records.find(record => record.Id === selectedRecordId);
        /* fire the event with the value of RecordId for the Selected RecordId */
        const selectedRecordEvent = new CustomEvent(
            "selectedrec",
            {
                //detail : selectedRecordId
                detail: { recordId: selectedRecordId, index: this.index, relationshipfield: this.relationshipfield }
            }
        );
        this.dispatchEvent(selectedRecordEvent);
    }

    handleRemove(event) {
        event.preventDefault();
        this.selectedRecord = undefined;
        this.records = undefined;
        this.error = undefined;
        /* fire the event with the value of undefined for the Selected RecordId */
        const selectedRecordEvent = new CustomEvent(
            "selectedrec",
            {
                detail: { recordId: undefined, index: this.index, relationshipfield: this.relationshipfield }
            }
        );
        this.dispatchEvent(selectedRecordEvent);
    }


}

Step4:- Create CustomLookupController Apex class

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
public with sharing class CustomLookupController {
public CustomLookupController() {}
@AuraEnabled(cacheable = true) public static List < SObject > findRecords(String searchKey, String objectName, String searchField) {
String key = '%' + searchKey + '%';
String QUERY = 'Select Id, ' + searchField + ' From ' + objectName + ' Where ' + searchField + ' LIKE :key';
System.debug(System.LoggingLevel.DEBUG, QUERY);
List < SObject > sObjectList = Database.query(QUERY);
return sObjectList;
}
}
public with sharing class CustomLookupController { public CustomLookupController() {} @AuraEnabled(cacheable = true) public static List < SObject > findRecords(String searchKey, String objectName, String searchField) { String key = '%' + searchKey + '%'; String QUERY = 'Select Id, ' + searchField + ' From ' + objectName + ' Where ' + searchField + ' LIKE :key'; System.debug(System.LoggingLevel.DEBUG, QUERY); List < SObject > sObjectList = Database.query(QUERY); return sObjectList; } }
public with sharing class CustomLookupController {
    public CustomLookupController() {}
    @AuraEnabled(cacheable = true) public static List < SObject > findRecords(String searchKey, String objectName, String searchField) {
        String key = '%' + searchKey + '%';
        String QUERY = 'Select Id, ' + searchField + ' From ' + objectName + ' Where ' + searchField + ' LIKE :key';
        System.debug(System.LoggingLevel.DEBUG, QUERY);
        List < SObject > sObjectList = Database.query(QUERY);
        return sObjectList;
    }
}

Step5:- Create a Demo App and test lookup

To test in LWC Use the below code

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<template>
<lightning-card variant="Narrow" title="Hello" icon-name="standard:contact">
<c-custom-lookup iconname="standard:contact"
object-name="Contact"
searchfield="Name">
</c-custom-lookup>
</lightning-card>
</template>
<template> <lightning-card variant="Narrow" title="Hello" icon-name="standard:contact"> <c-custom-lookup iconname="standard:contact" object-name="Contact" searchfield="Name"> </c-custom-lookup> </lightning-card> </template>
<template>
    <lightning-card  variant="Narrow"  title="Hello" icon-name="standard:contact">
        <c-custom-lookup iconname="standard:contact" 
            object-name="Contact"
            searchfield="Name">
        </c-custom-lookup>
    </lightning-card>
</template>

To test in Aura Component use the below code

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<aura:application extends="force:slds">
<c:customLookup iconname="standard:case" objectName="Case" searchfield="CaseNumber"/>
</aura:application>
<aura:application extends="force:slds"> <c:customLookup iconname="standard:case" objectName="Case" searchfield="CaseNumber"/> </aura:application>
<aura:application extends="force:slds"> 
<c:customLookup iconname="standard:case" objectName="Case" searchfield="CaseNumber"/> 
</aura:application>

 

If you have any Queries or Suggestions DM me @cloudyamit or email me @ sfdcpanther@gmail.com

Happy Learning  🙂 😉

#SFDCPanther #Trailblazer

36 COMMENTS

    • For this you need to add one more action to the List say it New Record and once use clicks on that open a pop for creating a new record and after saving the record get the Record Id, dispatch an event and then handle in the parent component. Seems complex yes it is but this is the approach you can follow.

  1. Hi Amit,
    How do I use this component inside a LWC.

    I called customLookup and passed three values which you are passing in app, but it is not appearing in my app page.

    Pls help.

  2. Amit,

    Great work on this. One small suggestion for your Demo App is to show how to retrieve the data:

    DemoApp:

    DemoAppController.js
    ({
    handleSelectedRec : function(component, event, helper)
    {
    console.log(“Selected Record Id: ” + event.getParam(“recordId”));
    }
    })

  3. Hello SFDC Panther,

    First of all, thanks for a good post to do this workaround for lookup fields.

    I can see that you tried to create an Aura Application in the last step, in order to showcase the custom lookup component to drive the functionality.

    Instead of that, i created a LWC itself having the following code:

    Then i displayed the LWC on the Lightning App Page (One Region)

    However, i noticed, that when i am typing some keyword, it does not do a search, of records, but whenever i press a backspace, i would get the list of records.

    For Example:
    If i open the page and type keyword “Uni” to search for list of records, i wont get any search results, but whenever i press the backspace on the keyboard resulting in searching for “Un” then the list of records appear.

    I noticed that there is some issue here:
    .then(result => {
    this.records = result;
    for(let i=0; i < this.records.length; i++) {
    this.records[i].Name = this.records[i][this.searchfield];
    }

    In the custom lookup js class.

    I wanted to know if you came across this?

    Thanks mate!

    • Hey Rajat,

      I used application to show the output as we can not create the application in LWC and you used the component in Lightning Page in both ways the goal is being achieved 🙂

      Thanks,
      SFDCPanther

    • we can make use of map function in order to fix that issue

      .then(result => {
      this.records = result;
      if (result && result.length){
      this.records = result.map((rec)=> {
      return {
      ...rec,
      Name: rec[this.searchfield]
      }
      });
      }

      // for (let i = 0; i < this.records.length; i++) {
      // const rec = this.records[i];
      // this.records[i].Name = rec[this.searchfield];
      // }
      this.error = undefined;
      //console.log(' records ', this.records);
      })

  4. Further to my comment before, i noticed, that if you remove the (cacheable=true) in the Apex class, the code starts working, without giving the backspace in order to create results (you may want to check this, by just using LWC instead of an aura application right at the end.)

    The other question i still have is, that whenever events are dispatched from the search component captured by the custom component, it appears that the event is being captured twice and not once.

    Let me know if there is any way to share screen shots of the console log of the screen

    • Yeah, I removed cacheable and it starts working thanks for the catch. For the event thing, it’s very strange but it might be as the event is being dispatched on the change of the input so every time you type an input it will dispatch the event. Let me know if this is the case.

      Thanks,
      SFDCPanther

  5. Hi,
    I’m new with event handling.
    I know when we dispatch event from a child component, parent component get that event.
    But here in the Custom Lookup component, we are dispatching a custom event: this.dispatchEvent(selectedRecordEvent);
    What is this for?

    Thanks in Advance

    • Hey Jayant,

      Once we will be using this component inside any component in real-time then we need to get the selected record Id. This event will be handled by the parent component of Custom Lookup Component.

      Hope this clears your doubt.

      Thanks & Regards,
      SFDCPanther

    • Hi Anuj,

      You can definitely do that but for that, you have to make the changes in the List Component and in the Parent Component. In the child, component sends the Index no while using a component inside the parent component and while firing the event on select send the index no as well.

  6. How would I go about returning additional fields in addition to the name? I have added MailingAddress to the Query but Im not sure how to get these values to show up in the list of records

  7. Hi SFDC PANTHER,
    I wanted to create a custom lookup for custom objects as well, but it is not giving any output.
    Please help.

    Thanks in Advance,
    Ishita

  8. Hi SFDC PANTHER,
    I want to use the same kind of lookup but for custom objects and search can happen on custom fields or standard fields but even after entering the custom field name in searchField key, its giving me value from Name only.
    Please help.

LEAVE A REPLY

Please enter your comment!
Please enter your name here