Custom Lookup in Lightning Web Components

In Salesforce, we use lookup field to connect objects. We can use inputField to show them but sometimes we need our own custom lookup with custom filter. Previously I have created Lookup component in Lightning which you can check here. So today I made that Lightning Web Components (LWC) compatible, and made a Custom Lookup in Lightning Web Components (LWC).

This is how our output will look using Lightning Web Component. UI is similar in both Lightning and Lightning Web Component.

Custom Lookup in Lightning Web Components

So we will now check the code part.


        <h3 slot="title">
            <lightning-icon icon-name="utility:connected_apps" size="small"></lightning-icon>
            Custom Lookup in Lightning Web Components
        <div slot="footer">
            <div class="slds-form-element">
                <div class="slds-form-element__control">
                    <div class="slds-combobox_container">
                        <div class={txtclassname} data-id="resultBox" aria-expanded="false" aria-haspopup="listbox" role="combobox">
                            <div class="slds-form-element__control slds-input-has-icon slds-input-has-icon slds-input-has-icon_left-right" role="none">
                                    <span class="slds-icon_container slds-icon-utility-search slds-input__icon iconheight">
                                        <lightning-icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" icon-name={iconName} size="x-small" alternative-text="icon" ></lightning-icon>
                                <lightning-input required={required} read-only={inputReadOnly} data-id="userinput" label={Label} name="searchText" onchange={searchField} value={selectRecordName} class="leftspace"></lightning-input>
                                <div if:true={iconFlag}>
                                    <span class="slds-icon_container slds-icon-utility-search slds-input__icon slds-input__icon_right iconheight">
                                        <lightning-icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" icon-name="utility:search" size="x-small" alternative-text="icon" ></lightning-icon>
                                <div if:true={clearIconFlag}>
                                    <button class="slds-input__icon slds-input__icon_right slds-button slds-button_icon iconheight" onclick={resetData}>
                                        <lightning-icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" icon-name="utility:clear" size="x-small" alternative-text="icon" ></lightning-icon>
                                        <span class="slds-assistive-text">Clear</span></button>
                            <!-- Second part display result -->
                            <div id="listbox-id-1" class="slds-dropdown slds-dropdown_length-with-icon-7 slds-dropdown_fluid" role="listbox">
                                <ul class="slds-listbox slds-listbox_vertical" role="presentation">
                                    <template for:each={searchRecords} for:item="serecord">
                                        <li role="presentation" class="slds-listbox__item" key={serecord.recId}>
                                            <div data-id={serecord.recId} data-name={serecord.recName} onclick={setSelectedRecord} class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta" role="option">
                                                <span class="slds-media__figure">
                                                    <span class="slds-icon_container slds-icon-standard-account">
                                                        <lightning-icon icon-name={iconName} class="slds-icon slds-icon slds-icon_small slds-icon-text-default" size="x-small"></lightning-icon>
                                                <span class="slds-media__body">
                                                    <span class="slds-listbox__option-text slds-listbox__option-text_entity">{serecord.recName}</span>
                                                    <span class="slds-listbox__option-meta slds-listbox__option-meta_entity">{objectName} • {serecord.recName}</span>
                            <div if:true={messageFlag}>
                                No result found.
                            <div if:true={LoadingText}>


import { LightningElement,wire,api,track } from 'lwc';
import getResults from '@salesforce/apex/lwcCustomLookupController.getResults';

export default class LwcCustomLookup extends LightningElement {
    @api objectName = 'Account';
    @api fieldName = 'Name';
    @api selectRecordId = '';
    @api selectRecordName;
    @api Label;
    @api searchRecords = [];
    @api required = false;
    @api iconName = 'action:new_account'
    @api LoadingText = false;
    @track txtclassname = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click';
    @track messageFlag = false;
    @track iconFlag =  true;
    @track clearIconFlag = false;
    @track inputReadOnly = false;

