Skip to content

Instantly share code, notes, and snippets.

@victorabraham
Created October 19, 2020 19:32
Show Gist options
  • Save victorabraham/a81b8bab5e4632b6e342a3253c4345b3 to your computer and use it in GitHub Desktop.
Save victorabraham/a81b8bab5e4632b6e342a3253c4345b3 to your computer and use it in GitHub Desktop.
<aura:component controller="Util_AutocompleteInputController">
<aura:attribute name="label" type="String"/>
<aura:attribute name="placeholder" type="String" default="Search"/>
<aura:attribute name="iconName" type="String" default="utility:account"/>
<aura:attribute name="objectToSearch" type="String" required="true"/>
<aura:attribute name="fieldToSearch" type="String" default="Name"/>
<aura:attribute name="fieldsToDisplay" type="String[]" default="['Name']"/>
<aura:attribute name="fieldsToReturn" type="String[]" default="['Id']"/>
<aura:attribute name="extraWhereClause" type="String" default=""/>
<aura:attribute name="maxResultCount" type="Integer" default="20"/>
<aura:attribute name="timer" type="Integer"/>
<aura:attribute name="searchDelay" type="Integer" default="350"/>
<aura:attribute name="resultList" type="Object[]" default="[]"/>
<aura:registerEvent name="onSelection" type="c:Util_SelectionEvent"/>
<div class="slds-form-element">
<label class="slds-form-element__label" for="combobox-id-3">{!(v.label || v.objectToSearch)}</label>
<div class="slds-form-element__control">
<div class="slds-combobox_container">
<div aura:id="autocompleteId" class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open"
aria-expanded="true" aria-haspopup="listbox" role="combobox">
<div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right" role="none">
<input type="text" class="slds-input slds-combobox__input slds-has-focus" id="combobox-id-3"
aria-activedescendant="option1" aria-autocomplete="list" aria-controls="listbox-id-3"
autoComplete="off" role="textbox" placeholder="{!v.placeholder}" onkeyup="{!c.handleSearch}" focus="{!c.showDropdown}"/>
<span
class="slds-icon_container slds-icon-utility-search slds-input__icon slds-input__icon_right">
<lightning:icon iconName="utility:search" alternativeText="Search" title="Search" size="small"/>
</span>
</div>
<div id="listbox-id-3" class="slds-dropdown slds-dropdown_length-with-icon-7 slds-dropdown_fluid"
role="listbox">
<ul class="slds-listbox slds-listbox_vertical" role="presentation">
<aura:iteration items="{!v.resultList}" var="result">
<li role="presentation" class="slds-listbox__item" data-id="{!result.id}" onclick="{!c.handleSelection}">
<div aria-selected="true" id="option1"
class="slds-media slds-listbox__option slds-listbox__option_entity slds-listbox__option_has-meta"
role="option" tabindex="0">
<span class="slds-media__figure slds-listbox__option-icon">
<span class="slds-icon_container slds-icon-standard-account">
<lightning:icon iconName="{!v.iconName}" alternativeText="" title="" />
</span>
</span>
<span class="slds-media__body">
<span class="slds-listbox__option-text slds-listbox__option-text_entity">{!result.title}</span>
<span class="slds-listbox__option-meta slds-listbox__option-meta_entity">{!result.subtitle}</span>
</span>
</div>
</li>
</aura:iteration>
</ul>
</div>
</div>
</div>
</div>
</div>
</aura:component>
({
handleSearch : function(component, event, helper) {
helper.showDropdown(component);
let timer = component.get('v.timer');
clearTimeout(timer);
let searchDelay = component.get('v.searchDelay');
timer = setTimeout(
$A.getCallback(function() {
helper.search(component, event, helper);
clearTimeout(timer);
component.set('v.timer', null);
}), searchDelay);
component.set('v.timer', timer);
},
handleSelection: function(component, event, helper) {
let resultList = component.get('v.resultList');
let selectedObj = resultList.filter(obj => {
return event.currentTarget.dataset.id === obj.id;
});
console.log('found', selectedObj[0]);
var event = component.getEvent("onSelection");
event.setParams({data: selectedObj[0].value});
event.fire();
helper.hideDropdwon(component);
},
showDropdown: function(component, event, helper) {
helper.showDropdown(component);
},
hideDropdown: function(component, event, helper) {
helper.hideDropdwon(component);
}
})
({
search : function(component, event, helper) {
let searchKey = event.target.value;
if(searchKey && searchKey.length > 0) {
let fieldToSearch = component.get('v.fieldToSearch');
let objectToSearch = component.get('v.objectToSearch');
let fieldsToDisplay = component.get('v.fieldsToDisplay');
let fieldsToReturn = component.get('v.fieldsToReturn');
let extraWhereClause = component.get('v.extraWhereClause');
let maxResultCount = component.get('v.maxResultCount');
let fieldArray = ['Id', ...fieldsToDisplay, ...fieldsToReturn];
let dedupedFieldString = [...new Set(fieldArray)].join(','); //removing duplicates and joining by ,
extraWhereClause = extraWhereClause ? `AND ${extraWhereClause}` : '';
let query = `SELECT ${dedupedFieldString} FROM ${objectToSearch} WHERE ${fieldToSearch} LIKE '${searchKey}%' ${extraWhereClause} LIMIT ${maxResultCount}`;
console.log('Search query => ', query);
var action = component.get('c.getQueryResult');
action.setParams({searchQuery: query});
action.setCallback(this, function (response) {
if (component.isValid() && response.getState().toLowerCase() === 'success') {
let searchResult = response.getReturnValue() || [];
let resultArray = [];
let [titleField, ...subtitleFields] = fieldsToDisplay;
for (const record of searchResult) {
let resultObj = {title: record[titleField], subtitle: '', id: record.Id, value: {}};
if(subtitleFields && subtitleFields.length > 0) {
let subtitleValues = [];
for(const subField of subtitleFields) {
if(record[subField]) {
subtitleValues.push(record[subField]);
}
}
resultObj.subtitle = subtitleValues.join(',');
}
if(fieldsToReturn && fieldsToReturn.length > 0) {
let returnObj = {};
for(const returnField of fieldsToReturn) {
returnObj[returnField] = record[returnField];
}
resultObj.value = returnObj;
}
resultArray.push(resultObj);
}
component.set('v.resultList', resultArray);
} else {
console.log('Search error', query);
}
});
$A.enqueueAction(action);
}else {
component.set('v.resultList', []);
}
},
showDropdown: function(component) {
setTimeout($A.getCallback(function() {
var myMenu = component.find('autocompleteId');
$A.util.addClass(myMenu, 'slds-is-open');
}), 50);
},
hideDropdwon: function(component) {
setTimeout($A.getCallback(function() {
var myMenu = component.find('autocompleteId');
$A.util.removeClass(myMenu, 'slds-is-open');
}), 50);
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment