├── AutoComplete.gif ├── AutoComplete ├── AutoComplete.cmp ├── AutoComplete.cmp-meta.xml ├── AutoCompleteController.cls ├── AutoCompleteController.cls-meta.xml ├── AutoCompleteController.js ├── AutoCompleteControllerTest.cls ├── AutoCompleteControllerTest.cls-meta.xml └── AutoCompleteHelper.js └── README.md /AutoComplete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/choudharymanish8585/AutoComplete-Lightning-Component/059068863edbc71beb9d289d3d66b608e287db26/AutoComplete.gif -------------------------------------------------------------------------------- /AutoComplete/AutoComplete.cmp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 21 |
22 |
23 |
25 |
26 | 31 | 32 | 34 | 35 | 36 | 37 | 41 | 42 | 43 |
44 |
46 | 63 |
64 |
65 |
66 |
67 |
68 | 69 |
70 | -------------------------------------------------------------------------------- /AutoComplete/AutoComplete.cmp-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 45.0 4 | A Lightning Component Bundle 5 | 6 | -------------------------------------------------------------------------------- /AutoComplete/AutoCompleteController.cls: -------------------------------------------------------------------------------- 1 | public with sharing class AutoCompleteController { 2 | @AuraEnabled(cacheable=true) 3 | public static List getRecords(String searchString, String objectApiName, String idFieldApiName, String valueFieldApiName, String extendedWhereClause, Integer maxRecords){ 4 | searchString = String.escapeSingleQuotes(searchString); 5 | objectApiName = String.escapeSingleQuotes(objectApiName); 6 | idFieldApiName = String.escapeSingleQuotes(idFieldApiName); 7 | valueFieldApiName = String.escapeSingleQuotes(valueFieldApiName); 8 | 9 | if(extendedWhereClause == null){ 10 | extendedWhereClause = ''; 11 | } 12 | 13 | String query = 'SELECT '+idFieldApiName+', '+valueFieldApiName+' FROM '+objectApiName+' WHERE '+valueFieldApiName+' LIKE \'%'+searchString+'%\' '+extendedWhereClause+' LIMIT '+maxRecords; 14 | return Database.query(query); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /AutoComplete/AutoCompleteController.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 45.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /AutoComplete/AutoCompleteController.js: -------------------------------------------------------------------------------- 1 | ({ 2 | searchHandler : function (component, event, helper) { 3 | const searchString = event.target.value; 4 | if (searchString.length >= 3) { 5 | //Ensure that not many function execution happens if user keeps typing 6 | if (component.get("v.inputSearchFunction")) { 7 | clearTimeout(component.get("v.inputSearchFunction")); 8 | } 9 | 10 | var inputTimer = setTimeout($A.getCallback(function () { 11 | helper.searchRecords(component, searchString); 12 | }), 1000); 13 | component.set("v.inputSearchFunction", inputTimer); 14 | } else{ 15 | component.set("v.results", []); 16 | component.set("v.openDropDown", false); 17 | } 18 | }, 19 | 20 | optionClickHandler : function (component, event, helper) { 21 | const selectedId = event.target.closest('li').dataset.id; 22 | const selectedValue = event.target.closest('li').dataset.value; 23 | component.set("v.inputValue", selectedValue); 24 | component.set("v.openDropDown", false); 25 | component.set("v.selectedOption", selectedId); 26 | }, 27 | 28 | clearOption : function (component, event, helper) { 29 | component.set("v.results", []); 30 | component.set("v.openDropDown", false); 31 | component.set("v.inputValue", ""); 32 | component.set("v.selectedOption", ""); 33 | }, 34 | }) 35 | -------------------------------------------------------------------------------- /AutoComplete/AutoCompleteControllerTest.cls: -------------------------------------------------------------------------------- 1 | @isTest 2 | public with sharing class AutoCompleteControllerTest { 3 | @TestSetup 4 | static void makeData(){ 5 | Account acc = new Account(Name='Salesforce'); 6 | insert acc; 7 | } 8 | 9 | @isTest 10 | public static void testGetRecords(){ 11 | List accounts = AutoCompleteController.getRecords('sales', 'Account', 'Id', 'Name', null, 10); 12 | System.assertEquals(1, accounts.size()); 13 | accounts = AutoCompleteController.getRecords('abc', 'Account', 'Id', 'Name', '', 100); 14 | System.assertEquals(0, accounts.size()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /AutoComplete/AutoCompleteControllerTest.cls-meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 45.0 4 | Active 5 | 6 | -------------------------------------------------------------------------------- /AutoComplete/AutoCompleteHelper.js: -------------------------------------------------------------------------------- 1 | ({ 2 | searchRecords : function(component, searchString) { 3 | var action = component.get("c.getRecords"); 4 | action.setParams({ 5 | "searchString" : searchString, 6 | "objectApiName" : component.get("v.objectApiName"), 7 | "idFieldApiName" : component.get("v.idFieldApiName"), 8 | "valueFieldApiName" : component.get("v.valueFieldApiName"), 9 | "extendedWhereClause" : component.get("v.extendedWhereClause"), 10 | "maxRecords" : component.get("v.maxRecords") 11 | }); 12 | action.setCallback(this,function(response) { 13 | var state = response.getState(); 14 | if (state === "SUCCESS") { 15 | const serverResult = response.getReturnValue(); 16 | const results = []; 17 | serverResult.forEach(element => { 18 | const result = {id : element[component.get("v.idFieldApiName")], value : element[component.get("v.valueFieldApiName")]}; 19 | results.push(result); 20 | }); 21 | component.set("v.results", results); 22 | if(serverResult.length>0){ 23 | component.set("v.openDropDown", true); 24 | } 25 | } else{ 26 | var toastEvent = $A.get("e.force:showToast"); 27 | if(toastEvent){ 28 | toastEvent.setParams({ 29 | "title": "ERROR", 30 | "type": "error", 31 | "message": "Something went wrong!! Check server logs!!" 32 | }); 33 | toastEvent.fire(); 34 | } 35 | } 36 | }); 37 | $A.enqueueAction(action); 38 | } 39 | }) 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AutoComplete-Lightning-Component 2 |

A custom component which will allow the user to search for records from Salesforce objects and create a dropdown populated with matching records.

3 | 4 |

The component can query records from any Salesforce object and can display matching records as a drop down. It accepts a few attributes which give you the power to control the component as per your use case.

5 | 6 | label - String type attribute. Display a label over the component if a value is supplied. 7 | 8 | objectApiName - String type attribute. Supply the API name of the object you want to query. 9 | 10 | idFieldApiName - String type attribute. Supply the API name of Id field you want to fetch. Most of the times you want to standard Id field of the record, but in case, you want any other field to act as an Id field in the dropdown, you can simply provide the API name of the field. 11 | 12 | valueFieldApiName - String type attribute. Supply the API name of the field you want to get value from. The values are displayed in the dropdown. 13 | 14 | extendedWhereClause - String type attribute. The component can also take additional where clause for backend query. Use this attribute to supply additional conditions to your query. Example: 15 | 'AND Amount > 1000' 16 | 17 | maxRecords - Number type attribute. The maximum matching records you want to fetch and display as dropdown. Default is 10. 18 | 19 |

Below are some of the examples of how you can invoke the component:

20 | 1. Fetching Account Records with Name- 21 | 22 | 23 | 24 | 2. Fetching Opportunity Records with Name having Amount>1000 - 25 | 26 | 27 | 28 | 3. Fetching record from custom object "Car__c", here Id field is a custom field "Car_External_Id__c", value field is standard "Name" field, max record fetched can be 20 - 29 | 30 | 31 | 32 | ![AutoComplete GIF](AutoComplete.gif) 33 | --------------------------------------------------------------------------------