LWC Components Used In this Project
- multiSelectPicklistLwc: In this component we can select multiple filters and we are showing catalog products according to filters


multiSelectPicklistLwc JS Controller
import { LightningElement, track, api } from 'lwc';
export default class MultiSelectCombobox extends LightningElement {
@api options;
@api selectedValue;
@api selectedValues = [];
@api label;
@api name;
@api minChar = 2;
@api disabled = false;
@api multiSelect = false;
@track value;
@track values = [];
@track optionData;
@track searchString;
@track message;
@track showDropdown = false;
connectedCallback() {
this.showDropdown = false;
var optionData = this.options ? (JSON.parse(JSON.stringify(this.options))) : null;
var value = this.selectedValue ? (JSON.parse(JSON.stringify(this.selectedValue))) : null;
var values = this.selectedValues ? (JSON.parse(JSON.stringify(this.selectedValues))) : null;
if(value || values) {
var searchString;
var count = 0;
for(var i = 0; i < optionData.length; i++) {
if(this.multiSelect) {
if(values.includes(optionData[i].value)) {
optionData[i].selected = true;
count++;
}
} else {
if(optionData[i].value == value) {
searchString = optionData[i].label;
}
}
}
if(this.multiSelect)
this.searchString = count + ' Option(s) Selected';
else
this.searchString = searchString;
}
this.value = value;
this.values = values;
this.optionData = optionData;
}
@api refresh(val) {
this.selectedValue = val;
this.showDropdown = false;
var optionData = this.options ? (JSON.parse(JSON.stringify(this.options))) : null;
var value = this.selectedValue ? (JSON.parse(JSON.stringify(this.selectedValue))) : null;
var values = this.selectedValues ? (JSON.parse(JSON.stringify(this.selectedValues))) : null;
if(value || values) {
var searchString;
var count = 0;
for(var i = 0; i < optionData.length; i++) {
if(this.multiSelect) {
if(values.includes(optionData[i].value)) {
optionData[i].selected = true;
count++;
}
} else {
if(optionData[i].value == value) {
searchString = optionData[i].label;
}
}
}
if(this.multiSelect)
this.searchString = count + ' Option(s) Selected';
else
this.searchString = searchString;
}
this.value = value;
this.values = values;
this.optionData = optionData;
}
filterOptions(event) {
this.searchString = event.target.value;
if( this.searchString && this.searchString.length > 0 ) {
this.message = '';
if(this.searchString.length >= this.minChar) {
var flag = true;
for(var i = 0; i < this.optionData.length; i++) {
if(this.optionData[i].label.toLowerCase().trim().startsWith(this.searchString.toLowerCase().trim())) {
this.optionData[i].isVisible = true;
flag = false;
} else {
this.optionData[i].isVisible = false;
}
}
if(flag) {
this.message = "No results found for '" + this.searchString + "'";
}
}
this.showDropdown = true;
} else {
this.showDropdown = false;
}
}
selectItem(event) {
var selectedVal = event.currentTarget.dataset.id;
if(selectedVal) {
var count = 0;
var options = JSON.parse(JSON.stringify(this.optionData));
for(var i = 0; i < options.length; i++) {
if(options[i].value === selectedVal) {
if(this.multiSelect) {
if(this.values.includes(options[i].value)) {
this.values.splice(this.values.indexOf(options[i].value), 1);
} else {
this.values.push(options[i].value);
}
options[i].selected = options[i].selected ? false : true;
} else {
this.value = options[i].value;
this.searchString = options[i].label;
}
}
if(options[i].selected) {
count++;
}
}
this.optionData = options;
if(this.multiSelect)
this.searchString = count + ' Option(s) Selected';
if(this.multiSelect)
event.preventDefault();
else
this.showDropdown = false;
}
}
showOptions() {
if(this.disabled == false && this.options) {
this.message = '';
this.searchString = '';
var options = JSON.parse(JSON.stringify(this.optionData));
for(var i = 0; i < options.length; i++) {
options[i].isVisible = true;
}
if(options.length > 0) {
this.showDropdown = true;
}
this.optionData = options;
}
}
removePill(event) {
var value = event.currentTarget.name;
var count = 0;
var options = JSON.parse(JSON.stringify(this.optionData));
for(var i = 0; i < options.length; i++) {
if(options[i].value === value) {
options[i].selected = false;
this.values.splice(this.values.indexOf(options[i].value), 1);
}
if(options[i].selected) {
count++;
}
}
this.optionData = options;
if(this.multiSelect)
this.searchString = count + ' Option(s) Selected';
this.dispatchValue();
}
blurEvent() {
var previousLabel;
var count = 0;
for(var i = 0; i < this.optionData.length; i++) {
if(this.optionData[i].value === this.value) {
previousLabel = this.optionData[i].label;
}
if(this.optionData[i].selected) {
count++;
}
}
if(this.multiSelect)
this.searchString = count + ' Option(s) Selected';
else
this.searchString = previousLabel;
this.showDropdown = false;
this.dispatchValue();
}
dispatchValue(){
this.dispatchEvent(new CustomEvent('select', {
detail: {
'payloadType' : 'multi-select',
'name': this.name,
'payload' : {
'value' : this.value,
'values' : this.values
}
}
}));
}
}
multiSelectPicklistLwc HTML
<template>
<!-- Header Label -->
<template if:true={label}>
<label class="slds-form-element__label">{label}</label>
</template>
<div class="slds-combobox_container">
<div class="slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-is-open" aria-expanded="true" aria-haspopup="listbox" role="combobox">
<!-- Search Input -->
<div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right" role="none">
<lightning-input disabled={disabled} class="inputBox" placeholder="Select an Option" onblur={blurEvent} onclick={showOptions} onkeyup={filterOptions} value={searchString} auto-complete="off" variant="label-hidden" id="combobox-id-1" ></lightning-input>
<lightning-icon class="slds-input__icon" icon-name="utility:down" size="x-small" alternative-text="search"></lightning-icon>
</div>
<!-- Dropdown List -->
<template if:true={showDropdown}>
<div id="listbox-id-1" class="slds-dropdown slds-dropdown_length-5 slds-dropdown_fluid"><!--style="{! 'max-height:' + (8 + (v.recordCount * 40)) + 'px' }""-->
<ul class="slds-listbox slds-listbox_vertical recordListBox" role="presentation">
<template if:false={message} >
<template for:each={optionData} for:item="option">
<template if:true={option.isVisible}>
<li key={option.value} data-id={option.value} onmousedown={selectItem} class="slds-listbox__item eachItem">
<template if:true={option.selected}>
<lightning-icon icon-name="utility:check" size="x-small" alternative-text="icon" ></lightning-icon>
</template>
<span class="slds-media slds-listbox__option_entity verticalAlign slds-truncate">{option.label}</span>
</li>
</template>
</template>
</template>
<template if:true={message} >
<li class="slds-listbox__item">
<span class="slds-media slds-listbox__option_entity verticalAlign slds-truncate">{message}</span>
</li>
</template>
</ul>
</div>
</template>
</div>
</div>
<!-- Multi Select Pills -->
<template for:each={optionData} for:item="option">
<template if:true={option.selected}>
<lightning-pill key={option.value} class="slds-m-around_xx-small" name={option.value} label={option.label} onremove={removePill}></lightning-pill>
</template>
</template>
</template>
multiSelectPicklistLwc CSS
.verticalAlign {
cursor: pointer;
padding: 0px 5px !important;
}
.slds-dropdown {
padding:0px !important;
}
.recordListBox {
margin-top:0px !important;
overflow-y: scroll;
}
.slds-listbox li {
padding: .45rem 0.7rem !important;
display: flex;
}
.inputBox input {
padding-left: 10px;
}
.eachItem:hover {
background-color: #F1F1F1;
cursor: pointer;
}
/* For Scrolling */
::-webkit-scrollbar {
width: 7px;
height: 7px;
}
::-webkit-scrollbar-track {
display: none !important;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: rgba(0,0,0,0.4);
}