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>
<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 ({error, data}) {
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(index, 1);
if(this.pillRecordsList.length==0){
this.isShowPillContainer =false;
}
}
}
Output:
customlookup.css :
.searchButtonStyle{
margin-top: 4px;
margin-right: 0px;
}
Reference :
https://www.lightningdesignsystem.com/components/lookups/#site-main-content
https://developer.salesforce.com/docs/component-library/bundle/lightning-pill-container/example