How to create a reusable field search Lightning Web Component

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

 

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, is fetched from Apex as a list using the Wire Service.
      • With each letter entered in the search field, the Wire Service fetches from Apex a list of all fields where the entered word occurs as a partial word and displays all found fields.
      • After selecting a field, the dropdown list closes and displays the selected field as a lightning-pill.
How to create a reusable field search Lightning Component

fieldSearch.html

<template>
    <div class="slds-combobox_container">
        <div class={boxClass} aria-expanded="true" aria-haspopup="listbox" role="combobox">
            <div class="slds-combobox__form-element" role="none">
                <template if:true={isValueSelected}>
                    <div class="slds-pill-container">
                        <lightning-pill
                                class="pillSize"
                                label={selectedFieldLabel}
                                onremove={handleRemovePill}
                        >
                        </lightning-pill>
                    </div>
                </template>
                <template if:false={isValueSelected}>
                    <lightning-input
                            class={inputClass}
                            type="search"
                            variant="label-hidden"
                            label=""
                            placeholder={searchPlaceholder}
                            value={searchTerm}
                            onclick={handleClick}
                            onchange={onChange}
                            autocomplete="false"
                    >
                    </lightning-input>
                </template>
            </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">
                    <template for:each={listOfFields} for:item="rec">
                        <li key={rec} data-id={rec.fieldName} data-name={rec.fieldLabel} data-item={rec.fieldType} onclick={onSelect} role="presentation">
                            <span class="slds-lookup__item-action" role="option">
                                <span class="slds-truncate">{rec.fieldLabel}</span>
                            </span>
                        </li>
                    </template>
                </ul>
            </div>
        </div>
    </div>
</template>

fieldSearch.js

import {api, LightningElement, wire} from 'lwc';

import getListOfFields from '@salesforce/apex/SfWiki_Handler.getListOfFields';

export default class FieldSearch extends LightningElement {

    @api searchPlaceholder = "Search";
    @api isValueSelected;
    @api selectedFieldLabel;
    @api sObjectName;

    listOfFields;
    searchTerm;

    //CSS
    boxClass = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus';
    inputClass = '';

    @wire(getListOfFields, {sObjectName: '$sObjectName', searchTerm : '$searchTerm'})
    wiredRecords({ error, data }) {
        if (data) {
            let listOfFields = [];
            for(let i = 0; i < data.length; i++) {
                let tempRecord = Object.assign({}, data[i]); //cloning object
                listOfFields.push(tempRecord);
            }
            listOfFields.sort(this.compare);
            this.listOfFields = listOfFields;
        } else if (error) {
            console.log(error);
        }
    }

    handleClick() {
        this.searchTerm = '';
        this.inputClass = 'slds-has-focus';
        this.boxClass = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus slds-is-open';
    }

    onSelect(event) {
        let selectedFieldApiName = event.currentTarget.dataset.id;
        this.selectedFieldLabel = event.currentTarget.dataset.name;
        let selectedFieldType = event.currentTarget.dataset.item;
        const valueSelectedEvent = new CustomEvent('fieldselected', {
            detail: {
                selectedFieldApiName: selectedFieldApiName,
                selectedFieldType: selectedFieldType,
                selectedFieldLabel: this.selectedFieldLabel,
            }});
        this.dispatchEvent(valueSelectedEvent);
        this.isValueSelected = true;
        this.boxClass = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus';
    }

    handleRemovePill() {
        this.isValueSelected = false;
    }

    onChange(event) {
        this.searchTerm = event.target.value;
    }

    /**
     * This function compares two fields (for sorting purposes) with each other
     */
    compare(a, b) {
        // Use toUpperCase() to ignore character casing
        const fieldLabelA = a.fieldLabel.toUpperCase();
        const fieldLabelB = b.fieldLabel.toUpperCase();

        let comparison = 0;
        if (fieldLabelA > fieldLabelB) {
            comparison = 1;
        } else if (fieldLabelA < fieldLabelB) {
            comparison = -1;
        }
        return comparison;
    }

}

Ctrl_fieldSearch.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; }
    }

}

That’s it!

I hope you have enjoyed learning “How to create a reusable field search Lightning Web Component”. 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!

How to assign Profile User to a Permission Set in Apex

How to assign Profile User to a Permission Set in Apex?It often happens that one of my...

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 [LWC]

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

How to add or remove rows dynamically [LWC]

In this tutorial, I will show you how to add or remove rows dynamically in Lightning Web Components.

How to navigate through Lightning Components [LWC]

In this tutorial, I will show you how to navigate through Lightning Components in Lightning Web Components.

Leave a comment!

5 1 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
devHamid