1/** 2 * Select Field Reset Handler 3 * Fügt Reset-Button zu Select-Feldern hinzu 4 */ 5 6(function() { 7 'use strict'; 8 9 class SelectFieldHandler { 10 constructor(selectElement) { 11 this.select = selectElement; 12 this.originalValue = this.select.value; 13 this.init(); 14 } 15 16 init() { 17 // Wrapper erstellen 18 const wrapper = this.createWrapper(); 19 20 // Reset Button erstellen 21 const resetBtn = this.createResetButton(); 22 23 // Events registrieren 24 this.registerEvents(resetBtn); 25 26 // Form Submit Handler registrieren 27 this.registerFormSubmitHandler(); 28 29 // Initial Button & Select Status 30 this.updateSelectState(resetBtn); 31 } 32 33 registerFormSubmitHandler() { 34 // Finde das übergeordnete Form-Element 35 const form = this.select.closest('form'); 36 37 if (form && !form.dataset.tsmdSubmitHandlerAdded) { 38 // Markiere Form als bereits behandelt 39 form.dataset.tsmdSubmitHandlerAdded = 'true'; 40 41 // Vor Submit: Alle disabled Selects temporär enablen 42 form.addEventListener('submit', (e) => { 43 // Finde alle disabled Selects in diesem Form 44 const disabledSelects = form.querySelectorAll('select.tsmd_dropdown[disabled]'); 45 46 disabledSelects.forEach(select => { 47 // Temporär enablen für Submit 48 select.removeAttribute('disabled'); 49 select.style.pointerEvents = 'auto'; 50 51 // Markiere für später 52 select.dataset.wasDisabled = 'true'; 53 }); 54 }); 55 } 56 } 57 58 createWrapper() { 59 const wrapper = document.createElement('div'); 60 wrapper.className = 'tsmd-select-reset-wrapper'; 61 wrapper.style.cssText = ` 62 position: relative; 63 display: inline-block; 64 width: 100%; 65 `; 66 67 //if select has class part, use 50% width, otherwise 100% 68 if (this.select.classList.contains('part')) { 69 wrapper.style.width = '50%'; 70 this.select.style.width = '100%'; 71 } 72 73 // Select in Wrapper verschieben 74 this.select.parentNode.insertBefore(wrapper, this.select); 75 wrapper.appendChild(this.select); 76 77 return wrapper; 78 } 79 80 createResetButton() { 81 const btn = document.createElement('button'); 82 btn.type = 'button'; 83 btn.className = 'tsmd-select-reset-btn'; 84 btn.innerHTML = 'â'; 85 btn.setAttribute('aria-label', 'Auswahl zurücksetzen'); 86 btn.setAttribute('title', 'Zurücksetzen'); 87 88 btn.style.cssText = ` 89 position: absolute; 90 right: 8px; 91 top: 50%; 92 transform: translateY(-50%); 93 background: none; 94 border: none; 95 font-size: 20px; 96 color: #000; 97 cursor: pointer; 98 padding: 5px 8px; 99 display: none; 100 z-index: 10; 101 line-height: 1; 102 transition: color 0.2s ease; 103 `; 104 105 // Hover Effekt 106 btn.addEventListener('mouseenter', () => { 107 btn.style.color = '#333'; 108 }); 109 110 btn.addEventListener('mouseleave', () => { 111 if (this.select.value !== this.select.options[0].value) { 112 btn.style.color = '#999'; 113 } 114 }); 115 116 this.select.parentNode.appendChild(btn); 117 return btn; 118 } 119 120 updateSelectState(resetBtn) { 121 const firstOptionValue = this.select.options[0].value; 122 const isFirstSelected = this.select.value === firstOptionValue || this.select.selectedIndex === 0; 123 124 if (isFirstSelected) { 125 // Erster Wert ist ausgewählt â Select ist AKTIV 126 this.enableSelect(); 127 resetBtn.style.display = 'none'; 128 129 // Wenn Marke auf _ALL zurückgesetzt â Modell ebenfalls zurücksetzen 130 if (this.select.name === 'tsmd_filter_vendor_key' && this.select.value === '_ALL') { 131 const modelSelect = document.querySelector('select[name="tsmd_filter_model_key"]'); 132 //if (modelSelect && modelSelect.selectedIndex !== 0) { 133 modelSelect.selectedIndex = 0; 134 modelSelect.dispatchEvent(new Event('change', { bubbles: true })); 135 //} 136 } 137 } else { 138 // Anderer Wert ist ausgewählt â Select ist DISABLED 139 this.disableSelect(); 140 resetBtn.style.display = 'block'; 141 } 142 } 143 144 enableSelect() { 145 this.select.removeAttribute('disabled'); 146 this.select.style.pointerEvents = 'auto'; 147 this.select.style.opacity = '1'; 148 this.select.style.backgroundColor = '#E5E7E6'; 149 this.select.style.cursor = 'pointer'; 150 this.select.style.paddingRight = ''; 151 } 152 153 disableSelect() { 154 this.select.setAttribute('disabled', 'disabled'); 155 this.select.style.cssText += ` 156 pointer-events: none; 157 opacity: 0.7; 158 background-color: #f5f5f5;
159 cursor: not-allowed; 160 padding-right: 35px; 161 `; 162 } 163 164 registerEvents(resetBtn) { 165 // Reset Button Click 166 resetBtn.addEventListener('click', (e) => { 167 e.preventDefault(); 168 e.stopPropagation(); 169 this.reset(resetBtn); 170 }); 171 172 // Select Change - Update enabled/disabled Status 173 this.select.addEventListener('change', () => { 174 this.updateSelectState(resetBtn); 175 }); 176 177 // Prevent clicks wenn disabled 178 this.select.addEventListener('click', (e) => { 179 if (this.select.disabled) { 180 e.preventDefault(); 181 } 182 }); 183 } 184 185 reset(btn) { 186 this.select.selectedIndex = 0; 187 const event = new Event('change', { bubbles: true }); 188 this.select.dispatchEvent(event); 189 this.updateSelectState(btn); 190 } 191 } 192 193 // Initialisierung 194 function init() { 195 // Finde alle Select-Felder mit den gewünschten Klassen 196 const selectFields = [...document.querySelectorAll('select.tsmd_dropdown')] 197 .filter(el => !el.closest('.tsmd_sorting_option')); 198 199 selectFields.forEach(select => { 200 // Prüfe ob bereits initialisiert 201 if (!select.closest('.tsmd-select-reset-wrapper')) { 202 new SelectFieldHandler(select); 203 } 204 }); 205 } 206 207 // DOM Ready 208 if (document.readyState === 'loading') { 209 document.addEventListener('DOMContentLoaded', init); 210 } else { 211 init(); 212 } 213 214 // Re-initialize nach Dynamic Content 215 if (window.MutationObserver) { 216 const observer = new MutationObserver((mutations) => { 217 let shouldReinit = false; 218 219 mutations.forEach((mutation) => { 220 if (mutation.addedNodes.length) { 221 mutation.addedNodes.forEach((node) => { 222 if (node.nodeType === 1) { // Element 223 if (node.matches?.('select.tsmd_dropdown') || 224 node.querySelector?.('select.tsmd_dropdown')) { 225 shouldReinit = true; 226 } 227 } 228 }); 229 } 230 }); 231 232 if (shouldReinit) { 233 setTimeout(init, 100); 234 } 235 }); 236 237 observer.observe(document.body, { 238 childList: true, 239 subtree: true 240 }); 241 } 242 243})();
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.