/*
|
* @Description:
|
* @version:
|
* @Author: chen jing wu
|
* @Date: 2023-04-28 17:41:48
|
* @LastEditors: chen jing wu
|
* @LastEditTime: 2023-04-28 17:50:29
|
*/
|
import { api, LightningElement, track } from 'lwc';
|
import lexmultiSelectComboboxItem from 'c/lexmultiSelectComboboxItem';
|
export default class LexmultiSelectCombobox extends LightningElement {
|
/**
|
* If present, the combobox is disabled and users cannot interact with it.
|
* @type {boolean}
|
* @default false
|
*/
|
@api disabled = false;
|
|
/**
|
* Text label for the combobox.
|
* @type {string}
|
* @default ''
|
*/
|
@api label = '';
|
/**
|
* Specifies the name of the combobox.
|
* @type {string}
|
*/
|
@api name;
|
/**
|
* A list of options that are available for selection. Each option has the following attributes: label and value.
|
* @type {Array}
|
* @example
|
* options = [
|
* {
|
* "label": "Option 1",
|
* "value": "option1"
|
* },
|
* {
|
* "label": "Option 2",
|
* "value": "option2"
|
* },
|
* ]
|
*/
|
@api options = [];
|
/**
|
* Text that is displayed before an option is selected, to prompt the user to select an option.
|
* @type {string}
|
* @default 'Select an Option'
|
*/
|
@api placeholder = 'Select an Option';
|
/**
|
* If present, the combobox is read-only. A read-only combobox is also disabled.
|
* @type {boolean}
|
* @default false
|
*/
|
@api readOnly = false;
|
/**
|
* If present, a value must be selected before a form can be submitted.
|
* @type {boolean}
|
* @default false
|
*/
|
@api required = false;
|
/**
|
* If present, the combobox only allows the selection of a single value.
|
* @type {boolean}
|
* @default false
|
*/
|
@api singleSelect = false;
|
/**
|
* If present, the combobox will show a pill container with the currently selected options.
|
* @type {boolean}
|
* @default false
|
*/
|
@api showPills = false;
|
@track currentOptions = [];
|
selectedItems = [];
|
selectedOptions = [];
|
isInitialized = false;
|
isLoaded = false;
|
isVisible = false;
|
isDisabled = false;
|
connectedCallback() {
|
this.isDisabled = this.disabled || this.readOnly;
|
this.hasPillsEnabled = this.showPills && !this.singleSelect;
|
}
|
renderedCallback() {
|
if (!this.isInitialized) {
|
this.template.querySelector('.multi-select-combobox__input').addEventListener('click', (event) => {
|
this.handleClick(event.target);
|
event.stopPropagation();
|
});
|
this.template.addEventListener('click', (event) => {
|
event.stopPropagation();
|
});
|
document.addEventListener('click', () => {
|
this.close();
|
});
|
this.isInitialized = true;
|
this.setSelection();
|
}
|
}
|
handleChange(event) {
|
this.change(event);
|
}
|
handleRemove(event) {
|
this.selectedOptions.splice(event.detail.index, 1);
|
this.change(event);
|
}
|
handleClick() {
|
// initialize picklist options on first click to make them editable
|
if (this.isLoaded === false) {
|
this.currentOptions = JSON.parse(JSON.stringify(this.options));
|
this.isLoaded = true;
|
}
|
if (this.template.querySelector('.slds-is-open')) {
|
this.close();
|
} else {
|
this.template.querySelectorAll('.multi-select-combobox__dropdown').forEach((node) => {
|
node.classList.add('slds-is-open');
|
});
|
}
|
}
|
change(event) {
|
// remove previous selection for single select picklist
|
if (this.singleSelect) {
|
this.currentOptions.forEach((item) => (item.selected = false));
|
}
|
// set selected items
|
this.currentOptions
|
.filter((item) => item.value === event.detail.item.value)
|
.forEach((item) => (item.selected = event.detail.selected));
|
this.setSelection();
|
const selection = this.getSelectedItems();
|
this.dispatchEvent(new CustomEvent('change', { detail: this.singleSelect ? selection[0] : selection }));
|
// for single select picklist close dropdown after selection is made
|
if (this.singleSelect) {
|
this.close();
|
}
|
}
|
close() {
|
this.template.querySelectorAll('.multi-select-combobox__dropdown').forEach((node) => {
|
node.classList.remove('slds-is-open');
|
});
|
this.dispatchEvent(new CustomEvent('close'));
|
}
|
setSelection() {
|
const selectedItems = this.getSelectedItems();
|
let selection = '';
|
if (selectedItems.length < 1) {
|
selection = this.placeholder;
|
this.selectedOptions = [];
|
} else if (selectedItems.length > 2) {
|
selection = `${selectedItems.length} Options Selected`;
|
this.selectedOptions = this.getSelectedItems();
|
} else {
|
selection = selectedItems.map((selected) => selected.label).join(', ');
|
this.selectedOptions = this.getSelectedItems();
|
}
|
this.selectedItems = selection;
|
this.isVisible = this.selectedOptions && this.selectedOptions.length > 0;
|
}
|
|
getSelectedItems() {
|
return this.currentOptions.filter((item) => item.selected);
|
}}
|