Icon for the Lightning Components topic

How to create a reusable field search Lightning Component [Aura]

In this tutorial, I will show you how to create a reusable field search Lightning Component using Lightning Aura Components. In the GIF below you can see the final result.

How to create a reusable field search Lightning Component

A brief summary of how the field search Lightning Component works:

  • It has two important parts: a search field and a dropdown suggestion list.
  • The data, in this case all the fields of the Account SObject, are fetched from Apex (getListOfFields) as a list when the component is initialized (doInit).
  • With each letter entered in the search field, the dropdown list opens and displays suggestions from the list of all Account fields based on the entered word.
  • After selecting a field, the dropdown list closes and displays the selected field as a lightning:pill.

searchObjectFields.cmp

<aura:component controller="SfWiki_Handler" access="global">

    <!-- Attributes -->
    <aura:attribute name="searchPlaceholder" type="String" default="Search"/>
    <aura:attribute name="isValueSelected" type="Boolean" default="false"/>
    <aura:attribute name="selectedFieldLabel" type="String" default=""/>
    <aura:attribute name="sObjectName" type="String" default=""/>
    <aura:attribute name="listOfAllFields" type="List"/>
    <aura:attribute name="listOfFilteredFields" type="List"/>
    <aura:attribute name="searchTerm" type="String" default=""/>
    <aura:attribute name="boxClass" type="String" default="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus"/>
    <aura:attribute name="inputClass" type="String" default="false"/>

    <!-- Initialization Method -->
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <!-- Register Event -->
    <aura:registerEvent name="searchFieldEvent" type="c:componentEvent"/>

    <div class="slds-combobox_container">
        <div class="{!v.boxClass}" aria-expanded="true" aria-haspopup="listbox" role="combobox">
            <div class="slds-combobox__form-element" role="none">
                <aura:renderIf isTrue="{!v.isValueSelected}">
                    <div class="slds-pill-container">
                        <lightning:pill
                                class="pillSize"
                                label="{!v.selectedFieldLabel}"
                                onremove="{!c.handleRemovePill}"
                        />
                    </div>
                    <aura:set attribute="else">
                        <lightning:input
                                class="{!v.inputClass}"
                                type="search"
                                variant="label-hidden"
                                label=""
                                placeholder="{!v.searchPlaceholder}"
                                value="{!v.searchTerm}"
                                onfocus="{!c.handleClick}"
                                onchange="{!c.handleSearch}"
                                autocomplete="off"
                        />
                    </aura:set>
                </aura:renderIf>
            </div>
            <div 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.listOfFilteredFields}" var="rec">
                        <li data-id="{!rec.fieldName}" data-name="{!rec.fieldLabel}" data-item="{!rec.fieldType}" onclick="{!c.onSelect}" role="presentation">
                            <span class="slds-lookup__item-action" role="option">
                                <span class="slds-truncate">{!rec.fieldLabel}</span>
                            </span>
                        </li>
                    </aura:iteration>
                </ul>
            </div>
        </div>
    </div>

</aura:component>

searchObjectFieldsController.js

({
    doInit: function(component, event, helper) {
        let action = component.get("c.getListOfFields");
        action.setParams({
            sObjectName : "Account",
            searchTerm: ""
        });
        action.setCallback(this, function(response) {
            let listOfFields = [];
            for(let i = 0; i < response.getReturnValue().length; i++) {
                let tempRecord = Object.assign({}, response.getReturnValue()[i]); //cloning object
                listOfFields.push(tempRecord);
            }
            listOfFields.sort(helper.compare);
            component.set("v.listOfAllFields", listOfFields);
            component.set("v.listOfFilteredFields", listOfFields);
        });
        $A.enqueueAction(action);
    },

    handleClick: function(component, event, helper) {
        component.set("v.searchTerm", "");
        component.set("v.inputClass", "slds-has-focus");
        component.set("v.boxClass", "slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus slds-is-open");
    },

    handleSearch: function(component, event, helper) {
        let searchTerm = component.get("v.searchTerm");
        let listOfAllFields = component.get("v.listOfAllFields");

        let listOfFilteredFields = [];
        for (let i = 0; i < listOfAllFields.length; i++) {
            if (listOfAllFields[i].fieldLabel.toLowerCase().includes(searchTerm.toLowerCase())) {
                listOfFilteredFields.push(listOfAllFields[i]);
            }
        }

        component.set("v.listOfFilteredFields", listOfFilteredFields);
    },

    onSelect: function(component, event, helper) {
        let selectedFieldApiName = event.currentTarget.dataset.id;
        let selectedFieldLabel = event.currentTarget.dataset.name;
        let selectedFieldType = event.currentTarget.dataset.item;
        component.set("v.selectedFieldLabel", selectedFieldLabel);

        //Send the selected field to "Example Component"
        let componentEvent = component.getEvent("searchFieldEvent");
        componentEvent.setParams({
            "selectedFieldApiName" : selectedFieldApiName,
            "selectedFieldLabel" : selectedFieldLabel,
            "selectedFieldType" : selectedFieldType
        });
        componentEvent.fire();

        component.set("v.isValueSelected", true);
        component.set("v.boxClass", "slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus");
    },

    handleRemovePill: function(component, event, helper) {
        component.set("v.isValueSelected", false);
        component.set("v.searchTerm", "");
        component.set("v.listOfFilteredFields", component.get("v.listOfAllFields"));
    }

});

SfWiki_Handler.cls

