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: 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.selectVInputEl!.oninput = (ev: InputEvent) => { 162 // @ts-ignore 163 if (this.selectVInputEl!.value === '00') { 164 this.selectVInputEl!.value = '0'; 165 ev.preventDefault(); 166 } 167 if (this.selectVInputEl!.value === '') { 168 this.shadowRoot?.querySelectorAll('lit-select-option').forEach((it) => { 169 it.removeAttribute('selected'); 170 this.showItems = []; 171 }); 172 } 173 }; 174 this.selectVSearchInputEl!.onkeydown = (ev: KeyboardEvent) => { 175 // @ts-ignore 176 if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') { 177 ev.preventDefault(); 178 } 179 }; 180 this.onclick = (ev: any) => { 181 if (this.focused === false) { 182 this.focused = true; 183 } else { 184 this.focused = false; 185 } 186 }; 187 this.selectVSearchInputEl?.addEventListener('keyup', () => { 188 let options = [...this.shadowRoot!.querySelectorAll<LitSelectOption>('.option')]; 189 options.filter((a: LitSelectOption) => { 190 if (a.textContent!.indexOf(this.selectVSearchInputEl!.value) <= -1) { 191 a.style.display = 'none'; 192 } else { 193 a.style.display = 'flex'; 194 } 195 }); 196 }); 197 this.setEvent(); 198 } 199 200 setEvent():void{ 201 this.onmouseout = this.onblur = (ev) => { 202 this.focused = false; 203 }; 204 this.selectVInputEl.onfocus = (ev: any) => { 205 if (this.hasAttribute('disabled')) return; 206 }; 207 this.selectVInputEl.onblur = (ev: any) => { 208 if (this.hasAttribute('disabled')) return; 209 }; 210 } 211 212 initHtml() { 213 return ` 214 ${selectVHtmlStr} 215 <div class="root noSelect" tabindex="0" hidefocus="true"> 216 <input id="select-input" placeholder="${this.placeholder}" tabindex="0" readonly="readonly"> 217 <lit-icon class="icon" name='down' color="#c3c3c3"></lit-icon> 218 </div> 219 <div class="body"> 220 <div class="body-select"> 221 <input id="search-input" placeholder="Search"> 222 </div> 223 <div class="body-opt"> 224 <slot></slot> 225 <slot name="footer"></slot> 226 </div> 227 </div> 228 `; 229 } 230 231 connectedCallback() {} 232 233 initCustomOptions() { 234 let querySelector = this.shadowRoot?.querySelector( 235 `lit-select-option[value="${this.valueStr}"]` 236 ) as LitSelectOption; 237 this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => { 238 a.setAttribute('check', ''); 239 a.addEventListener('onSelected', (e: any) => { 240 if (a.hasAttribute('selected')) { 241 let number = this.showItems.indexOf(a.textContent!); 242 if (number > -1) { 243 this.showItems!.splice(number, 1); 244 this.selectVInputEl!.value = this.showItems; 245 } 246 this.all = false; 247 querySelector.removeAttribute('selected'); 248 a.removeAttribute('selected'); 249 return; 250 } else { 251 let index = this.itemValue.indexOf(a.textContent!); 252 let value = this.showItems.indexOf(a.textContent!); 253 if (index > -1 && value == -1) { 254 this.showItems.push(a.textContent!); 255 this.selectVInputEl!.value = this.showItems; 256 } 257 if (this.showItems.length >= this.itemValue.length) { 258 querySelector.setAttribute('selected', ''); 259 this.all = true; 260 } else { 261 querySelector.removeAttribute('selected'); 262 this.all = false; 263 } 264 a.setAttribute('selected', ''); 265 } 266 }); 267 }); 268 this.selectAll(querySelector); 269 } 270 271 initOptions() { 272 this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => { 273 a.setAttribute('check', ''); 274 a.addEventListener('onSelected', (e: any) => { 275 if (a.hasAttribute('selected')) { 276 let number = this.showItems.indexOf(a.textContent!); 277 if (number > -1) { 278 this.showItems.splice(number, 1); 279 } 280 a.removeAttribute('selected'); 281 } else { 282 let index = this.itemValue.indexOf(a.textContent!); 283 if (index > -1) { 284 this.showItems.push(a.textContent!); 285 } 286 a.setAttribute('selected', ''); 287 } 288 let items = this.selectVInputEl!.value.split(','); 289 this.customItem = []; 290 items.forEach((item: string) => { 291 if (item.trim() != '') { 292 let indexItem = this.itemValue.indexOf(item.trim()); 293 if (indexItem == -1) { 294 this.customItem.push(item.trim()); 295 } 296 } 297 }); 298 if (this.customItem.length > 0) { 299 this.selectVInputEl.value = this.customItem.concat(this.showItems); 300 } else { 301 this.selectVInputEl.value = this.showItems; 302 } 303 }); 304 }); 305 } 306 307 selectAll(querySelector: LitSelectOption) { 308 querySelector?.addEventListener('click', (ev) => { 309 if (querySelector.hasAttribute('selected')) { 310 this.shadowRoot?.querySelectorAll('lit-select-option').forEach((a) => { 311 a.setAttribute('selected', ''); 312 this.all = true; 313 }); 314 this.itemValue.forEach((i) => { 315 this.showItems.push(i); 316 }); 317 this.selectVInputEl.value = this.itemValue; 318 } else { 319 this.shadowRoot?.querySelectorAll('lit-select-option').forEach((i) => { 320 i.removeAttribute('selected'); 321 this.all = false; 322 }); 323 this.showItems = []; 324 this.selectVInputEl.value = ''; 325 } 326 }); 327 } 328 329 attributeChangedCallback(name: any, oldValue: any, newValue: any) {} 330} 331