Saturday, 25 September 2021

Custom Lookup with multiple record selection lwc

 Hi,

Here are we are going to learn how to design custom lookup with multi-selection with the help of lightning-pill-container.

For designing custom lookup, we are simply using CSS from Lightning Design System here.

customlookup.html

<template>
    <div class="slds-p-horizontal_small">
        <div class="row">
            <div class="slds-form-element">
                <div class="slds-form-element__control">
                    <div class="slds-combobox_container">
                        <div 
                            class="slds-combobox slds-dropdown-trigger 
                            slds-dropdown-trigger_click" aria-expanded="false"
                            aria-haspopup="listbox" role="combobox">
                            <div class="slds-combobox__form-element 
                                slds-input-has-icon slds-input-has-icon_right"
                                role="none">
                                <lightning-input type="text" id="combobox-id-16" 
                                    value={accountName}
                                    onchange={handleKeyChange} 
                                    onkeydown={handleClick} onclick={handleClick}
                                    onblur={handleClick} 
                                    aria-activedescendant="option1" label='Account'
                                    aria-autocomplete="list" 
                                    aria-controls="listbox-id-12" role="textbox"
                                    placeholder="Search..."></lightning-input>                                  
                            <button
                                    class="slds-button 
                                slds-button_icon slds-input__icon 
                                slds-input__icon_right searchButtonStyle"
                                    title="Remove selected option">
                                    <lightning-button-icon 
                                            icon-name="utility:search" variant="bare" 
                                            alternative-text="Search"
                                             aria-hidden="true" 
                                        onclick={handleOpenModal}>
                                    </lightning-button-icon>
                           </button>    
                            </div>
                            <!-- Start : Parent Search Result -->
                            <div if:true={messageResult}>
                                No Result Found!
                            </div>
                            <template if:true={showSearchedValues}>
                                <div class="slds-box" 
                                    style="height: 130px; 
                                    overflow-y: scroll;">
                                    <ul class="" role="">
                                        <template for:each={accountList} 
                                                for:item="actObj">
                                            <li 
                                               class="slds-p-around_x-small" 
                                               style="cursor: pointer;" 
                                               key={actObj.Id}
                                               onclick={handleParentSelection} 
                                               data-value={actObj.Id}
                                               data-label={actObj.Name}>
                                               {actObj.Name}
                                            </li>
                                        </template>
                                    </ul>
                                </div>
                            </template>
                        </div>      
                            <template if:true={isShowPillContainer}>
                                <lightning-pill-container
                                     items={pillRecordsList}
                                    onitemremove={handleItemRemove}>
                                </lightning-pill-container>  
                            </template>
                                        
                    </div>
                    
                </div>
            </div>
        </div>
    </div>

    <section role="dialog" if:true={isshow}  tabindex="-1" 
            class="slds-modal slds-fade-in-open" 
                aria-labelledby="modal-heading-01" 
                aria-modal="true" aria-describedby="modal-content-id-1">
            
        <div class="slds-modal__container">
          <header class="slds-modal__header">
            <lightning-button-icon
            icon-name="utility:close"
            variant="bare"
            onclick={handleCloseModal}
            alternative-text="Close window" style="float: right;">
        </lightning-button-icon>
            <h2 id="modal-heading-01" class="slds-modal__title 
                slds-hyphenate">
                Account Creation
            </h2>
          </header>
          <div class="slds-modal__content slds-p-around_medium" 
                id="modal-content-id-1">
            <lightning-record-edit-form object-api-name="Account" 
                    onsuccess={handleSuccess}>
                <lightning-messages>
                </lightning-messages>
                <lightning-input-field field-name="Name">
                    
                </lightning-input-field>
                <lightning-input-field field-name="Industry">
                    
                </lightning-input-field>
                <div class="slds-m-top_medium">
                    <lightning-button class="slds-m-top_small" 
                        label="Cancel" 
                        onclick={handleReset}></lightning-button>&nbsp;
                    <lightning-button class="slds-m-top_small" 
                        variant="brand"  
                        type="submit" label="Save Record"></lightning-button>
                </div>
                  
            </lightning-record-edit-form>            
          </div>          
        </div>
      </section>
      <div class="slds-backdrop slds-backdrop_open" if:true={isshow}>
        </div>
