
How to create custom Lookup in lightning component
This Post Is Outdated Due To Some Salesforce New Release update, Please refer below post for reusable custom lightning component
thanks
Create Re-Usable Custom Lookup In Salesforce Lightning Component Version 2 : Dynamic
Prerequisites : basic understanding of Lightning Component.
Step 0 : Create Support SVG Lightning component.
In the first step, we are create a small lightning component, for rendered the SVG icons in our Lookup component.
you can also use this svg component in any of your lightning component for display the SVG icons
- create a new lightning component bundle with Name svg
lightning component [svg.cmp]
<aura:component > <aura:attribute name="class" type="String" description="CSS classname for the SVG element" /> <aura:attribute name="xlinkHref" type="String" description="SLDS icon path. Ex: /assets/icons/utility-sprite/svg/symbols.svg#download" /> <aura:attribute name="aria-hidden" type="String" default="true" description="aria-hidden true or false. defaults to true" /> </aura:component>
next click on the RENDERER tab on lightning component bundle and past below code:
RENDERER.js [svgRenderer.js]
({ render: function(component, helper) { //grab attributes from the component markup var classname = component.get("v.class"); var xlinkhref = component.get("v.xlinkHref"); var ariaHidden = component.get("v.aria-hidden"); //return an svg element w/ the attributes var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute('class', classname); svg.setAttribute('aria-hidden', ariaHidden); svg.innerHTML = '<use xlink:href="'+xlinkhref+'"></use>'; return svg; } })
Yoo… our SVG component is ready for Use… 🙂
now we can display SVG icons from our Design System Zip file (static resources) By using.
<c:svg class="slds-input__icon slds-show" xlinkHref="{!$Resource.SLDS24 + '/assets/icons/utility-sprite/svg/symbols.svg#search'}" /> <!-- here c: is org. namespace prefix-->
Lightning Icon Reference :https://www.lightningdesignsystem.com/icons/
Step 1 : Create Apex Class Controller.
Apex class [lookUpController.apxc]
public class lookUpController { @AuraEnabled public static List < account > fetchAccount(String searchKeyWord) { String searchKey = searchKeyWord + '%'; List < Account > returnList = new List < Account > (); List < Account > lstOfAccount = [select id, Name from account where Name LIKE: searchKey]; for (Account acc: lstOfAccount) { returnList.add(acc); } return returnList; } }
- In above Apex class we have only one @AuraEnabled Method.
- In this method we have one String ‘searchKeyWord’ parameter.
- By this parameter we are find Account 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.
- Events are contain attributes that can be set before the event is fired and read when the event is handled by component.
lightning Event [selectedAccountEvent.evt]
<aura:event type="COMPONENT" description="by this event we are pass the selected account in the parent component"> <aura:attribute name="accountByEvent" type="account"/> </aura:event>
- Â In above Event we have only single attribute which type is Account type.
- by this attribute, we are passing the selected account record to parent component [ customLookup ]Â by child component[customLookupResult ].
COMPONENT BLUEPRINT :
Step 3 : Create Child Component For Display the Search Result List
Lightning Component [customLookupResult.cmp]
<aura:component > <aura:attribute name="oAccount" type="Account" /> <!--Register the component level event--> <aura:registerEvent name="oSelectedAccountEvent" type="c:selectedAccountEvent"/> <li role="presentation"> <span class="slds-lookup__item-action slds-media slds-media--center" id="lookup-option-350" role="option"> <div class="slds-media__body"> <div class="slds-input-has-icon slds-input-has-icon--right"> <c:svg class="slds-input__icon" xlinkHref="{!$Resource.SLDS24 + '/assets/icons/standard-sprite/svg/symbols.svg#account'}" /> <div class="slds-lookup__result-text"><a onclick="{!c.selectAccount}">{!v.oAccount.Name}</a></div> </div> </div> </span> </li> </aura:component>
JS Controller [customLookupResultController.js]
({ selectAccount : function(component, event, helper){ // get the selected Account from list var getSelectAccount = component.get("v.oAccount"); // call the event var compEvent = component.getEvent("oSelectedAccountEvent"); // set the Selected Account to the event attribute. compEvent.setParams({"accountByEvent" : getSelectAccount }); // fire the event compEvent.fire(); }, })
NOTE: Change $Resource.SLDS24 with your SLDS file Name (static resource zip file Name).
Step 4 : Create Lightning Custom Lookup Component
- Create a lightning component bundle with Name customLookup
lightning component [customLookup.cmp]
<aura:component controller="lookUpController" > <!---Use Salesforce Lightning Design System CSS From Static resources--> <ltng:require styles="{!$Resource.SLDS24 + '/assets/styles/salesforce-lightning-design-system.css'}"/> <!--declare attributes--> <aura:attribute name="selectedRecord" type="Account" default="{}" description="Use,for store SELECTED sObject Record"/> <aura:attribute name="listOfSearchRecords" type="Account[]" description="Use,for store the list of search records which returns from apex class"/> <aura:attribute name="SearchKeyWord" type="string"/> <aura:attribute name="Message" type="String" default="Search Result.."/> <!--declare events hendlers--> <aura:handler name="oSelectedAccountEvent" event="c:selectedAccountEvent" action="{!c.handleComponentEvent}"/> <aura:handler event="aura:waiting" action="{!c.showSpinner}"/> <aura:handler event="aura:doneWaiting" action="{!c.hideSpinner}"/> <!-- https://www.lightningdesignsystem.com/components/lookups/ --> <div class="slds-m-around--large"> <div aura:id="searchRes" class="slds-form-element slds-lookup slds-is-close" data-select="single"> <label class="slds-form-element__label" for="lookup-348"> Account Name </label> <!--This part is for display search bar for lookup--> <div class="slds-form-element__control"> <div class="slds-input-has-icon slds-input-has-icon--right"> <c:svg class="slds-input__icon slds-show" xlinkHref="{!$Resource.SLDS24 + '/assets/icons/utility-sprite/svg/symbols.svg#search'}" /> <!-- This markup is for when an record is selected --> <div aura:id="lookup-pill" class="slds-pill-container slds-hide"> <span class="slds-pill"> <span class="slds-pill__label"> {!v.selectedRecord.Name} </span> <button class="slds-button slds-button--icon slds-pill__remove" onclick="{!c.clear}"> <c:svg class="slds-button__icon" xlinkHref="{!$Resource.SLDS24 + '/assets/icons/utility-sprite/svg/symbols.svg#close'}" /> <span class="slds-assistive-text">Remove</span> </button> </span> </div> <div aura:id="lookupField" class="slds-show"> <ui:inputText updateOn="keyup" keyup="{!c.keyPressController}" class="slds-lookup__search-input slds-input " value="{!v.SearchKeyWord}" placeholder="search.."/> </div> </div> </div> <!--This part is for Display typehead lookup result List--> <div class="slds-lookup__menu slds" id="lookup-348"> <div class="slds-lookup__item--label slds-text-body--small">{!v.Message}</div> <center> <ui:spinner aura:id="spinner"/> </center> <ul class="slds-lookup__list" role="listbox"> <aura:iteration items="{!v.listOfSearchRecords}" var="singleRec"> <c:customLookupResult oAccount="{!singleRec}" /> </aura:iteration> </ul> </div> </div> </div> </aura:component>
JS Controller [customLookupController.js]
({ keyPressController : function(component, event, helper) { // get the search Input keyword var getInputkeyWord = component.get("v.SearchKeyWord"); // check if getInputKeyWord size id more then 0 then open the lookup result List and // call the helper // else close the lookup result List part. if( getInputkeyWord.length > 0 ){ var forOpen = component.find("searchRes"); $A.util.addClass(forOpen, 'slds-is-open'); $A.util.removeClass(forOpen, 'slds-is-close'); helper.searchHelper(component,event,getInputkeyWord); } else{ component.set("v.listOfSearchRecords", null ); var forclose = component.find("searchRes"); $A.util.addClass(forclose, 'slds-is-close'); $A.util.removeClass(forclose, 'slds-is-open'); } }, // function for clear the Record Selaction clear :function(component,event,heplper){ var pillTarget = component.find("lookup-pill"); var lookUpTarget = component.find("lookupField"); $A.util.addClass(pillTarget, 'slds-hide'); $A.util.removeClass(pillTarget, 'slds-show'); $A.util.addClass(lookUpTarget, 'slds-show'); $A.util.removeClass(lookUpTarget, 'slds-hide'); component.set("v.SearchKeyWord",null); component.set("v.listOfSearchRecords", null ); }, // This function call when the end User Select any record from the result list. handleComponentEvent : function(component, event, helper) { // get the selected Account record from the COMPONETN event var selectedAccountGetFromEvent = event.getParam("accountByEvent"); component.set("v.selectedRecord" , selectedAccountGetFromEvent); 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'); }, // automatically call when the component is done waiting for a response to a server request. hideSpinner : function (component, event, helper) { var spinner = component.find('spinner'); var evt = spinner.get("e.toggle"); evt.setParams({ isVisible : false }); evt.fire(); }, // automatically call when the component is waiting for a response to a server request. showSpinner : function (component, event, helper) { var spinner = component.find('spinner'); var evt = spinner.get("e.toggle"); evt.setParams({ isVisible : true }); evt.fire(); }, })
JS Helper [customLookupHelper.js]
({ searchHelper : function(component,event,getInputkeyWord) { // call the apex class method var action = component.get("c.fetchAccount"); // set param to method action.setParams({ 'searchKeyWord': getInputkeyWord }); // set a callBack action.setCallback(this, function(response) { var state = response.getState(); if (state === "SUCCESS") { var storeResponse = response.getReturnValue(); // if storeResponse size is equal 0 ,display No Result Found... message on screen. if (storeResponse.length == 0) { component.set("v.Message", 'No Result Found...'); } else { component.set("v.Message", 'Search Result...'); } // set searchResult list with return value from server. component.set("v.listOfSearchRecords", storeResponse); } }); // enqueue the Action $A.enqueueAction(action); }, })
TestApp.app
<aura:application > <c:customLookup/> <!-- here c: is org. namespace prefix--> </aura:application>
Output :

Related Resources :
Salesforce Lightning Design System Lookup
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. ?
49 comments
Hi –
I’m getting the following exception: System.FinalException: Cannot modify a collection while it is being iterated.
Can you help me in adressing this issue.
Thanks in advance.
Best Regards
Rajesh
HI @Rajesh
did you get this error with above apex class (Apex class [lookUpController.apxc]), which use in this sample lookup code , ?
and Basically This type exception is occurred when you are trying to modify some record while you are iterating same record.
you can post you issue on http://sfdcmonkey.com/community/main-forum/
in Details.so i look into this.
thanks
Hi-
Thanks for the quick reply. It was able to figure this out. I modified your code and did that above mistake. I has another issue regarding the performance so i posted in the forum.
Thanks in advance.
Will it work on SF1??
NO,NOT COMPATIBLE WITH S1 MOBILE
here is the reference link for it
https://www.lightningdesignsystem.com/components/lookups/
Does this override the standard lookup ?
I have created a custom lookup component on account object in my results I want to specify the record type. based upon record type only I need display the results in search field. Please tell me how can I.
Thanks & Best Regards,
Rajesh
Hi Rajesh, you can add a where condition in your component apex controller query such as “WHERE RecordType.Name = ‘yourSpecificRecordTypeName'”
Thanks
Hello. Much thanks for this article. But I have a remark: in summer 17 they removed ‘display:flex;’ from selector “.slds-lookup[data-select=single] .slds-pill, .slds-lookup[data-select=multi] .slds-pill {“, so now when record is selected, it does not stretch to fit parent container. Can you make proper adjustments please?
hi Vladyslav Kushney,
Thanks for your feedback, and i don’t have Summer 17 ready org [sandbox] right now for testing it. so i will update soon when i have access in summer 17 ready org.
and can you please mention the official doc. on this new update
thanks
Is n’t it possible in other ways without creating components for lookup field? Can’t we use Force input field and what other ways to get lookup field ?
Really nice article. But, one question: How can we pass the selected value to a Controller?
HI SF User ,
Thanks for your valuable feedback :).
you can get selected value in client side(javaScript) controller by :
component.get(“v.selectedRecord”) // for selected account object
component.get(“v.selectedRecord”).Name // for selected account Name
component.get(“v.selectedRecord”).Id // for selected account Id
Hopes it helps you 🙂
thanks
Thank you for the quick reply, but I was not specific enough.
I wanted to know, how can we get the selected record (Account) into the APEX controller?
Thank you
ok, so first create a simple button in your lightning component
button onclick=”{!c.onSave}”> save button
now create onSave javaScript controller function
onSave : function (component, event, helper) {
// call the apex class method
var action = component.get(“c.saveAccount”);
// set param to method
action.setParams({
‘obj’: component.get(“v.selectedRecord”)
});
// set a callBack
action.setCallback(this, function(response) {
var state = response.getState();
if (state === “SUCCESS”) {
console.log(state);
}
});
// enqueue the Action
$A.enqueueAction(action);
}
add method in apex class
@AuraEnabled
public static void saveAccount(Account obj){
system.debug(‘selectedAccount–>’ + obj);
}
Hops it helps you
thanks
First of all this is a great component, thanks for sharing it.
I would like to use this with another component like this :
Parent Component
Is there a way to set the default value as a parameter so when the component is rendered he already has a value on it? (Like a account select or so)
Thanks!
Hi,
Thanks for such a wonderful article!
I have one question, when i select an account from the list then it doesn’t get in to the search box, can you please help on this.
Thanks.
great article. The big icons appears on page load at once and than disappears. what is wrong?
Hi nothing is wrong here, sometime it will take little bit time to load lightning css i guess.
Hi! excellent article! I wonder how I can reset the selection, I want to clear the form after submission if success but I cant find a way to clear the selection, I tried setting selectedRecord to null and selection is cleared, but I see the empty square with the X.
Thanks!
Thank you for the Article.It really helped me.
One problem that i faced while using your article was that search and cancel symbols not showing in IE 11 where as its showing correctly in Chrome Version 59.0.3071.115.Please help me on this
Thank you
Hi Naveen,
thanks for your appreciation and i think here some problem with lightning component on IE11 : Not all browsers support CSP. In particular, IE11 is…problematic. In browsers that don’t support CSP, such as IE11, LockerService is disabled. salesforce strongly recommend that, for enhanced security, you update to a modern browser, such as the latest versions of Chrome, Safari, Firefox, or Microsoft Edge.
refrence: https://trailhead.salesforce.com/en/modules/lex_dev_lc_vf_tips/units/lex_dev_lc_vf_tips_javascript
While trying to fetch the selectedAccount parameter from the event, the function is returning undefined, hence although search is being done, while trying to save it the name of the selectedRecord does not appear. Am i missing something here? I saw that the event is registered
hi roy,
here is the new version of this custom lookup with sample “how to use” example
http://sfdcmonkey.com/2017/07/17/re-usable-custom-lookup/
thanks
HI sfdcMonkey,
I am using lookup field . and want to show error if that field is blank . I am using another component to show the lookup field value. I am show error another fields but not successs to show blank error on the lookup field . pls guide how to show error on lookup field.
thanks
vikas
Hi SFDC Monkey,
Excellent article..,if i want to display header Name in the look up display list, can you help me in achieving this?.
Thanks,
Jewelslyn
Great article!
I was just wondering if  we can add multiple accounts through the search and display the selection as lightning pills? I see its working for only one selection.
Can you try creating a lookup which will display all contacts associated to an account?
Hi
Great Article
How to set default in custom lookup field
Position of lookup icon gets change if any error shown below input box.please help..!
 https://salesforce.stackexchange.com/questions/208253/dynamic-add-row-in-lightning
Could you explain how to make this field a required field?
Hi,
I have created the aura component with quick action. Here i need to pre-populate lookup value based on current record for using custom lookup. Please help me how we can populate the default value from source record look up field here.
post your issue on developer forums in more details and share question URL here, so i can look into your issue. Thanks
https://developer.salesforce.com/forums
Nice article, Can you help me on 1) how to make this multi select? 2) dependent lookup’s i.e., on selecting value in one lookup other lookup field values should vary?
Thanks
Hemanth
http://sfdcmonkey.com/2018/02/20/multi-select-lookup-salesforce-lightning/
How to make custom lookup is mandatory field
Thank you so much for this! I was at my wits end creating sub-flows for lookup field replacements in my VisualWorkflows.
I used your code above and then created a lightning component which uses the customlookup.
CMP:
<aura:component implements=”lightning:availableForFlowScreens” access=”global”>
<aura:attribute name=”selectedRecord” type=”Contact” default=”{}”/>
<div class=”slds-m-around_large”>
<c:customLookup objectAPIName=”contact” IconName=”standard:contact” label=”Contact” selectedRecord=”{!v.selectedRecord}” />
</div>
</aura:component>
And a Design for the SelectedRecord attribute.
Now i need to figure out how to limit the look up to contacts in a specific Account.
Ok.. i figured out how to add a limit by a record for the use in my Flow.
I had to modify the base code you provided with a simple if statement, variables for the limitfield, limitvalue, Operator, ANDOR, and one boolean variable to use or not use the limit the additional Statement or not.
So my flow now passes in values for either the 4 fields used to build the added string to the sQuery.
Thank you so much again for the starting point!
I have used same component to display custom flookup its working perfect but i need to save the lookup value corresponding to other value such as name, phone value etc it getting saved in the back end, in the component only lookup field gets empty. how can i resolve this issue.
Hi my requirement is when i click on the lookup search it will open a window displaying all the accounts and need one button if user wants to create a account please help me out thanks advance.
I want to select the lookup filed value by using keyboard up and down keys.please give me the answer
hi i want to search Email id from Account by Account name
I have copy pasted the whole code just to understand how the flow works.
however, I have received the following error:
“This page has an error. You might just need to refresh it. Action failed: ltng:outApp$controller$init [Incorrect usage of ltng:outApp. Refer to the ‘Lightning Components Developer Guide’ for correct usage] Failing descriptor: {ltng:outApp$controller$init}”
Help me out with this
how to implement search record add one by one for e.g standard email functionality when we search Email id we can add multiple Email Id i need to implement same how can possible. any one help me
when I start writing her self blocks me and shows me this error message
Sorry to interrupt
This page has an error. You might just need to refresh it.
Unable to find action ‘hideSpinner’ on the controller of c:customLookup
Failing descriptor: {c:customLookup}
Hi ,
You mentioned this component will not work due to some release update. I used this component and It was working before the spring 19 release but suddenly it is giving “<strong>Uncaught render threw an error in ‘c:iCRM_LookUpSVG_LT’ [Failed to execute ‘querySelector’ on ‘Element’: ‘#httpsgauk–ghservdev.lightning.force.comlightningoAsset%7B’iconsutility-spritesvgsymbols.svg_search’}’ is not a valid selector.]</strong>” error on component load only.
Will you please help me in this. I’m just curios what actually changed. In your new updated component I’m not able to see “SVG” component. So there any reason you removed it?
It’s very critical issue for me, Already deployed this in production so have to fix it ASAP.
Thanks in advance.
hello,
how to upload this svg which is using in this lightning in our static resources