custom lookup in salesforce lightning

Create Re-Usable Custom Lookup In Salesforce Lightning Component Version 2 : Dynamic

Lightning Component

Last Updated : 1 February 2018

Hi Guys , Today In this post we are going  create a new updated version of our previous post on custom lookup :

 In this post we will create a custom Re-Usable lookup and also create sample example on how to use this custom lookup.

custom lookup component display
Component Output
Prerequisites : basic understanding of Lightning Component. and apex programming

custom lookup in salesforce lightning sfdcmonkey.com

Step 1 : Create Apex Class Controller.
Apex class [customLookUpController.apxc]

  • In above Apex class we have only one @AuraEnabled Method.
  • In this method we have 2 String ‘searchKeyWord’ and ‘ObjectName’ parameter.
  • By this parameter we are find sObject record List and Return the list.
 Step 2 : Create Lightning Event
  • Next we create a Lightning Event bundle for communicate data(attribute values) between different components. (Child To Parent Component )
  • Events are contain attributes that can be set before the event is fired and read when the event is handled by component.

from developer console >> file >> new >> Lightning Event >> enter name >> selectedsObjectRecordEvent >> save

lightning Event [selectedsObjectRecordEvent.evt]

  •  In above Event we have only single attribute which type is sObject type.
  • by this attribute, we are passing the selected Object record to parent component [ CustomLookup ]  by child component[customLookupResult ].

Component Blue Print 

custom lookup in salesforce lightning sfdcmonkey.com

Step 3 : Create Child Component For Display the Search Result List
Lightning Component [customLookupResult.cmp] 

JS Controller [customLookupResultController.js]

  •  See Code Comments.
Step 4 : Create Lightning Custom Lookup Component [Parent]
Lightning Component [customLookup.cmp]

  •  See Code Comments.
JS Controller [customLookupController.js]

  •  See Code Comments.
JS Helper [customLookupHelper.js]

  •  See Code Comments.
Style Tab Code  [customLookup.CSS]

TestApp.app

This is a dynamic Re-Usable Lightning Component you have need to pass the objectAPIName , IconName, selected Record and Field Label Name Attribute when use this Custom Lookup component.
Output : 

custom lookup component display

How to Use –  Example Custom Lookup Component

Now we are create a simple and small Lightning Component to create Contact Record Using custom Account Lookup and Name field.

Apex Controller 

Lightning Component 

JavaScript Controller 

Output :

custom lookup in salesforce lightning sfdcmonkey.com

Related Resources :

https://www.lightningdesignsystem.com/icons/#standard

Salesforce Lightning Design System Lookup

Lightning Component Events

ui:Spinner

Like our facebook page for new post updates. & Don’t forget to bookmark this site for your future reference.

if you have any suggestions or issue with it, you can post in comment box  🙂

(Visited 26,730 times, 26 visits today)