    searchField(event) {
        var currentText =;
        this.LoadingText = true;
        getResults({ ObjectName: this.objectName, fieldName: this.fieldName, value: currentText  })
        .then(result => {
            this.searchRecords= result;
            this.LoadingText = false;
            this.txtclassname =  result.length > 0 ? 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open' : 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click';
            if(currentText.length > 0 && result.length == 0) {
                this.messageFlag = true;
            else {
                this.messageFlag = false;

            if(this.selectRecordId != null && this.selectRecordId.length > 0) {
                this.iconFlag = false;
                this.clearIconFlag = true;
            else {
                this.iconFlag = true;
                this.clearIconFlag = false;
        .catch(error => {
   setSelectedRecord(event) {
        var currentRecId =;
        var selectName =;
        this.txtclassname =  'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click';
        this.iconFlag = false;
        this.clearIconFlag = true;
        this.selectRecordName =;
        this.selectRecordId = currentRecId;
        this.inputReadOnly = true;
        const selectedEvent = new CustomEvent('selected', { detail: {selectName, currentRecId}, });
        // Dispatches the event.
    resetData(event) {
        this.selectRecordName = "";
        this.selectRecordId = "";
        this.inputReadOnly = false;
        this.iconFlag = true;
        this.clearIconFlag = false;



div input[readonly] {
    padding-left: 1.75rem !important;  
    padding-left: 1.75rem !important;

.slds-input-has-icon .slds-input__icon {
    top: 56% !important;
.slds-icon_small, .slds-icon--small {
    width: 1.5rem;
    height: 1.5rem;
    line-height: 2;

To use this component in your lightning component first declare this component:

<aura:application extends="force:slds">

    <aura:attribute name="selectRecordName" type="String" description="text" ></aura:attribute>
    <aura:attribute name="selectRecordId" type="String" description="text" ></aura:attribute>

    <lightning:card title="">
    	<c:lwcCustomLookup objectName="Account" fieldName="Name" selectRecordId="{!v.selectRecordId}" 
                       selectRecordName="{!v.selectRecordName}" iconName = "action:new_account" onselected="{!c.selectedRecords}"/>
        Selected Record Name: {!v.selectRecordName} <br/>
        Selected Record Id: {!v.selectRecordId}


    selectedRecords : function(component, event, helper) {
        var selectRecName = event.getParam('selectName');
        var selectRecId = event.getParam('currentRecId');
        if(selectRecName != undefined) {
            component.set("v.selectRecordName", selectRecName);
            component.set("v.selectRecordId", selectRecId);

To pass data to parent component, we have used Events. You can read about them in detail here.

Now we will look into code. When user type input we call the controller method, we pass the string and in controller search for related records. We have used Imperative calling. You can read about it here. Then we are using template to iterate the result.

You can find complete code of Custom Lookup in Lightning Web Components in github-repo here.

Did you like the post or have any question, let me know in comments. Happy Programming 🙂


25 thoughts on “Custom Lookup in Lightning Web Components

  1. A nice enhancement would be reading icon info from the SObject itself instead of relying on parent component to pass through. Something along the line of

    @wire(getObjectInfo, { objectApiName: ‘$objectType’ })
    _objectInfo({ data, error }) {
    if (error) { console.error(error); }
    if (data) {
    this._iconColor = ‘background: #’ + data.themeInfo.color;
    this._iconSrc = data.themeInfo.iconUrl


    The above code could be updated to allow parent component to override the SObject default icon if need to.

  2. Instead of just a single record can you show regarding multiple record.Means when we are searching record we are doing it one at time.I want to see the list of searched records below the lookup field

      1. my concern is if we are selecting record from lookup field instead of showing it in combo-box it should have a add,delete and refresh button.if we are clicking the add button it should display below the combo-box in proper format

  3. You have mentioned about using the component, however I’m unable to relate the
    onselected=”{!c.selectedRecords}” part of it. This piece of code is introducing exception. Is there anything that i’m missing.

  4. Hi Tushar,

    I have used your code to replicate the custom lookup functionality.

    I am encountering an error after selecting the lookup value .Please find the below error details.

    Uncaught Unable to find action ‘selectedRecords’ on the controller of harshabr:AccountLookUp

    Please let me know why I am facing this issue.I have copied the code from the github.

      1. Thanks Tushar for the code update.

        I see your below code

        selectedRecords : function(component, event, helper) {
        var selectRecName = event.getParam(‘selRecords’);
        if(selectRecName != undefined) {
        component.set(“v.selectedRecords”, selectRecName);

        Even this is not working.

        What does selReords contains?

        Thanks in advance.

        Harsha BR

          1. Thanks Tushar.

            “Selected Record Name ” value is coming.But “Selected Record Id” is not coming.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.