Apex Class :
Create below apex controllercustomLookUpController.apex
public class customLookUpController { @AuraEnabled public static List < sObject > fetchLookUpValues(String searchKeyWord, String ObjectName) { system.debug('ObjectName-->' + ObjectName); String searchKey = searchKeyWord + '%'; List < sObject > returnList = new List < sObject > (); // Create a Dynamic SOQL Query For Fetch Record List with LIMIT 5 String sQuery = 'select id, Name from ' +ObjectName + ' where Name LIKE: searchKey order by createdDate DESC limit 5'; List < sObject > lstOfRecords = Database.query(sQuery); for (sObject obj: lstOfRecords) { returnList.add(obj); } return returnList; } }
Lightning Event :
Create below lighitng eventselectedsObjectRecordEvent.evt
<aura:event type="COMPONENT" description="by this event we are pass the selected sObject(lookup list record) in the parent component"> <aura:attribute name="recordByEvent" type="sObject"/> </aura:event>
Lightning Component :
Create [ Child ]customLookupResult.cmpComponent For Display the Search Result List
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global"> <aura:attribute name="oRecord" type="sObject" /> <aura:attribute name="IconName" type="string"/> <!--Register the component level event--> <aura:registerEvent name="oSelectedRecordEvent" type="c:selectedsObjectRecordEvent"/> <li role="presentation" class="slds-listbox__item" onclick="{!c.selectRecord}"> <span id="listbox-option-unique-id-01" 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" title="Description of icon when needed"> <lightning:icon iconName="{!v.IconName}" class="slds-icon slds-icon_small" size="small" alternativeText="icon"/> <span class="slds-assistive-text">Description of icon</span> </span> </span> <span class="slds-media__body"> <span class="slds-listbox__option-text slds-listbox__option-text_entity">{!v.oRecord.Name}</span> </span> </span> </li> </aura:component>
JavaScript Controller :
Create below jscustomLookupResultController.js controller to use it incustomLookupResult.cmp
({ selectRecord : function(component, event, helper){ // get the selected record from list var getSelectRecord = component.get("v.oRecord"); // call the event var compEvent = component.getEvent("oSelectedRecordEvent"); // set the Selected sObject Record to the event attribute. compEvent.setParams({"recordByEvent" : getSelectRecord }); // fire the event compEvent.fire(); }, })
Lightning Component :
Create Lightning Custom Lookup ComponentcustomLookup.cmp[ Parent ]
<aura:component controller="customLookUpController" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global"> <!--declare attributes--> <aura:attribute name="selectedRecord" type="sObject" default="{}" description="Use,for store SELECTED sObject Record"/> <aura:attribute name="listOfSearchRecords" type="List" description="Use,for store the list of search records which returns from apex class"/> <aura:attribute name="SearchKeyWord" type="string"/> <aura:attribute name="objectAPIName" type="string" default=""/> <aura:attribute name="IconName" type="string" default=""/> <aura:attribute name="label" type="string" default=""/> <aura:attribute name="Message" type="String" default=""/> <!--declare events hendlers--> <aura:handler name="oSelectedRecordEvent" event="c:selectedsObjectRecordEvent" action="{!c.handleComponentEvent}"/> <!-- https://www.lightningdesignsystem.com/components/lookups/ --> <div onmouseleave="{!c.onblur}" aura:id="searchRes" class="slds-form-element slds-lookup slds-is-close" data-select="single"> <label class="slds-form-element__label" for="lookup-348">{!v.label}</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"> <!-- This markup is for when an record is selected --> <div aura:id="lookup-pill" class="slds-pill-container slds-hide"> <lightning:pill class="pillSize" label="{!v.selectedRecord.Name}" name="{!v.selectedRecord.Name}" onremove="{! c.clear }"> <aura:set attribute="media"> <lightning:icon iconName="{!v.IconName}" size="x-small" alternativeText="{!v.IconName}"/> </aura:set> </lightning:pill> </div> <div aura:id="lookupField" class="slds-show"> <lightning:icon class="slds-input__icon slds-show" iconName="utility:search" size="x-small" alternativeText="search"/> <span class="slds-icon_container slds-combobox__input-entity-icon" title="record"> <lightning:icon class="slds-icon slds-icon slds-icon_small slds-icon-text-default" iconName="{!v.IconName}" size="x-small" alternativeText="icon"/> <span class="slds-assistive-text"></span> </span> <ui:inputText click="{!c.onfocus}" updateOn="keyup" keyup="{!c.keyPressController}" class="slds-lookup__search-input slds-input leftPaddingClass" value="{!v.SearchKeyWord}" placeholder="search.."/> </div> </div> </div> <!--This part is for Display typehead lookup result List--> <ul style="min-height:40px;margin-top:0px !important" class="slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid slds-lookup__menu slds" role="listbox"> <lightning:spinner class="slds-hide" variant="brand" size="small" aura:id="mySpinner"/> <center> {!v.Message}</center> <aura:iteration items="{!v.listOfSearchRecords}" var="singleRec"> <c:customLookupResult oRecord="{!singleRec}" IconName="{!v.IconName}"/> </aura:iteration> </ul> </div> </aura:component>
JavaScript Controller :
Create below JS controllercustomLookupController.js
({ onfocus : function(component,event,helper){ $A.util.addClass(component.find("mySpinner"), "slds-show"); var forOpen = component.find("searchRes"); $A.util.addClass(forOpen, 'slds-is-open'); $A.util.removeClass(forOpen, 'slds-is-close'); // Get Default 5 Records order by createdDate DESC var getInputkeyWord = ''; helper.searchHelper(component,event,getInputkeyWord); }, onblur : function(component,event,helper){ component.set("v.listOfSearchRecords", null ); var forclose = component.find("searchRes"); $A.util.addClass(forclose, 'slds-is-close'); $A.util.removeClass(forclose, 'slds-is-open'); }, 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 ); component.set("v.selectedRecord", {} ); }, // 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("recordByEvent"); 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'); }, })
JavaScript Controller :
Create below JS controllercustomLookupHelper.js Helper
({ searchHelper : function(component,event,getInputkeyWord) { // call the apex class method var action = component.get("c.fetchLookUpValues"); // set param to method action.setParams({ 'searchKeyWord': getInputkeyWord, 'ObjectName' : component.get("v.objectAPIName") }); // set a callBack action.setCallback(this, function(response) { $A.util.removeClass(component.find("mySpinner"), "slds-show"); 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", ''); } // set searchResult list with return value from server. component.set("v.listOfSearchRecords", storeResponse); } }); // enqueue the Action $A.enqueueAction(action); }, })
Style Tab CSS :
Create below csscustomLookup.CSS
.THIS .leftPaddingClass { padding-left: 2rem; } .THIS .pillSize{ width:100%; }
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 :
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 Class :
Create below apexcontactSaveCtrl.apexcontroller
public class contactSaveCtrl { @AuraEnabled public static void saveContact(Contact con){ insert con; } }
Lightning Component :
Create belowexample.cmpLightning Component
<aura:component controller="contactSaveCtrl" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global"> <aura:attribute name="selectedLookUpRecord" type="sObject" default="{}"/> <aura:attribute name="objContact" type="contact" default="{'sobjectType':'contact'}"/> <div class="slds-m-around_large"> <ui:inputText class="slds-input" value="{!v.objContact.LastName}" label="Last Name"/> <c:customLookup objectAPIName="account" IconName="standard:account" label="Account Name" selectedRecord="{!v.selectedLookUpRecord}"/> <br/> <button class="slds-utton slds-button_brand" onclick="{!c.saveContactRecord}">Save Contact</button> </div> </aura:component>
JavaScript Controller :
Create below JavaScriptexampleController.jscontroller
({ saveContactRecord : function(component, event, helper) { var conObj = component.get("v.objContact"); //set the default accountId is null conObj.AccountId = null ; // check if selectedLookupRecord is not equal to undefined then set the accountId from // selected Lookup Object to Contact Object before passing this to Server side method if(component.get("v.selectedLookUpRecord").Id != undefined){ conObj.AccountId = component.get("v.selectedLookUpRecord").Id; } //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); } })