lightiningLookup

Lightining Framework comes with many inbulit functionalities and features but there is one important thing that is missing that is lookup component. developers faces alot of problems when there is any requirement to create a component with lookpup fields .

So here in this blog i will tell you how you can create your own lookup component in lightining.

Before dive into the code here is the file names with description

1) Lightining Lookup Component   –  The main lookup component
2) LightiningLookupjsController     –  JS  Controller For lookup component
3) LightiningLookupHelper            –  JS Controller Helper Class
4) LightiningLookupController       –  Apex Controller for Lookup Component
5) LightiningApplication               –   Application in which we use our lightining component

So You just need to embed the component in your application like below Example :

Example : 


<c:LightningLookup

objectName=”Account”

field_API_text=”Name”

field_API_val=”Id”

limit=”4″

field_API_search=”Name”

lookupIcon=”standard:account”  

selItem=”{!v.accountVal}”

placeholder=”Enter space after text to search Account”

/>


Paramter you need to pass to your component  :

  • ObjectName – Name of SObject
  • field_API_text – API name of field to display to user while searching
  • field_API_Val – API name of field to be returned by Lookup COmponent
  • limit – Total number of record to be returned
  • field_API_search – API name of field to be searched
  • searchText – text to be searched

Here is the code for lightining lookup component : 

  1. Lightining Lookup Component 
<aura:component controller="LightningLookupController"> 
     <aura:attribute Name="selItem" type="object" access="public" 
                     description="This attribute can be used by parent component to read selected record"/>  
     <aura:attribute Name="server_result" type="object[]" access="private" /> 
     
     <aura:attribute name="lookupIcon" type="String" access="public" default="standard:contact"/>
    
    <aura:attribute name="objectName" type="String" access="public" 
                    description="Name of Object to be searched"/>
    <aura:attribute name="field_API_text" type="String" access="public" 
                    description="API Name of field, to be used to show text"/>
    <aura:attribute name="field_API_val" type="String" access="public" 
                    description="API Name of field, to be returned from component"/>
    <aura:attribute name="field_API_search" type="String" access="public" 
                    description="API Name of field to be searched"/>
    <aura:attribute name="limit" type="Integer" access="public" default="5" 
                    description="Total number of record to be returned"/>
    <aura:attribute name="placeholder" type="String" access="public" 
                    default="Space character is used to search" />
    
    <aura:attribute name="last_SearchText" type="String" access="private" />
    <aura:attribute name="last_ServerResult" type="object[]" access="private" /> 
    
    <!--attribs for Hassler App requirement-->
    <aura:attribute name="parentFieldAPI" type="String" access="public" />
    <aura:attribute name="parentId" type="String" access="public" />

    <div class="slds">      
        <div class="slds-form-element"> 
            <div class="slds-form-element__control">
                <div class="slds-combobox_container slds-has-inline-listbox">
                    <div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open" 
                         aria-expanded="true" aria-haspopup="listbox" role="combobox" style="width:95%">
                        <div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right">
                            <div> 
                                <aura:if isTrue="{! empty(v.selItem) }"> 
                                         <input type="text" class="slds-input slds-combobox__input" id="combobox-unique-id" 
                                                aria-activedescendant="listbox-option-unique-id-01" aria-autocomplete="list" 
                                                aria-controls="listbox-unique-id" autocomplete="off" role="combobox" 
                                                placeholder="{!v.placeholder}" 
                                                onkeyup="{!c.serverCall}" />
                                        <aura:set attribute="else"> 
                                                <span class="slds-pill slds-pill_link fullWidth"> 
                                                  <a href="javascript:void(0);" 
                                                     class="slds-pill__action slds-p-left_x-small" title="{#v.selItem.text}">
                                                    <lightning:icon iconName="{#v.lookupIcon}" size="x-small"/>
                                                    <span class="slds-pill__label slds-p-left_x-small">{#v.selItem.text}</span>
                                                  </a>
                                                  <button onclick="{!c.clearSelection}" 
                                                          class="slds-button slds-button_icon slds-button_icon slds-pill__remove" 
                                                          title="Remove">
                                                    <lightning:icon iconName="utility:close" size="small" 
                                                                    alternativeText="Press delete or backspace to remove"/>
                                                    <span class="slds-assistive-text" >Remove</span>
                                                  </button>
                                                </span> 
                                        </aura:set>
                                    </aura:if> 
                           	 	</div> 
                            </div>
                            <aura:if isTrue="{! greaterthanorequal(v.server_result.length,1) }"> 
                                <div id="listbox-unique-id" role="listbox">
                                    <ul class="slds-listbox slds-listbox_vertical slds-dropdown slds-dropdown_fluid" role="presentation"
                                        style="display: block; min-width: auto; max-width: 100% ; width: 100%;">
                                        <aura:iteration items="{!v.server_result}" var="item" indexVar="i">
                                            <li role="presentation" class="slds-listbox__item" data-selectedIndex="{#i}" 
                                                onclick="{!c.itemSelected}">
                                                <span id="{#'listbox-option-unique-id-'+i+1}"  
                                                      class="slds-media slds-listbox__option slds-listbox__option_entity 
                                                             slds-listbox__option_has-meta" 
                                                      role="option">
                                                    <span class="slds-media__figure optionIcon">
                                                        <span class="slds-icon_container" >
                                                            <lightning:icon iconName="{#v.lookupIcon}" size="small"/>
                                                            <span class="slds-assistive-text">{#v.objectName}</span>
                                                        </span>
                                                    </span>
                                                    <span class="slds-media__body singleRow">
                                                        <span 
                                                              class="optionTitle slds-listbox__option-text 
                                                                     slds-listbox__option-text_entity">{#item.text}</span>
                                                    </span>
                                                </span>
                                            </li>
                                        </aura:iteration> 
                                    </ul>
                                </div>
                            </aura:if> 
                        </div>
                    </div>
                </div>
            </div> 
    </div>     
</aura:component>

2) LightiningLookupjsController

 

({
  itemSelected : function(component, event, helper) {
    helper.itemSelected(component, event, helper);
  }, 
    serverCall :  function(component, event, helper) {
    helper.serverCall(component, event, helper);
  },
    clearSelection : function(component, event, helper){
        helper.clearSelection(component, event, helper);
    } 
})

3) LightiningLookupHelper