public without sharing class SfWiki_Handler {

    @AuraEnabled(Cacheable=true)
    public static List<Fields> getListOfFields(String sObjectName, String searchTerm) {
        List<Fields> listOfFields = new List<Fields>();

        Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
        Map<String, Schema.SObjectField> fieldMap = schemaMap.get(sObjectName).getDescribe().fields.getMap();

        for(String fieldName : fieldMap.keySet()) {
            //We don't want to search for fields with these data-types: ADDRESS, REFERENCE, ID & URL
            if(String.valueOf(fieldMap.get(fieldName).getDescribe().getType()) != 'ADDRESS'
                    && String.valueOf(fieldMap.get(fieldName).getDescribe().getType()) != 'REFERENCE'
                    && String.valueOf(fieldMap.get(fieldName).getDescribe().getType()) != 'ID'
                    && String.valueOf(fieldMap.get(fieldName).getDescribe().getType()) != 'URL') {
                if(String.valueOf(fieldMap.get(fieldName).getDescribe().getLabel().toLowerCase()).contains(searchTerm.toLowerCase())) {
                    Fields newFieldProperties = new Fields();
                    newFieldProperties.fieldLabel = fieldMap.get(fieldName).getDescribe().getLabel();
                    newFieldProperties.fieldName = fieldMap.get(fieldName).getDescribe().getName();
                    newFieldProperties.fieldType = String.valueOf(fieldMap.get(fieldName).getDescribe().getType());
                    listOfFields.add(newFieldProperties);
                }
            }

        }

        return listOfFields;
    }

    public class Fields {
        @AuraEnabled
        public String fieldLabel { get; set; }
        @AuraEnabled
        public String fieldName { get; set; }
        @AuraEnabled
        public String fieldType { get; set; }
    }

}

Example how to use

exampleComponent.cmp

<aura:component implements="flexipage:availableForAllPageTypes" access="global">

    <!-- Attributes -->
    <aura:attribute name="accountId" type="Id" default=""/>
    <aura:attribute name="selectedFieldLabel" type="String" default=""/>
    <aura:attribute name="selectedFieldApiName" type="String" default=""/>
    <aura:attribute name="selectedFieldType" type="String" default=""/>

    <!-- Event Handler -->
    <aura:handler name="searchFieldEvent" event="c:componentEvent" action="{!c.handleComponentEvent}"/>

    <div class="slds-card" style="font-family: 'Open Sans', sans-serif">

        <!-- Header -->
        <header class="slds-card__header slds-media slds-media_center">
            <div class="slds-media__figure">
                <lightning:icon iconName="standard:custom_notification" size="small"/>
            </div>
            <div class="slds-media__body slds-card__header-title slds-text-title_bold" style="font-size: 14px">
                Example Component
            </div>
        </header>

        <!-- Body -->
        <div class="slds-p-around_small">
            <div class="slds-text-align_center slds-container_center" style="font-size: 15px;">
                <div class="slds-size_2-of-3 slds-align_absolute-center slds-p-bottom_small">
                    <c:searchObjectFields
                            sObjectName="Account"
                            searchPlaceholder="Search Account field"
                    />
                </div>
                <p>Field-Label: <span style="font-weight: bold">{!v.selectedFieldLabel}</span></p>
                <p>Field-API-Name: <span style="font-weight: bold">{!v.selectedFieldApiName}</span></p>
                <p>Field-Datatype: <span style="font-weight: bold">{!v.selectedFieldType}</span></p>
                <p class="slds-p-top_small">Hope you like this tutorial</p>
                <p style="font-weight: bold; color: red">Sf <span style="font-weight: bold; color: black">Wiki</span></p>
            </div>
        </div>

    </div>

</aura:component>

exampleComponentController.js

({
    handleComponentEvent : function(component, event, helper) {
        component.set("v.selectedFieldLabel", event.getParam("selectedFieldLabel"));
        component.set("v.selectedFieldApiName", event.getParam("selectedFieldApiName"));
        component.set("v.selectedFieldType", event.getParam("selectedFieldType"));
    }
});

That’s it!

I hope you have enjoyed learning “How to create a reusable field search Lightning Component [Aura]”. Please share your thoughts in the comments below. If you find value in this type of post, please subscribe because we have tons of tutorials in progress to be posted!

If you prefer to see the result with Lightning Web Components, here’s the link to it: How to create a reusable field search Lightning Component [LWC].

How to create a reusable field search Lightning Component using Lightning Aura Components

How to create a reusable field search Lightning Component [Aura]

In this tutorial, I will show you how to create a reusable field search Lightning Component in Lightning Aura Components.

How to create a reusable field search Lightning Component using Lightning Web Components

How to create a reusable field search Lightning Component [LWC]

In this tutorial, I will show you how to create a reusable field search Lightning Component in Lightning Web Components.

How to create a reusable Lookup Lightning Component

How to create a reusable Lookup Lightning Component [Aura]

In this tutorial, I will show you how to create a reusable Lookup Lightning Component in Lightning Aura Components.

How to create a reusable Lookup Lightning Component

How to create a reusable Lookup Lightning Component [LWC]

In this tutorial, I will show you how to create a reusable Lookup Lightning Component in Lightning Web Components.

How to remove Lightning App Page Header

How to remove Lightning App Page Header [Aura]

In this tutorial, I will show you how to remove Lightning App Page Header in Lightning Aura Components.

Leave a comment!

0 0 votes
Article Rating
guest
0 Comments
Inline Feedbacks
View all comments
Hamid Abassi

Hamid Abassi

SfWiki Founder

I am a Salesforce Developer from Hamburg who wants to help the Salesforce Community around the world with my tutorials. Feel free to explore my website and hopefully learn something new.