1class JSHeaderSearch 2{ 3 cache = {}; 4 params = {}; 5 6 processing = false; 7 pending = false; 8 9 form = null; 10 dropContainer = null; 11 resultContainer = null; 12 input = null; 13 loader = null; 14 empty = null; 15 reset = null; 16 searchQueryRemoveButtonList = null; 17 debounceTimer = null; 18 19 constructor(arParams) { 20 let self = this; 21 22 self.params = { 23 'AJAX_PAGE': arParams.AJAX_PAGE, 24 'SEARCH_HISTORY_AJAX': arParams.SEARCH_HISTORY_AJAX, 25 'FORM_ID': arParams.FORM_ID, 26 'DROP_CONTAINER_ID': arParams.DROP_CONTAINER_ID, 27 'RESULT_CONTAINER_ID': arParams.RESULT_CONTAINER_ID, 28 'INPUT_ID': arParams.INPUT_ID, 29 'LOADER_ID': arParams.LOADER_ID, 30 'EMPTY_ID': arParams.EMPTY_ID, 31 'RESET_ID': arParams.RESET_ID, 32 'SEARCH_ALL_ID': arParams.SEARCH_ALL_ID, 33 'SEARCH_QUERY_REMOVE_CLASS': arParams.SEARCH_QUERY_REMOVE_CLASS, 34 'MIN_QUERY_LEN': parseInt(arParams.MIN_QUERY_LEN) ?? 3, 35 }; 36 37 BX.ready(function() { 38 self.init(); 39 }); 40 } 41 42 init() { 43 this.form = document.getElementById(this.params.FORM_ID); 44 this.dropContainer = document.getElementById(this.params.DROP_CONTAINER_ID); 45 this.resultContainer = document.getElementById(this.params.RESULT_CONTAINER_ID); 46 this.input = document.getElementById(this.params.INPUT_ID); 47 this.loader = document.getElementById(this.params.LOADER_ID); 48 this.empty = document.getElementById(this.params.EMPTY_ID); 49 this.reset = document.getElementById(this.params.RESET_ID); 50 this.searchQueryRemoveButtonList = document.querySelectorAll('.' + this.params.SEARCH_QUERY_REMOVE_CLASS); 51 52 this.initHandlers(); 53 } 54 55 initHandlers() { 56 let self = this; 57 58 self.form.addEventListener('submit', function(event) { 59 event.preventDefault(); 60 self.loaderStart(); 61 self.addQueryToSearchHistory(); 62 }) 63 64 self.input.addEventListener('input', function() { 65 let inputValueLength = self.input.value.length; 66 let minInputValueLength = self.params.MIN_QUERY_LEN; 67 68 if (inputValueLength >= minInputValueLength) { 69 self.onChange(); 70 } 71 else if (inputValueLength < minInputValueLength) { 72 self.clearResult(); 73 } 74 }); 75 76 self.reset.addEventListener('click', function() { 77 self.input.value = ''; 78 self.clearResult(); 79 }); 80 81 self.searchQueryRemoveButtonList.forEach(function(button){ 82 button.addEventListener('click', function(event) { 83 let target = event.target; 84 85 let queryBlock = target.closest('.header-search__item'); 86 let queryListBlock = target.closest('.header-search__list'); 87 let historyBlock = target.closest('.header-search__history'); 88 89 let query = target.getAttribute('data-value'); 90 if (query) { 91 self.deleteQueryFromSearchHistory(query); 92 queryBlock.remove(); 93 } 94 95 if (historyBlock && queryListBlock.childElementCount < 1) { 96 historyBlock.remove(); 97 } 98 }); 99 }); 100 } 101 102 initAjaxHandlers() { 103 let self = this; 104 105 let searchAllButton = document.getElementById('search-all'); 106 if (searchAllButton) { 107 searchAllButton.addEventListener('click', function(event) { 108 event.preventDefault(); 109 self.loaderStart(); 110 self.addQueryToSearchHistory(); 111 }) 112 } 113 } 114 115 addQueryToSearchHistory() { 116 let self = this; 117 118 BX.ajax({ 119 url: self.params.SEARCH_HISTORY_AJAX, 120 data: { 121 'type': 'add', 122 'query': self.input.value, 123 }, 124 method: 'POST', 125 dataType: 'json', 126 onsuccess: function(response){ 127 if (response && response.status !== 'success') { 128 console.log('Add query to search history error!'); 129 } 130 self.redirectToSearchPage(); 131 }, 132 onfailure: function(){ 133 console.log('Request error!'); 134 } 135 }); 136 } 137 138 deleteQueryFromSearchHistory(query) { 139 let self = this; 140 141 BX.ajax({ 142 url: self.params.SEARCH_HISTORY_AJAX, 143 data: { 144 'type': 'delete', 145 'query': query, 146 }, 147 method: 'POST', 148 dataType: 'json', 149 onsuccess: function(response){ 150 if (response && response.status !== 'success') { 151 console.log('Delete query to search history error!'); 152 } 153 }, 154 onfailure: function(){ 155 console.log('Request error!'); 156 } 157 }); 158 } 159 160 redirectToSearchPage() { 161 location.href = '/search/?q=' + this.input.value.trim().replace(' ', '%20'); 162 } 163 164 onChange() { 165 let self = this; 166 167 if (self.processing) { 168 self.pending = true; 169 return; 170 } 171 172 clearTimeout(self.debounceTimer); 173 174 self.debounceTimer = setTimeout(() => { 175 self.loaderStart(); 176 177 let query = self.input.value.trim();
178 if (self.cache[query] != null) { 179 self.showResult(self.cache[query]); 180 self.loaderEnd(); 181 } else { 182 BX.ajax.post( 183 self.params.AJAX_PAGE, 184 { 185 'ajax_call': 'y', 186 'INPUT_ID': self.params.INPUT_ID, 187 'l': self.params.MIN_QUERY_LEN, 188 'q': query, 189 }, 190 function(response) { 191 self.cache[query] = response.trim(); 192 self.showResult(self.cache[query]); 193 self.loaderEnd(); 194 195 if (self.pending) { 196 self.pending = false; 197 self.onChange(); 198 } 199 200 self.initAjaxHandlers(); 201 }, 202 ); 203 } 204 }, 1000); 205 } 206 207 loaderStart() { 208 this.processing = true; 209 this.loader.classList.remove('hidden'); 210 this.empty.classList.add('hidden'); 211 } 212 213 loaderEnd() { 214 this.processing = false; 215 this.loader.classList.add('hidden'); 216 } 217 218 showResult(html = '') { 219 this.hideAdditionalBlock(); 220 221 this.resultContainer.innerHTML = html; 222 223 if (html.length > 0) { 224 this.empty.classList.add('hidden'); 225 } else { 226 this.empty.classList.remove('hidden'); 227 } 228 } 229 230 clearResult() { 231 this.showAdditionalBlocks(); 232 this.resultContainer.innerHTML = ''; 233 } 234 235 showAdditionalBlocks() { 236 document.querySelectorAll('.additional-block').forEach(function(block) { 237 block.classList.remove('hidden'); 238 }) 239 } 240 241 hideAdditionalBlock() { 242 document.querySelectorAll('.additional-block').forEach(function(block) { 243 block.classList.add('hidden'); 244 }) 245 } 246}
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.