({
  itemSelected : function(component, event, helper) {
        var target = event.target;   
        var SelIndex = helper.getIndexFrmParent(target,helper,"data-selectedIndex");  
        if(SelIndex){
            var serverResult = component.get("v.server_result");
            var selItem = serverResult[SelIndex];
            if(selItem.val){
               component.set("v.selItem",selItem);
               component.set("v.last_ServerResult",serverResult);
            } 
            component.set("v.server_result",null); 
        } 
  }, 
    serverCall : function(component, event, helper) {  
        var target = event.target;  
        var searchText = target.value; 
        var last_SearchText = component.get("v.last_SearchText");
        //Escape button pressed 
        if (event.keyCode == 27 || !searchText.trim()) { 
            helper.clearSelection(component, event, helper);
        }else if(searchText.trim() != last_SearchText  && /\s+$/.test(searchText) ){ 
            //Save server call, if last text not changed
            //Search only when space character entered
         
            var objectName = component.get("v.objectName");
            var field_API_text = component.get("v.field_API_text");
            var field_API_val = component.get("v.field_API_val");
            var field_API_search = component.get("v.field_API_search");
            var limit = component.get("v.limit");
            
            var action = component.get('c.searchDB');
            action.setStorable();
            
            action.setParams({
                objectName : objectName,
                fld_API_Text : field_API_text,
                fld_API_Val : field_API_val,
                lim : limit, 
                fld_API_Search : field_API_search,
                searchText : searchText,
                parentFieldAPI : component.get("v.parentFieldAPI"),
                parentId : component.get("v.parentId")
            });
    
            action.setCallback(this,function(a){
                this.handleResponse(a,component,helper);
            });
            
            component.set("v.last_SearchText",searchText.trim());
            console.log('Server call made');
            $A.enqueueAction(action); 
        }else if(searchText && last_SearchText && searchText.trim() == last_SearchText.trim()){ 
            component.set("v.server_result",component.get("v.last_ServerResult"));
            console.log('Server call saved');
        }         
  },
    handleResponse : function (res,component,helper){
        if (res.getState() === 'SUCCESS') {
            var retObj = JSON.parse(res.getReturnValue());
            if(retObj.length <= 0){
                var noResult = JSON.parse('[{"text":"No Results Found"}]');
                component.set("v.server_result",noResult); 
            	component.set("v.last_ServerResult",noResult);
            }else{
                component.set("v.server_result",retObj); 
            	component.set("v.last_ServerResult",retObj);
            }  
        }else if (res.getState() === 'ERROR'){
            var errors = res.getError();
            if (errors) {
                if (errors[0] && errors[0].message) {
                    alert(errors[0].message);
                }
            } 
        }
    },
    getIndexFrmParent : function(target,helper,attributeToFind){
        //User can click on any child element, so traverse till intended parent found
        var SelIndex = target.getAttribute(attributeToFind);
        while(!SelIndex){
            target = target.parentNode ;
      SelIndex = helper.getIndexFrmParent(target,helper,attributeToFind);           
        }
        return SelIndex;
    },
    clearSelection: function(component, event, helper){
        component.set("v.selItem",null);
        component.set("v.server_result",null);
    } 
})

