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