+ Start a Discussion
Luke Higgins 22Luke Higgins 22 

input on a custom lookup field

I'm trying to make a custom user lookup component and I've gotten to where the lookup's dropdown works, but only after the space bar is hit. Is there anyway for this to update on every key hit instead? I've already tried to use oninput and onchange with no luck. Here's what I have:

usernameLookup.cmp
<aura:component controller="lookupSearch"> 
     <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" /> 

    <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}" 
                                                oninput="{!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>

userLookupController.js

({
	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);
    } 
})
usernameLookupHelper.js
({
	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) { 
            helper.clearSelection(component, event, helper);
        }else if(searchText != 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
            });
    
            action.setCallback(this,function(a){
                this.handleResponse(a,component,helper);
            });
            
            component.set("v.last_SearchText",searchText);
            console.log('Server call made');
            $A.enqueueAction(action); 
        }else if(searchText && last_SearchText && searchText == last_SearchText){ 
            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);
    } 
})
And this is how it is on the parent component:
<div class="slds">
                                <div class="slds-grid slds-wrap slds-p-bottom_xx-large">
                                    <div class="slds-size_1-of-1 
                                                slds-small-size_1-of-1 
                                                slds-medium-size_1-of-2 
                                                slds-large-size_1-of-2 ">
                                        <c:usernameLookup objectName="User"
                                                  field_API_text="Name"
                                                  field_API_val="Username"
                                                  limit="4"
                                                  field_API_search="Name"
                                                  lookupIcon="standard:user" 
                                                  selItem="{!v.selItem}" 
                                                  placeholder="Enter space after text to search Users"
                                                  />  
                                                  <aura:if isTrue="{! not(empty(v.selItem)) }"> 
                                                    <br />
                                                    User Selected : {#v.selItem.text}<br />
                                                    Username - {#v.selItem.val} <br /> 
                                                </aura:if> 
                                    </div>
                                </div>
                            </div>

 
Maharajan CMaharajan C
Hi Luke,

Try to use the onkeyup="{!c.serverCall}"  function.

i tried the below sample for keyup function in w3schools and it's working fine.
===========

<!DOCTYPE html>
<html>
<body> 
<p> Test1 </p> 
<form action="/action_page.php">
First name: <input type="text" name="FirstName" value="Mickey" id="demo1" onkeyup="displayname()"><br>
Last name: <input type="text" name="LastName" value="Mouse" id="demo2" onkeyup="displayname()"><br>
</form>

<script>
function displayname() {
  var fn = document.getElementById("demo1").value;
  var ln = document.getElementById("demo2").value;
  document.getElementById("demo").innerHTML =  fn + ' ' + ln ;
}
</script>
<p id="demo"></p>
</body>
</html>

=============


And also Please refer the below link for your lookup component reference:
http://cafeforce.com/custom-lookup-component-salesforce-lightning/

Thanks,
Maharajan.C