• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { BaseElement, element } from '../BaseElement';
17import { LitSelectOption } from './LitSelectOption';
18import { selectHtmlStr, selectVHtmlStr } from './LitSelectHtml';
19
20@element('lit-select-v')
21export class LitSelectV extends BaseElement {
22  showItems: Array<string> = [];
23  ignoreValues: Array<string> = [];
24  itemValue: Array<string> = [];
25  customItem: Array<string> = [];
26  private focused: unknown;
27  private selectVInputEl: unknown;
28  private selectVSearchInputEl: unknown;
29  private selectVIconEl: unknown;
30  private selectVOptions: HTMLDivElement | undefined;
31  private selectVBody: HTMLDivElement | undefined;
32
33  private valueStr: string = '';
34  private currentvalueStr: string = '';
35
36  static get observedAttributes(): string[] {
37    return ['value', 'default-value', 'placeholder', 'disabled', 'show-search', 'border', 'mode'];
38  }
39
40  get value(): string {
41    // @ts-ignore
42    return this.selectVInputEl!.value || this.defaultValue;
43  }
44
45  get rounded(): boolean {
46    return this.hasAttribute('rounded');
47  }
48
49  set rounded(selectVRounded: boolean) {
50    if (selectVRounded) {
51      this.setAttribute('rounded', '');
52    } else {
53      this.removeAttribute('rounded');
54    }
55  }
56
57  get placement(): string {
58    return this.getAttribute('placement') || '';
59  }
60
61  set placement(selectVPlacement: string) {
62    if (selectVPlacement) {
63      this.setAttribute('placement', selectVPlacement);
64    } else {
65      this.removeAttribute('placement');
66    }
67  }
68
69  get border(): string {
70    return this.getAttribute('border') || 'true';
71  }
72
73  set border(selectVBorder) {
74    if (selectVBorder) {
75      this.setAttribute('border', 'true');
76    } else {
77      this.setAttribute('border', 'false');
78    }
79  }
80
81  get defaultPlaceholder(): string {
82    return this.getAttribute('placeholder') || '';
83  }
84
85  get defaultValue(): string {
86    return this.getAttribute('default-value') || '';
87  }
88
89  set defaultValue(selectVDefaultValue) {
90    this.setAttribute('default-value', selectVDefaultValue);
91  }
92
93  get placeholder(): string {
94    return this.getAttribute('placeholder') || this.defaultPlaceholder;
95  }
96
97  set placeholder(selectVPlaceholder) {
98    this.setAttribute('placeholder', selectVPlaceholder);
99  }
100
101  set all(isAll: boolean) {
102    if (isAll) {
103      this.setAttribute('is-all', '');
104    } else {
105      this.removeAttribute('is-all');
106    }
107  }
108
109  get all(): boolean {
110    return this.hasAttribute('is-all');
111  }
112
113  dataSource(selectVData: Array<string>, valueStr: string, isSingle?: boolean): void {
114    this.selectVOptions!.innerHTML = '';
115    if (selectVData.length > 0) {
116      this.selectVBody!.style.display = 'block';
117      this.valueStr = valueStr;
118      this.itemValue = selectVData;
119      if (valueStr !== '') {
120        let option = document.createElement('lit-select-option');
121        if (this.all) {
122          option.setAttribute('selected', '');
123          this.showItems = selectVData;
124        }
125        option.setAttribute('value', valueStr);
126        option.textContent = valueStr;
127        this.selectVOptions!.appendChild(option);
128        this.initDataItem(selectVData);
129        if (isSingle) {
130          this.initSingleCustomOptions();
131        } else {
132          this.initCustomOptions();
133        }
134      } else {
135        this.initDataItem(selectVData);
136        if (isSingle) {
137          this.initSingleCustomOptions();
138        } else {
139          this.initOptions();
140        }
141      }
142    } else {
143      this.selectVBody!.style.display = 'none';
144    }
145    if (this.title === 'Event List') {
146      let inputElement = this.shadowRoot?.querySelector('input') as HTMLInputElement;
147      inputElement.readOnly = false;
148    }
149  }
150
151  setIgnoreValues(values: string[]) {
152    this.ignoreValues = values;
153  }
154
155  setSelectedOptions(selectArray: Array<string>) {
156    let allSelected = true;
157    this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => {
158      if (selectArray.includes(a.textContent!)) {
159        a.setAttribute('selected', '');
160      } else {
161        allSelected = false;
162        a.removeAttribute('selected');
163      }
164    });
165    this.all = allSelected;
166    selectArray.forEach((i) => {
167      this.showItems.push(i);
168    });
169    // @ts-ignore
170    this.selectVInputEl.value = selectArray.filter(it => !this.ignoreValues.includes(it));
171  }
172
173  initDataItem(selectVDataItem: Array<string>): void {
174    selectVDataItem.forEach((item) => {
175      let selectVOption = document.createElement('lit-select-option');
176      if (this.showItems.indexOf(item) > -1 || this.all) {
177        selectVOption.setAttribute('selected', '');
178      }
179      selectVOption.className = 'option';
180      selectVOption.setAttribute('value', item);
181      selectVOption.textContent = item;
182      this.selectVOptions!.appendChild(selectVOption);
183    });
184  }
185
186  initElements(): void {
187    this.tabIndex = 0;
188    this.focused = false;
189    this.selectVInputEl = this.shadowRoot!.querySelector('#select-input') as HTMLInputElement;
190    this.selectVSearchInputEl = this.shadowRoot!.querySelector('#search-input') as HTMLInputElement;
191    this.selectVBody = this.shadowRoot!.querySelector('.body') as HTMLDivElement;
192    this.selectVOptions = this.shadowRoot!.querySelector('.body-opt') as HTMLDivElement;
193    this.selectVIconEl = this.shadowRoot!.querySelector('.icon'); // @ts-ignore
194    this.selectVInputEl?.addEventListener('keyup', (e) => {
195      if (e.code === 'Enter' || e.code === 'NumpadEnter') {// @ts-ignore
196        this.selectVInputEl.blur();
197      }
198    });// @ts-ignore
199    this.selectVInputEl!.oninput = (ev: InputEvent): void => {
200      // @ts-ignore
201      if (this.selectVInputEl!.value === '00') {
202        // @ts-ignore
203        this.selectVInputEl!.value = '0';
204        ev.preventDefault();
205      } // @ts-ignore
206      if (this.selectVInputEl!.value === '') {
207        this.shadowRoot?.querySelectorAll('lit-select-option').forEach((it) => {
208          it.removeAttribute('selected');
209          this.showItems = [];
210          this.currentvalueStr = '';
211        });
212      }
213    }; // @ts-ignore
214    this.selectVSearchInputEl!.onkeydown = (ev: KeyboardEvent): void => {
215      // @ts-ignore
216      if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') {
217        ev.preventDefault();
218      }
219    };
220    this.onclick = (ev: unknown): void => {
221      if (this.focused === false) {
222        this.focused = true;
223      } else {
224        this.focused = false;
225      }
226    }; // @ts-ignore
227    this.selectVSearchInputEl?.addEventListener('keyup', () => {
228      let options = [...this.shadowRoot!.querySelectorAll<LitSelectOption>('.option')];
229      options.filter((a: LitSelectOption) => {
230        // @ts-ignore
231        if (a.textContent!.indexOf(this.selectVSearchInputEl!.value) <= -1) {
232          a.style.display = 'none';
233        } else {
234          a.style.display = 'flex';
235        }
236      });
237    });
238    this.setEvent();
239  }
240
241  setEvent(): void {
242    this.onmouseout = this.onblur = (ev): void => {
243      this.focused = false;
244    }; // @ts-ignore
245    this.selectVInputEl.onfocus = (ev: unknown): void => {
246      if (this.hasAttribute('disabled')) {
247        return;
248      }
249    }; // @ts-ignore
250    this.selectVInputEl.onblur = (ev: unknown): void => {
251      if (this.hasAttribute('disabled')) {
252        return;
253      }
254    };
255  }
256
257  initHtml(): string {
258    return `
259        ${selectVHtmlStr}
260        <div class="root noSelect" tabindex="0" hidefocus="true">
261            <input id="select-input" placeholder="${this.placeholder}" tabindex="0" readonly="readonly">
262            <lit-icon class="icon" name='down' color="#c3c3c3"></lit-icon>
263        </div>
264        <div class="body">
265            <div class="body-select">
266             <input id="search-input" placeholder="Search">
267           </div>
268            <div class="body-opt">
269               <slot></slot>
270               <slot name="footer"></slot>
271            </div>
272        </div>
273        `;
274  }
275
276  connectedCallback(): void { }
277
278  initCustomOptions(): void {
279    let querySelector = this.shadowRoot?.querySelector(
280      `lit-select-option[value="${this.valueStr}"]`
281    ) as LitSelectOption;
282    this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => {
283      a.setAttribute('check', '');
284      a.addEventListener('onSelected', (e: unknown) => {
285        if (a.hasAttribute('selected')) {
286          let number = this.showItems.indexOf(a.textContent!);
287          if (number > -1) {
288            this.showItems!.splice(number, 1); // @ts-ignore
289            this.selectVInputEl!.value = this.showItems.filter(it => !this.ignoreValues.includes(it));
290          }
291          this.all = false;
292          querySelector.removeAttribute('selected');
293          a.removeAttribute('selected');
294          return;
295        } else {
296          let index = this.itemValue.indexOf(a.textContent!);
297          let value = this.showItems.indexOf(a.textContent!);
298          if (index > -1 && value === -1) {
299            this.showItems.push(a.textContent!); // @ts-ignore
300            this.selectVInputEl!.value = this.showItems.filter(it => !this.ignoreValues.includes(it));
301          }
302          if (this.showItems.length >= this.itemValue.length) {
303            querySelector.setAttribute('selected', '');
304            this.all = true;
305          } else {
306            querySelector.removeAttribute('selected');
307            this.all = false;
308          }
309          a.setAttribute('selected', '');
310        }
311      });
312    });
313    this.selectAll(querySelector);
314  }
315
316  initSingleCustomOptions(): void {
317    let selectedOption = this.shadowRoot?.querySelector(
318      `lit-select-option[value="${this.currentvalueStr}"]`
319    ) as LitSelectOption | null;
320    if (selectedOption) {
321      selectedOption.setAttribute('selected', '');
322    }
323    this.shadowRoot?.querySelectorAll('lit-select-option').forEach((option) => {
324      option.addEventListener('onSelected', () => {
325        this.shadowRoot?.querySelectorAll('lit-select-option').forEach((o) => {
326          o.removeAttribute('selected');
327        });
328        option.setAttribute('selected', '');
329        this.dispatchEvent(new CustomEvent('valueChange', {
330          detail: { value: option.textContent! },
331          bubbles: true,
332          composed: true
333        }));
334        //@ts-ignore
335        this.selectVInputEl!.value = option.textContent!;
336        this.currentvalueStr = option.textContent!;
337      });
338    });
339  }
340
341  initOptions(): void {
342    this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => {
343      a.setAttribute('check', '');
344      a.addEventListener('onSelected', (e: unknown) => {
345        if (a.hasAttribute('selected')) {
346          let number = this.showItems.indexOf(a.textContent!);
347          if (number > -1) {
348            this.showItems.splice(number, 1);
349          }
350          a.removeAttribute('selected');
351        } else {
352          let index = this.itemValue.indexOf(a.textContent!);
353          if (index > -1) {
354            this.showItems.push(a.textContent!);
355          }
356          a.setAttribute('selected', '');
357        } // @ts-ignore
358        let items = this.selectVInputEl!.value.split(',');
359        this.customItem = [];
360        items.forEach((item: string) => {
361          if (item.trim() !== '') {
362            let indexItem = this.itemValue.indexOf(item.trim());
363            if (indexItem === -1) {
364              this.customItem.push(item.trim());
365            }
366          }
367        });
368        if (this.customItem.length > 0) {
369          // @ts-ignore
370          this.selectVInputEl.value = this.customItem.concat(this.showItems)
371            .filter(it => !this.ignoreValues.includes(it));
372        } else {
373          // @ts-ignore
374          this.selectVInputEl.value = this.showItems.filter(it => !this.ignoreValues.includes(it));
375        }
376      });
377    });
378  }
379
380  selectAll(querySelector: LitSelectOption): void {
381    querySelector?.addEventListener('click', (ev) => {
382      if (querySelector.hasAttribute('selected')) {
383        this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => {
384          a.setAttribute('selected', '');
385          this.all = true;
386        });
387        this.itemValue.forEach((i) => {
388          this.showItems.push(i);
389        }); // @ts-ignore
390        this.selectVInputEl.value = this.itemValue.filter(it => !this.ignoreValues.includes(it));;
391      } else {
392        this.shadowRoot?.querySelectorAll('lit-select-option').forEach((i) => {
393          i.removeAttribute('selected');
394          this.all = false;
395        });
396        this.showItems = []; // @ts-ignore
397        this.selectVInputEl.value = '';
398      }
399    });
400  }
401
402  clearVal(): void {// @ts-ignore
403    this.selectVInputEl!.value = '';
404    this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => {
405        if (a.hasAttribute('selected')) {
406          a.removeAttribute('selected');
407        }
408    });
409    this.dataSource([], '');
410  }
411
412  attributeChangedCallback(name: unknown, oldValue: unknown, newValue: unknown): void { }
413}
414