4) LightiningLookupController

 

public with sharing class LightningLookupController 
{


  /**
     * Returns JSON of list of ResultWrapper to Lex Components
     * @objectName - Name of SObject
     * @fld_API_Text - API name of field to display to user while searching
     * @fld_API_Val - API name of field to be returned by Lookup COmponent
     * @lim   - Total number of record to be returned
     * @fld_API_Search - API name of field to be searched
     * @searchText - text to be searched
     * */
    @AuraEnabled 
    public static String searchDB(String objectName, String fld_API_Text, String fld_API_Val, 
                                  Integer lim,String fld_API_Search,String searchText, String parentFieldAPI, String parentId )
    {
        System.debug('parentId------'+parentId);
        List<ResultWrapper> lstRet = new List<ResultWrapper>();
        if((objectName=='Contact' || objectName=='Opportunity') && String.isBlank(parentId)){
        	return JSON.serialize(lstRet) ;                    
        }
        if(String.isNotBlank(searchText.trim())){
            searchText='\'%' + String.escapeSingleQuotes(searchText.trim()) + '%\'';
        }
        

        
        String query = 'SELECT '+fld_API_Text+' ,'+fld_API_Val+
            			' FROM '+objectName;
        if(String.isNotBlank(searchText)){
            query+=' WHERE '+fld_API_Search+' LIKE '+searchText;
        }
            				
            			
        
        if(String.isNotBlank(parentId)){
            query+=(String.isNotBlank(searchText) ? ' AND ' : '  WHERE  ')+parentFieldAPI+' = \''+parentId+'\'';
        }
        query+=' LIMIT '+lim;
        System.debug('query------'+query);
        List<sObject> sobjList = Database.query(query);
        
        
        for(SObject s : sobjList){
            ResultWrapper obj = new ResultWrapper();
            obj.objName = objectName;
            obj.text = String.valueOf(s.get(fld_API_Text)) ;
            obj.val = String.valueOf(s.get(fld_API_Val))  ;
            lstRet.add(obj);
        } 
         return JSON.serialize(lstRet) ;
    }
    
    public class ResultWrapper{
        public String objName {get;set;}
        public String text{get;set;}
        public String val{get;set;}
    }
}

5) Lightining Lookup Component CSS

.THIS{
    width:99%;
}
.THIS .fullWidth{
    width:100%;
}
.THIS .slds-listbox__item:hover {
    background: #d8edff;
    text-shadow: none;
    color: #16325c;
}

.THIS .optionParent1{
    line-height: 1.5;
    padding: 0.25rem 0.75rem;
    font-size: 0.8125rem;
}

.THIS .optionIcon {
   margin-top: 0.50rem;
}

.THIS .optionTitle{
        max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
    margin-bottom: 0.125rem;
}

.THIS .optionline{
        display: block;
    margin-top: -0.25rem;
    color: #54698d;
}
.THIS .singleRow{
    padding-top:5px;
}

.THIS .hide{
    display:none;
}

6) Lightining Lookup Component Application

This is the component in which you can embed your lightining lookup component . you can embed your component in visualforce page as well .

In lightining Component Application you need to just embeed your lightining component like :

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

<c:LightningLookup objectName="Account" field_API_text="Name" field_API_val="Id" limit="4" field_API_search="Name" lookupIcon="standard:account"
                                       selItem="{!v.accountVal}" placeholder="Enter space after text to search Account" />

</aura:application>

 

Hits: 454

Share Post

By Himanshu Rana

My Name is Himanshu Rana, 23 Years young, born and grow up in Ghaziabad, India. A High Spirited Salesforce Admin, Developer and a Blogger. I currently work at Wakencode Technologies,

Leave a Reply

Your email address will not be published. Required fields are marked *