1class ItcCustomSelect { 2 static EL = 'itc-select'; 3 static EL_SHOW = 'itc-select_show'; 4 static EL_OPTION = 'itc-select__option'; 5 static EL_OPTION_SELECTED = 'itc-select__option_selected'; 6 static DATA = '[data-select]'; 7 static DATA_TOGGLE = '[data-select="toggle"]'; 8 9 static template(params) { 10 const { name, options, targetValue } = params; 11 const items = []; 12 let selectedIndex = -1; 13 let selectedValue = ''; 14 let selectedContent = 'ÐÑбеÑиÑе из ÑпиÑка'; 15 options.forEach((option, index) => { 16 let selectedClass = ''; 17 if (option[0] === targetValue) { 18 selectedClass = ` ${this.EL_OPTION_SELECTED}`; 19 selectedIndex = index; 20 selectedValue = option[0]; 21 selectedContent = option[1]; 22 } 23 items.push(`<li class="itc-select__option${selectedClass}" data-select="option" 24 data-value="${option[0]}" data-index="${index}">${option[1]}</li>`); 25 }); 26 return `<button type="button" class="itc-select__toggle" name="${name}" 27 value="${selectedValue}" data-select="toggle" data-index="${selectedIndex}"> 28 ${selectedContent}</button><div class="itc-select__dropdown"> 29 <ul class="itc-select__options">${items.join('')}</ul></div>`; 30 } 31 32 static hideOpenSelect() { 33 document.addEventListener('click', (e) => { 34 if (!e.target.closest(`.${this.EL}`)) { 35 const elsActive = document.querySelectorAll(`.${this.EL_SHOW}`); 36 elsActive.forEach((el) => { 37 el.classList.remove(this.EL_SHOW); 38 }); 39 } 40 }); 41 } 42 static create(target, params) { 43 this._el = typeof target === 'string' ? document.querySelector(target) : target; 44 if (this._el) { 45 return new this(target, params); 46 } 47 return null; 48 } 49 constructor(target, params) { 50 this._el = typeof target === 'string' ? document.querySelector(target) : target; 51 this._params = params || {}; 52 this._onClickFn = this._onClick.bind(this); 53 if (this._params.options) { 54 this._el.innerHTML = this.constructor.template(this._params); 55 this._el.classList.add(this.constructor.EL); 56 } 57 this._elToggle = this._el.querySelector(this.constructor.DATA_TOGGLE); 58 this._el.addEventListener('click', this._onClickFn); 59 } 60 61 _onClick(e) { 62 const { target } = e; 63 const type = target.closest(this.constructor.DATA).dataset.select; 64 if (type === 'toggle') { 65 this.toggle(); 66 } else if (type === 'option') { 67 this._changeValue(target); 68 } 69 } 70 71 _updateOption(el) { 72 const elOption = el.closest(`.${this.constructor.EL_OPTION}`); 73 const elOptionSel = this._el.querySelector(`.${this.constructor.EL_OPTION_SELECTED}`); 74 if (elOptionSel) { 75 elOptionSel.classList.remove(this.constructor.EL_OPTION_SELECTED); 76 } 77 elOption.classList.add(this.constructor.EL_OPTION_SELECTED); 78 this._elToggle.textContent = elOption.textContent; 79 this._elToggle.value = elOption.dataset.value; 80 this._elToggle.dataset.index = elOption.dataset.index; 81 this._el.dispatchEvent(new CustomEvent('itc.select.change')); 82 this._params.onSelected ? this._params.onSelected(this, elOption) : null; 83 return elOption.dataset.value; 84 } 85 86 _reset() { 87 const selected = this._el.querySelector(`.${this.constructor.EL_OPTION_SELECTED}`); 88 if (selected) { 89 selected.classList.remove(this.constructor.EL_OPTION_SELECTED); 90 } 91 this._elToggle.textContent = 'ÐÑбеÑиÑе из ÑпиÑка'; 92 this._elToggle.value = ''; 93 this._elToggle.dataset.index = '-1'; 94 this._el.dispatchEvent(new CustomEvent('itc.select.change')); 95 this._params.onSelected ? this._params.onSelected(this, null) : null; 96 return ''; 97 } 98 99 _changeValue(el) { 100 if (el.classList.contains(this.constructor.EL_OPTION_SELECTED)) { 101 return; 102 } 103 this._updateOption(el); 104 this.hide(); 105 } 106 107 show() { 108 document.querySelectorAll(this.constructor.EL_SHOW) 109 .forEach((el) => { 110 el.classList.remove(this.constructor.EL_SHOW); 111 }); 112 this._el.classList.add(`${this.constructor.EL_SHOW}`); 113 } 114 115 hide() { 116 this._el.classList.remove(this.constructor.EL_SHOW); 117 } 118 119 toggle() { 120 this._el.classList.contains(this.constructor.EL_SHOW) ? this.hide() : this.show(); 121 } 122 123 dispose() { 124 this._el.removeEventListener('click', this._onClickFn); 125 } 126 127 get value() { 128 return this._elToggle.value; 129 } 130 131 set value(value) { 132 let isExists = false;
133 this._el.querySelectorAll('.select__option') 134 .forEach((option) => { 135 if (option.dataset.value === value) { 136 isExists = true; 137 this._updateOption(option); 138 } 139 }); 140 if (!isExists) { 141 this._reset(); 142 } 143 } 144 145 get selectedIndex() { 146 return this._elToggle.dataset.index; 147 } 148 149 set selectedIndex(index) { 150 const option = this._el.querySelector(`.select__option[data-index="${index}"]`); 151 if (option) { 152 this._updateOption(option); 153 } 154 this._reset(); 155 } 156} 157 158ItcCustomSelect.hideOpenSelect();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.