• 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.js';
17import { LitSelectOption } from './LitSelectOption.js';
18import { selectHtmlStr } from './LitSelectHtml.js';
19
20@element('lit-select-v')
21export class LitSelectV extends BaseElement {
22  showItems: Array<string> = [];
23  itemValue: Array<string> = [];
24  customItem: Array<string> = [];
25  private focused: any;
26  private selectVInputEl: any;
27  private selectVSearchInputEl: any;
28  private selectVIconEl: any;
29  private selectVOptions: HTMLDivElement | undefined;
30  private selectVBody: HTMLDivElement | undefined;
31
32  private valueStr: string = '';
33
34  static get observedAttributes() {
35    return ['value', 'default-value', 'placeholder', 'disabled', 'show-search', 'border', 'mode'];
36  }
37
38  get value() {
39    return this.selectVInputEl!.value || this.defaultValue;
40  }
41
42  get rounded() {
43    return this.hasAttribute('rounded');
44  }
45
46  set rounded(selectVRounded: boolean) {
47    if (selectVRounded) {
48      this.setAttribute('rounded', '');
49    } else {
50      this.removeAttribute('rounded');
51    }
52  }
53
54  get placement(): string {
55    return this.getAttribute('placement') || '';
56  }
57
58  set placement(selectVPlacement: string) {
59    if (selectVPlacement) {
60      this.setAttribute('placement', selectVPlacement);
61    } else {
62      this.removeAttribute('placement');
63    }
64  }
65
66  get border() {
67    return this.getAttribute('border') || 'true';
68  }
69
70  set border(selectVBorder) {
71    if (selectVBorder) {
72      this.setAttribute('border', 'true');
73    } else {
74      this.setAttribute('border', 'false');
75    }
76  }
77
78  get defaultPlaceholder() {
79    return this.getAttribute('placeholder') || '';
80  }
81
82  get defaultValue() {
83    return this.getAttribute('default-value') || '';
84  }
85
86  set defaultValue(selectVDefaultValue) {
87    this.setAttribute('default-value', selectVDefaultValue);
88  }
89
90  get placeholder() {
91    return this.getAttribute('placeholder') || this.defaultPlaceholder;
92  }
93
94  set placeholder(selectVPlaceholder) {
95    this.setAttribute('placeholder', selectVPlaceholder);
96  }
97
98  set all(isAll: boolean) {
99    if (isAll) {
100      this.setAttribute('is-all', '');
101    } else {
102      this.removeAttribute('is-all');
103    }
104  }
105
106  get all() {
107    return this.hasAttribute('is-all');
108  }
109
110  dataSource(selectVData: Array<string>, valueStr: string) {
111    this.selectVOptions!.innerHTML = '';
112    if (selectVData.length > 0) {
113      this.selectVBody!.style.display = 'block';
114      this.valueStr = valueStr;
115      this.itemValue = selectVData;
116      if (valueStr != '') {
117        let option = document.createElement('lit-select-option');
118        if (this.all) {
119          option.setAttribute('selected', '');
120          this.showItems = selectVData;
121        }
122        option.setAttribute('value', valueStr);
123        option.textContent = valueStr;
124        this.selectVOptions!.appendChild(option);
125        this.initDataItem(selectVData);
126        this.initCustomOptions();
127      } else {
128        this.initDataItem(selectVData);
129        this.initOptions();
130      }
131    } else {
132      this.selectVBody!.style.display = 'none';
133    }
134    if (this.title == 'Event List') {
135      let inputElement = this.shadowRoot?.querySelector('input') as HTMLInputElement;
136      inputElement.readOnly = false;
137    }
138  }
139
140  initDataItem(selectVDataItem: Array<string>) {
141    selectVDataItem.forEach((item) => {
142      let selectVOption = document.createElement('lit-select-option');
143      if (this.showItems.indexOf(item) > -1 || this.all) {
144        selectVOption.setAttribute('selected', '');
145      }
146      selectVOption.className = 'option';
147      selectVOption.setAttribute('value', item);
148      selectVOption.textContent = item;
149      this.selectVOptions!.appendChild(selectVOption);
150    });
151  }
152
153  initElements(): void {
154    this.tabIndex = 0;
155    this.focused = false;
156    this.selectVInputEl = this.shadowRoot!.querySelector('#select-input') as HTMLInputElement;
157    this.selectVSearchInputEl = this.shadowRoot!.querySelector('#search-input') as HTMLInputElement;
158    this.selectVBody = this.shadowRoot!.querySelector('.body') as HTMLDivElement;
159    this.selectVOptions = this.shadowRoot!.querySelector('.body-opt') as HTMLDivElement;
160    this.selectVIconEl = this.shadowRoot!.querySelector('.icon');
161    this.onclick = (ev: any) => {
162      if (this.focused === false) {
163        this.focused = true;
164      } else {
165        this.focused = false;
166      }
167    };
168    this.selectVSearchInputEl?.addEventListener('keyup', () => {
169      let options = [...this.shadowRoot!.querySelectorAll<LitSelectOption>('.option')];
170      options.filter((a: LitSelectOption) => {
171        if (a.textContent!.indexOf(this.selectVSearchInputEl!.value) <= -1) {
172          a.style.display = 'none';
173        } else {
174          a.style.display = 'flex';
175        }
176      });
177    });
178
179    this.onmouseout = this.onblur = (ev) => {
180      this.focused = false;
181    };
182    this.selectVInputEl.onfocus = (ev: any) => {
183      if (this.hasAttribute('disabled')) return;
184    };
185    this.selectVInputEl.onblur = (ev: any) => {
186      if (this.hasAttribute('disabled')) return;
187    };
188  }
189
190  initHtml() {
191    return `
192        <style>
193        ${selectHtmlStr()}
194        .body{
195            max-height: 286px;
196            box-shadow: 0 5px 15px 0px #00000033;
197            border-radius: 10px;
198        }
199        input{
200            width: 100%;
201        }
202        #search-input {
203          outline: none;
204          border: none;
205        }
206        .body-select {
207           margin-top: 3px;
208           background-color: var(--dark-background4,#fff);
209           width: 100%;
210           border-bottom: none;
211        }
212        .body-opt{
213            width: 100%;
214            max-height: 256px;
215            border-top: none;
216            overflow: auto;
217            border-bottom-left-radius: 10px;
218            border-bottom-right-radius: 10px;
219            background-color: var(--dark-background4,#fff);
220        }
221        .loading{
222            display: none;
223        }
224        input::-webkit-input-placeholder {
225                color: var(--dark-color,#aab2bd);
226        }
227        #search-input{
228           margin-left: 15px;
229        }
230        .icon{
231            display: flex;
232        }
233        /*Define the height, width and background of the scroll bar*/
234        ::-webkit-scrollbar
235        {
236          width: 8px;
237          border-radius: 10px;
238          background-color: var(--dark-background3,#FFFFFF);
239        }
240
241        /*define slider*/
242        ::-webkit-scrollbar-thumb
243        {
244          border-radius: 6px;
245          background-color: var(--dark-background7,rgba(0,0,0,0.1));
246        }
247
248        </style>
249        <div class="root noSelect" tabindex="0" hidefocus="true">
250            <input id="select-input" placeholder="${this.placeholder}" tabindex="0" readonly="readonly">
251            <lit-icon class="icon" name='down' color="#c3c3c3"></lit-icon>
252        </div>
253        <div class="body">
254            <div class="body-select">
255             <input id="search-input" placeholder="Search">
256           </div>
257            <div class="body-opt">
258               <slot></slot>
259               <slot name="footer"></slot>
260            </div>
261        </div>
262        `;
263  }
264
265  connectedCallback() {}
266
267  initCustomOptions() {
268    let querySelector = this.shadowRoot?.querySelector(
269      `lit-select-option[value="${this.valueStr}"]`
270    ) as LitSelectOption;
271    this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => {
272      a.setAttribute('check', '');
273      a.addEventListener('onSelected', (e: any) => {
274        if (a.hasAttribute('selected')) {
275          let number = this.showItems.indexOf(a.textContent!);
276          if (number > -1) {
277            this.showItems!.splice(number, 1);
278            this.selectVInputEl!.value = this.showItems;
279          }
280          this.all = false;
281          querySelector.removeAttribute('selected');
282          a.removeAttribute('selected');
283          return;
284        } else {
285          let index = this.itemValue.indexOf(a.textContent!);
286          let value = this.showItems.indexOf(a.textContent!);
287          if (index > -1 && value == -1) {
288            this.showItems.push(a.textContent!);
289            this.selectVInputEl!.value = this.showItems;
290          }
291          if (this.showItems.length >= this.itemValue.length) {
292            querySelector.setAttribute('selected', '');
293            this.all = true;
294          } else {
295            querySelector.removeAttribute('selected');
296            this.all = false;
297          }
298          a.setAttribute('selected', '');
299        }
300      });
301    });
302    this.selectAll(querySelector);
303  }
304
305  initOptions() {
306    this.selectVOptions!.addEventListener('click', (ev) => {
307      let items = this.selectVInputEl!.value.split(',');
308      this.customItem = [];
309      items.forEach((item: string) => {
310        if (item.trim() != '') {
311          let indexItem = this.itemValue.indexOf(item.trim());
312          if (indexItem == -1) {
313            this.customItem.push(item.trim());
314          }
315        }
316      });
317      if (this.customItem.length > 0) {
318        this.selectVInputEl.value = this.customItem.concat(this.showItems);
319      } else {
320        this.selectVInputEl.value = this.showItems;
321      }
322    });
323    this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => {
324      a.setAttribute('check', '');
325      a.addEventListener('onSelected', (e: any) => {
326        if (a.hasAttribute('selected')) {
327          let number = this.showItems.indexOf(a.textContent!);
328          if (number > -1) {
329            this.showItems.splice(number, 1);
330          }
331          a.removeAttribute('selected');
332          return;
333        } else {
334          let index = this.itemValue.indexOf(a.textContent!);
335          if (index > -1) {
336            this.showItems.push(a.textContent!);
337          }
338          a.setAttribute('selected', '');
339        }
340      });
341    });
342  }
343
344  selectAll(querySelector: LitSelectOption) {
345    querySelector?.addEventListener('click', (ev) => {
346      if (querySelector.hasAttribute('selected')) {
347        this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => {
348          a.setAttribute('selected', '');
349          this.all = true;
350        });
351        this.itemValue.forEach((i) => {
352          this.showItems.push(i);
353        });
354        this.selectVInputEl.value = this.itemValue;
355      } else {
356        this.shadowRoot?.querySelectorAll('lit-select-option').forEach((i) => {
357          i.removeAttribute('selected');
358          this.all = false;
359        });
360        this.showItems = [];
361        this.selectVInputEl.value = '';
362      }
363    });
364  }
365
366  attributeChangedCallback(name: any, oldValue: any, newValue: any) {}
367}
368