</template>

customlookup.js

   
import { LightningElement,wire,track } from 'lwc';
import getAccounts 
    from '@salesforce/apex/AccountSearchController.getAccounts';
export default class CustomLookup extends LightningElement {
        accountName = '';
        accountList = [];     
        accountId
        isshow=false;
        messageResult=false;
        isShowResult = true;   
        showSearchedValues = false;   
        @track pillRecordsList = [];
        pillRecordIdList = [];
        isShowPillContainer = false;
        @wire(getAccounts, {actName:'$accountName'})
        retrieveAccounts ({errordata}) {
        this.messageResult=false;
        if (data) {
            // TODO: Error handling 
            console.log('data::'+data.length);
            if(data.length>0 && this.isShowResult){
                this.accountList = data;                
                this.showSearchedValues = true
                this.messageResult=false;
            }            
            else if(data.length==0){
                this.accountList = [];                
                this.showSearchedValues = false;
                if(this.accountName!='')
                    this.messageResult=true;               
            }  
                
        } else if (error) {
            // TODO: Data handling
            this.accountId =  '';
            this.accountName =  '';
            this.accountList=[];           
            this.showSearchedValues = false;
            this.messageResult=true;   
        }
    }
    handleClick(event){
        this.isShowResult = true;   
        this.messageResult=false;        
    }
    handleKeyChange(event){       
        this.messageResult=false
        this.accountName = event.target.value;
    }  
    handleParentSelection(event){        
        this.showSearchedValues = false;
        this.isShowResult = false;
        this.messageResult=false;
        //Set the parent calendar id
        this.accountId =  event.target.dataset.value;
        //Set the parent calendar label
        this.accountName =  event.target.dataset.label;   
        if(!this.pillRecordIdList.includes(this.accountId)){
            let record = {"type":"icon""label": this.accountName,
                "iconName": "standard:account","name": this.accountId};  
            console.log('accountId::'+this.accountId);    
            this.pillRecordsList.push(record);
            if(this.pillRecordsList){
                this.isShowPillContainer = true;
            }
            this.pillRecordIdList.push(this.accountId);
        } 
       
        this.accountName = '';        
    }
    handleOpenModal(event){
        this.isshow = true;
        console.log('balaji:::');
    }
    handleCloseModal(event){
        this.isshow = false;
    }
    handleSuccess(event){       
        this.isShowResult = false;
        this.messageResult=false;
        this.isshow = false;
        this.accountId = event.detail.id;
        console.log(event.detail.id);
        //console.log('JSON OBject:'+JSON.stringify(event.detail));
        this.accountName = event.detail.fields.Name.value;
        if(!this.pillRecordIdList.includes(this.accountId)){
            let record = {"type":"icon""label": this.accountName,
                "iconName": "standard:account","name": this.accountId};  
            console.log('accountId::'+this.accountId);    
            this.pillRecordsList.push(record);
            if(this.pillRecordsList){
                this.isShowPillContainer = true;
            }
            this.pillRecordIdList.push(this.accountId);
        } 
       
        this.accountName = '';
        const selectedEvent = new CustomEvent('selected', { detail: this.accountId });
        // Dispatches the event.
        this.dispatchEvent(selectedEvent);
    }
    handleReset(event) {
        const inputFields = this.template.querySelectorAll(
            'lightning-input-field'
        );
        if (inputFields) {
            inputFields.forEach(field => {
                field.reset();
            });
        }
        this.isshow = false;
    }

    handleItemRemove (event) {
        const name = event.detail.item.name;
        console.log(name + ' pill was removed!');
        const index = event.detail.index;
        this.pillRecordsList.splice(index1);
        if(this.pillRecordsList.length==0){
            this.isShowPillContainer =false;
        }
    }
}


Output:






customlookup.css :

.searchButtonStyle{
    margin-top4px;
    margin-right0px;
}


Reference : 

https://www.lightningdesignsystem.com/components/lookups/#site-main-content

https://developer.salesforce.com/docs/component-library/bundle/lightning-pill-container/example







What’s the difference between Einstein Article Recommendations and Suggested Articles?

How Does Einstein Article Recommendations Work? Einstein Article Recommendations helps support agents resolve customer cases efficiently by ...