106 comments

    • here is the sample code for required situation//
      ({
      saveContactRecord : function(component, event, helper) {
      var isValid = true;

      var conObj = component.get(“v.objContact”);
      conObj.ParentId = null ;
      if(component.get(“v.selectedLookUpRecord”).Id != undefined){
      conObj.ParentId = component.get(“v.selectedLookUpRecord”).Id;
      }else{
      alert(‘Required : Please Select Record Lookup’);
      isValid = false;
      }
      if(isValid){
      //call apex class method
      var action = component.get(‘c.saveContact’);
      action.setParams({
      ‘con’: conObj
      })
      action.setCallback(this, function(response) {
      //store state of response
      var state = response.getState();
      if (state === “SUCCESS”) {
      alert(‘Record Created’);
      }
      });
      $A.enqueueAction(action);
      }

      }
      })

      Thanks

  • Fantastic post!

    Tried to implement a change owner action for the Case object, how can I click the icon to switch the sObject between Users and Queues?

  • Thank you, this code is really useful can you please help me to understand how to use this code in case of edit record? the problem i am facing is on edit page i am not able to see the account record that i used to create the contact.

    • In Edit scenario you can add method call in INIT of the component to get the current value of the record and then fire the lightning event.It will get the current state of record and dispaly as we have prepopulated it.

  • How to Pre-populate Values in the Lookup , Suppose i am working on Edit mode of a record and if this lookup is having some values already in the back-end , but it is not showing in front end ?

  • Hi
    Thanks for the wonderful explanation and code.
    How can I auto populate some fields(custom fields from the related object) from the lookup object on the input:text field on the component page when lookup is selected by user?
    Please suggest
    Thanks in advance

  • Hi

    I appreciate the work done, It is good lookup for getting the value but i am facing a problem when i am overriding the edit page and cannot auto populate this lookup field to restore the value from database.

    Thanks in Advance.

  • Hi

    It is good lookup for getting the value but i am facing a problem when i am overriding the edit page and cannot auto populate this lookup field to restore the value from database.

    Thanks in Advance.

    • Hi, i needed the same so i include a bit of code, not the prettiest, but it’s a start

      on customlookupcontroller.js i added

      onselectedRecordChange : function (component, event, helper) {

      //var compEvent = component.getEvent(“oSelectedRecordEvent”);
      //compEvent.fire();
      debugger;

      var oldValue = event.getParam(“oldValue”);
      var newValue = event.getParam(“value”);

      console.log(“Old value: ” + oldValue);
      console.log(“Current value: ” + newValue);

      if(oldValue.Id !== newValue.Id){
      component.set(“v.selectedRecord” , event.getParam(“value”));

      var forclose = component.find(“lookup-pill”);
      $A.util.addClass(forclose, ‘slds-show’);
      $A.util.removeClass(forclose, ‘slds-hide’);

      var forclose = component.find(“searchRes”);
      $A.util.addClass(forclose, ‘slds-is-close’);
      $A.util.removeClass(forclose, ‘slds-is-open’);

      var lookUpTarget = component.find(“lookupField”);
      $A.util.addClass(lookUpTarget, ‘slds-hide’);
      $A.util.removeClass(lookUpTarget, ‘slds-show’);
      }

      }

      which is a copy paste from handleComponentEvent,

      on the component i put

        • Are you using the above to get the value from the database on an edit type form? I’m trying the about to do that but no luck. I think I’m looking for a doInit type function but I have tried and can’t get set the value from my component. Any suggestions?

      • Hello,
        I am happy to have this component. As it is very helpful while doing work for Lookup fields in creating/updating records in Salesforce Lightning.

        But I am facing issue while updating records using this Lookup component. As it is not showing the selected Contact/(or any object’s record, selected) as required.

        My scenario is:
        I have three lookup fields of type “User” in an object.
        I have set up my component in such a way that your lookup component is being used in three places (line by line).

        Now, If I click on update button, it should show those three fields populated with three users values coming from database for that selected record.

        So, please tell me about the way using which I can populate the lookup component values for multiple times.

        Thank you,
        Khawaja M. Awais

        • create 3 attribute for each component :

          < aura:attribute name="selectedLookUpRecord1" type="sObject" default="{}" / >
          < aura:attribute name="selectedLookUpRecord2" type="sObject" default="{}" / >
          < aura:attribute name="selectedLookUpRecord3" type="sObject" default="{}" / >

          and bind component with saparate attribute

          Thanks

          • I already have done that, but when I edit a record which has values for these three fields, it should populate these fields (Lookup components). But it is not doing it as desired.

  • Appreciate the post. Helpful for most of the requirements. However, i have a requirement, where i need to be able to select multiple accounts, similar to the name selector in the standard lightning event / task/ log a call. Do you have any suggestions on this ?

     

    • for do this you have need to pass the account id in SOQl where clause : such as .. WHERE AccountId = ‘001XXXXXXXXXXXX’;
      Thanks

  • On selecting a value from lookup, I am getting the id of the record in a alert box popped in the center.

    I checked the whole code and didn’t find any alert message code written.

    Could you please tell me from where it is coming in your code.

     

    Thanks

    • for this you have need to change in lookup component code [js controller], if ‘selectedLookUpRecord’ Id field is not undefined/null then hide the searchbar and show the record pill
      Thanks

      • HI Piyush,

        Can you explain in detail like in which controller method, the above mentioned change has to be made? I am really looking for pre-populating the lookup field value.

      • Can you please explain where we need to do this?

        And it will be a great help if you give some sample code for this?
        Means the event/function where we need to update the code to get fields populated for Edit Functionality?

        Thank you

  • We have Encrypted “Name” field on Contact object, so SOQL doesn’t work from the apex controller. Any suggestions?

    Also, are we expecting out of the box, that is from salesforce, a lookup component, that can be customized on any object in the upcoming release?

  • I think this is only for single field.
    How about Lookup fields for table in every row?

    And how to display already created record by SOQL in table?

    A lot of question, sorry about that.

  • Hi,

    So far no one has face this issue I guess. I am using this component in a page. And after clicking on the component, the result drop down appears. However, if user decides to click some where else on the page (of course not selecting any value from result drop down), the drop down doesn’t retract/disappear. Can you please help me with this issue?

     

    Regards

    • hi Udayvir singh, here is the fix of your issue :
      – Change in Step 4 lightning component on Line Number 20, add below attribute to

      :
      – onmouseleave=”{!c.onblur}”

      – On Line Number 52, add below style attribute to

        – style=”margin-top:0px !important”

        – add below function in clinet side controller :

        onblur : function(component,event,helper){
        if(! component.get(“v.doNotClearSearchText”)){
        component.set(“v.SearchKeyWord”, null);
        }
        component.set(“v.listOfSearchRecords”, null );
        var forclose = component.find(“searchRes”);
        $A.util.addClass(forclose, ‘slds-is-close’);
        $A.util.removeClass(forclose, ‘slds-is-open’);
        },

      • Hi Piyush,

        Line 20 is a DIV tag line and line 52 is comments.
        Can you please copy and paste where this needs to be added?

  • Hi, in customLookupResult.cmp, if I want to show more fields detail in each result, how can I iteration “v.oRecord” object by using <aura:iteration> witout doing like below:

    <span class=”slds-media__body”>
    <span class=”slds-listbox__option-text slds-listbox__option-text_entity”>
    {!v.oRecord.Name}
    </span>
    <span class=”slds-listbox__option-text slds-listbox__option-text_entity”>
    Unit List Price: {!v.oRecord.Unit_List_Price_PS__c}
    </span>
    <span class=”slds-listbox__option-text slds-listbox__option-text_entity”>
    Unit Type: {!v.oRecord.Unit_Type__c}
    </span>
    <span class=”slds-listbox__option-text slds-listbox__option-text_entity”>
    Area: {!v.oRecord.Useable_Area_SqM_PS__c} Sq.m
    </span>
    </span>

  • Hello,

    When I add this code on a record detail page and upon the button click, I have implemented a code such that this lookup component pops up in a Modal. In the modal when I click on the search-box the lookup results area shows but, the entire result component height does not change. There is a scroll bar that shows up along with results. In the standard functionality, the results list looks like they pop out of the lookup component. How do I fix this issue? Any help is highly appreciated.

     

    Thanks,

    Raghu

  • Excellent code, but I am getting a null reference when I try to set the lookup ID. I’ve changed a bit of the code:

    The attribute:

    <aura:attribute name="selectedContactLookupRecord" type="sObject" default="{}"/>

    The component:
    <c:customLookup objectAPIName="contact" IconName="standard:contact" label="Lead Inventor" selectedRecord="{!v.selectedContactLookupRecord}"/>

    The controller action:
    component.set("v.simpleInvention.Lead_Inventor__c", component.get("v.selectedContactLookupRecord").Id);

     

      •  

         

        • Try below code once :

          component.set("v.simpleInvention.Name", '');
          component.set("v.simpleInvention.Working_Title__c", component.find('workingTitle').get("v.value"));
          component.set("v.simpleInvention.Campus__c", component.find('invCampus').get("v.value"));
          var recId = component.get("v.selectedContactLookupRecord.Id");
          alert(recId);
          component.set("v.simpleInvention.Lead_Inventor__c",recId);

  • Excellent code, but I am getting a null reference when I try to set the lookup ID. I’ve changed a bit of the code.

    The attribute:

    <aura:attribute name="selectedContactLookupRecord" type="sObject" default="{}"/>

    The component:
    <c:customLookup objectAPIName="contact" IconName="standard:contact" label="Lead Inventor" selectedRecord="{!v.selectedContactLookupRecord}"/>

    The controller action:
    component.set("v.simpleInvention.Lead_Inventor__c", component.get("v.selectedContactLookupRecord").Id);

    When I try to save I get the message: “Uncaught Action failed: c:inventionCreate$controller$handleSaveInvention [get is not defined]”

  • HI Piyush,

    Can you explain in detail like in which controller method, the above mentioned change has to be made? I am really looking for pre-populating the lookup field value.

  • Hi,

    Great Post, Worked like a charm!!

    Can you tell how to populate value into that lookup on component load.

    Thanks in advance!!

  • How do I set other Contact fields based on the Account that is chosen on the lookup:
    <aura:application extends=“force:slds”>
      <!– Create attribute to store lookup value as a sObject–>
      <aura:attribute name=“selectedLookUpRecord” type=“sObject” default=“{}”/>

      <c:customLookup objectAPIName=“account” IconName=“standard:account” selectedRecord=“{!v.selectedLookUpRecord}” label=“Account Name”/>

    <input type=”checkbox”  label=”Contact Billable” value=”{!v.selectedLookUpRecord.Billable_c}

    </aura:application>
    Is the highlighted part right if I want to pull Billable field from Account and set it on Contact?

  • I already have done that. This working for creation of record.
    But when I edit a record which has values for these three fields, it should populate these fields (Lookup components). But it is not working for this prospect.
    Means it is not auto-populating values in these lookup components..

  • Hi

    I am using this for Contact object and

    would like to populate “Account name” underneath of Contact Name, like standard look up

      • Thanks  for the quick response Piyush… I figured it out quite quickly but in standard look up when we type text and press enter it does open Modal with relevant search result … is there any way  I can extend that.

        Thank you in advance.

  • Piyush, this works great! I am trying to implement a functionality like: ‘+ New Account’ at the the bottom of the search result. Clicking on it should allow me to create a new record on-the-go and append in the field.
    How can I achieve this?
    Thanks

  • Hi Piyush,

    Just wondering, when if I wanted Lookup Required, instead of showing alert I would like to show error message on the filed, I am getting error “Cannot read property ‘set’ of undefined”

    var accLkp = component.find(“v.lookupField”);

    accLkp.set(“v.errors”, [{message: “Account can not be empty”}]);

    thank you in advance

  • Hi

     

    how do i display different value for different sObject results. i.e

    for Contact :  name & Account Name

    for Account : name & Location

    etc.

    <div class=”slds-m-left–smalllabels slds-truncate slds-media__body”>
    <div class=”primaryLabel slds-truncate slds-lookup__result-text”>{!v.oRecord.Name}</div><br/>
    <div class=”slds-lookup__result-meta secondaryLabel slds-truncate slds-text-body–small”>{!v.oRecord.Account.Name}</div>
    </div>
    </aura:if>

    <aura:if isTrue=”{!v.oRecord == ‘Account’}”>
    <div class=”slds-m-left–smalllabels slds-truncate slds-media__body”>
    <div class=”primaryLabel slds-truncate slds-lookup__result-text”>{!v.oRecord.Name}</div><br/>
    <div class=”slds-lookup__result-meta secondaryLabel slds-truncate slds-text-body–small”>{!v.oRecord.Sector__c}</div>
    </div>
    </aura:if>
    <aura:if isTrue=”{!v.oRecord == ‘campaign’}”>
    <div class=”slds-m-left–smalllabels slds-truncate slds-media__body”>
    <div class=”primaryLabel slds-truncate slds-lookup__result-text”>{!v.oRecord.Name}</div><br/>
    </div>
    </aura:if>

     

    thanks in advance

  • can u help me with the multi select lookup? for example- the functionality to search and multi select from a lookup and get related into a list. thanks

    • Hey Sriram, were you able to close the drop down when you click outside? I am also facing the same issue as the drop down would only close if you cleared the text in the search box. Any help would be appreciated.

  • Hi, Great article!

    What change needs to be done if I want to have the option to create new record through lookup field like in the native lightning lookup field?

    Thanks,
    CJ

  • Great Code. But this still cannot be used as a generic lookup. Main reason being the fields.

    For eg: I have a usecase to show user lookup with 3 fields at one place and with 4 fields at another place in the same application. Tried couple of things but still not confident what should be the correct approach there.

    Any suggestions/sample code would be highly appreciated

  • I kind of modified the component to just focus as a custom contact lookup, but I’m having an issue of when I select a record the component just disappears

  • I modified the code a bit just so it focused on contacts, but I’m having an issue where when I select a contact the whole component disappears off of the page.

  • i am unable to set the record id for the lookup fields in edit page

    when i click on edit i am setting the record id to the selectrecord attribute but it is still showing empty in the lookup field

    can any one help me on this , thanks in advance

  • Hi Piyush,
    I have a exiting look up field with some filter. I want to use this field in a visual flow. So I implemented the lightning component as mentioned and its working great. But in this case i have to additionally write the filter criteria for the lightning component. Is there a way which can help me use the existing look up field so that if the filter criteria is changed in the object, it will automatically reflect in the lightning component.

  • I have used this to render the lookup on Visual force page
    Can you please let me know how Can I get the Selected value in VF page

     

  • Hi

    Thank you for your post. It is very helpful

    I have used your custom component in a component of mine that updates contact fields. The problem is if that contact is already associated with an account, the account name doesn’t pre-populate the first time and it looks as if this contact is not associated with an account.

    Any thoughts on that?

    Really appreciate

    • Found a way:

      (1) Create formula fields to get Name field values of the records looked up.
      (2) Populate the “SearchKeyWord” attribute of the lookup components with these formula fields.
      (3) Use the DoInit method of your master component to set any selectedLookUpRecord attributes to the corresponding field values.
      (4) Change the save function to set attributes to said field values instead of null (might be redundant here).

      Works perfectly. Not truly pre-populating, but the effect seems to be exactly the same.

      • Might skip step 3. Looks like just 4 is needed. Example:

        handleUpdateForm: function(component, event, helper) {
        //if(helper.validateContactForm(component)) {

        var recObj = component.get(“v.theRecord”);
        //THIS SECTION NEEDED TO HANDLE CUSTOM LOOKUPS.
        recObj.Patient_Name__c = component.get(“v.theRecord.Patient_Name__c”);
        recObj.Location_of_Incident__c = component.get(“v.theRecord.Location_of_Incident__c”);
        recObj.Name_of_CRP__c = component.get(“v.theRecord.Name_of_CRP__c”);
        // ASSIGN NEW VALUES IF THE LOOKUPS HAVE CHANGED.
        if(component.get(“v.selectedLookUpRecord_Patient”).Id != undefined){
        recObj.Patient_Name__c = component.get(“v.selectedLookUpRecord_Patient”).Id;
        }
        if(component.get(“v.selectedLookUpRecord_HBLocation”).Id != undefined){
        recObj.Location_of_Incident__c = component.get(“v.selectedLookUpRecord_HBLocation”).Id;
        }
        if(component.get(“v.selectedLookUpRecord_CRP”).Id != undefined){
        recObj.Name_of_CRP__c = component.get(“v.selectedLookUpRecord_CRP”).Id;
        }

        // Prepare the action to create / update the new record
        var saveUpdateAction = component.get(“c.saveUpdateRecord”);
        saveUpdateAction.setParams({
        “theSaveRecord”: recObj
        });

        // Configure the response handler for the action
        saveUpdateAction.setCallback(this, function(response) {
        var state = response.getState();
        if(state === “SUCCESS”) {
        var updatedRecord = response.getReturnValue();
        component.set(“v.theRecord”, updatedRecord);
        //OPEN THE MODAL BOX WHICH SUBSTITUTES FOR A TOAST IN LIGHTNING-OUT
        component.set(“v.isOpen”, true);
        }
        else if (state === “ERROR”) {
        console.log(‘Problem saving contact, response state: ‘ + state);
        }
        else {
        console.log(‘Unknown problem, response state: ‘ + state);
        }
        });

        // Send the request to do the insert / update.
        $A.enqueueAction(saveUpdateAction);

        //}

        }

  • Hello,

    Thank you for this wonderful post. I have made some modifications and make it work for my requirement. Although, I have a small problem which I’m unable to find a solution for. In the above example, the only way to choose the result is by clicking on it. I would like to have the ability to use the arrow keys to go through the results and choose using the enter button. If you or anyone on the blog has any solution, please suggest.

    Thanks

    Narsimha Rao

     

  • Hi Admin,

    I want to use auto complete input field which displays country name .I am using billing country of account object for this functionality.

    I  added BillingCity in the Apex controller customLookUpController.apxc

    String sQuery = ‘select id, BillingCity from ‘ +ObjectName + ‘ where BillingCity LIKE: searchKey’;
    List < sObject > lstOfRecords = Database.query(sQuery);

    Calling below code in my component

    <aura:attribute name=“selectedLookUpRecord” type=“sObject” default=“{}”/>

    <c:customLookup objectAPIName=“account” IconName=“standard:account” label=“Billing City”  selectedRecord=“{!v.selectedLookUpRecord}”/>

    Is anything else I need to add to the code you posted .
          
    Thanks in advance

     

     

     

  • Using the code provided I am getting both the magnify glass and X sitting on top of each other when a record is selected in the list of records provided by the lookup results.

    How do I ensure only the magnify glass is present while searching and X is shown when option is selected?

  • Have a Init method in Lookup component and use below logic to auto populate lookup field

    var selRec = component.get(“v.selectedRecord”);
    if(selRec != null && selRec != ” && JSON.stringify(selRec) != ‘{}’) {
    var forclose = component.find(“lookup-pill”);
    $A.util.addClass(forclose, ‘slds-show’);
    $A.util.removeClass(forclose, ‘slds-hide’);

    var lookUpTarget = component.find(“lookupField”);
    $A.util.addClass(lookUpTarget, ‘slds-hide’);
    $A.util.removeClass(lookUpTarget, ‘slds-show’);

    }

    Note you need to map existing sObject  value to the “selectedRecord” attribute in your main component. in my case

    e.g. <c:customLookup objectAPIName=“account” IconName=“standard:account” selectedRecord=“{!v.Test__c.Test1__r}” label=“Account Name”/>

  • I want to display dependent lookup for contact based on selected account. So I used this code for contact custom lookup with filter condition. When I click enter key in this custom contact lookup field, the selected account value was removed.

    so I tried to disable ‘Enter’ key action on keyDown/KeyUp action. But still, it is removing.

    Could you please suggest any solution for this issue?

     

  • Hi,

    Its a great post !!!.

    Thank you for the help for custom Lookup . I need to put a scroll bar in the child component to scroll .

    is this possible in the above scenario ?

     

    Its a great post !!!

      • Hi Piyush,

        Thank you again, I am facing some problem with chrome version 69 which is the latest one.
        Its working fine with chrome version 55 but not showing my lightning component in chrome version 69.

        Could you please help me ?

  • Awesome article SFDCMonkey! Thank you for posting. I have implemented and is working as you have outlined. However, I have found that there can be a bit of a lag when typing due to large number of records and trips to sfdc server. I am considering loading the filtered record set (approx 5000 records) on an initialization and storing in a JSON array. I have been able to fetch and store the list of JSON objects however it’s not clear to me how to filter as user keys in the filter criteria. If you have done this or have seen it elsewhere would you kindly point me in that direction? Thank you!

  • Hi I am trying to implement the lookup component.But When i implemented I have total 13 lookups in the modal in that 3 are referring from the same object.That object has 5 record types.In that 5 i am using three record types ,But when I am  trying to select the value it is showing all the 5 record type value because it is reference by the Same object api name.I want to achieve this by selecting one record type values for one particular  lookup.Let me know if you have any ideas to solve this.

  • I use the lookup component above,When i implementing I have 13  lookups in my modal ,In which I have 3 lookups referencing the same object,That object has 5 record types.So When I rerenced by the object api name .In each of the three lookups  I am able to see all the 5 record type values.I need for each single lookup I have to select particular recordtype value.How to acheive it?

  • I use the lookup component above,When i implementing I have 13  lookups in my modal ,In which I have 3 lookups referencing the same object,That object has 5 record types.So When I rerenced by the object api name .In each of the three lookups  I am able to see all the 5 record type values.I need for each single lookup I have to select particular recordtype value.How to acheive it Please let me know?

  • Really great component to re-use. Thank for sharing. But i am facing small problem, when i am selecting from result, pill don’t display what i selected (i know, its selected, but can no see what i selected). I am new to salesforce lightning, not sure how to fix this issue. can you please help for same?

Leave a Reply