buli
2023-05-22 71b93327e8f3fb3bffffc7c033c1f782e7b6ab32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
 * @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);
}}