1/** 2 * Required Scripts for page search 3 * 4 * @return {void} 5 */ 6const ajaxSearch = () => { 7 8 const searchInstances = document.querySelectorAll('.js-search'); 9 10 if (searchInstances.length > 0) { 11 12 searchInstances.forEach((searchInstance) => { 13 14 visibleTrigger(searchInstance); 15 getText(searchInstance); 16 navigation(searchInstance); 17 clearInputEvent(searchInstance); 18 19 }); 20 21 } 22 23} 24 25/** 26 * Clear Search 27 * 28 * @param {node} searchInstance 29 * 30 * @return {void} 31 */ 32const clearSearch = (searchInstance) => { 33 34 const searchInput = searchInstance.querySelector('.js-search-input'); 35 const searchResults = searchInstance.querySelector('.js-search-results') 36 searchInput.value = ''; 37 searchInstance.classList.remove('c-ajax-search--on'); 38 selectNav('all', searchInstance); 39 searchFilter('all', searchInstance); 40 const nothing = searchResults.querySelector('.js-search-list-item[data-id="nothing"]'); 41 42 if (nothing) { 43 44 searchResults.innerHTML = ''; 45 46 } 47 48} 49 50/** 51 * Clear input 52 * 53 * @param {node} searchInstance 54 * 55 * @return {void} 56 */ 57const clearInputEvent = (searchInstance) => { 58 59 const clearButton = searchInstance.querySelector('.js-search-clear'); 60 61 clearButton.addEventListener('click', () => { 62 63 clearSearch(searchInstance); 64 65 }); 66 67} 68 69/** 70 * Search Filter 71 * 72 * @param {node} searchInstance 73 * 74 * @return {void} 75 */ 76const visibleTrigger = (searchInstance) => { 77 78 document.addEventListener('click', (event) => { 79 80 const isClickInside = searchInstance.contains(event.target) 81 82 if (!isClickInside) { 83 84 searchInstance.classList.remove('c-ajax-search--on'); 85 86 } 87 88 }) 89 90} 91 92/** 93 * Tabs Navigation 94 * 95 * @param {node} searchInstance 96 * 97 * @return {void} 98 */ 99const navigation = (searchInstance) => { 100 101 const triggers = searchInstance.querySelectorAll('.js-search-nav-link'); 102 let tabId = ''; 103 104 if (triggers.length > 0) { 105 106 triggers.forEach((trigger) => { 107 108 trigger.addEventListener('click', (e) => { 109 110 if (trigger.classList.contains('c-form-nav__item-button--active') === false || null) { 111 112 tabId = trigger.dataset.id; 113 114 selectNav(tabId, searchInstance); 115 searchFilter(tabId, searchInstance); 116 117 } 118 e.preventDefault(); 119 120 }) 121 122 }) 123 124 } 125 126} 127 128/** 129 * Select naviagtion tab 130 * 131 * @param {string} id 132 * @param {node} searchInstance 133 * 134 * @return {void} 135 */ 136const selectNav = (id, searchInstance) => { 137 138 const tabs = searchInstance.querySelectorAll('.js-search-nav-link'); 139 const activeTab = searchInstance.querySelector(`.js-search-nav-link[data-id="${id}"]`);
140 tabs.forEach((t) => t.classList.remove('c-form-nav__item-button--active')); 141 activeTab.classList.add('c-form-nav__item-button--active'); 142 143 const form = searchInstance.querySelector('form'); 144 if (form) { 145 if (id !== 'all') { 146 let hiddenInput = form.querySelector('input[type=hidden]'); 147 if (hiddenInput) { 148 hiddenInput.value = id; 149 } else { 150 hiddenInput = document.createElement('input'); 151 hiddenInput.name = 'source'; 152 hiddenInput.type = 'hidden'; 153 hiddenInput.value = id; 154 form.appendChild(hiddenInput); 155 } 156 }else{ 157 const hiddenInput = form.querySelector('input[type=hidden]'); 158 if (hiddenInput) { 159 hiddenInput.remove(); 160 } 161 } 162 } 163} 164 165/** 166 * Search Filter 167 * 168 * @param {string} id 169 * @param {node} searchInstance 170 * 171 * @return {void} 172 */ 173const searchFilter = (id, searchInstance) => { 174 175 const searchResults = searchInstance.querySelector('.js-search-results'); 176 const listItemsAll = searchResults.querySelectorAll('.js-search-list-item'); 177 const listItems = searchResults.querySelectorAll(`.js-search-list-item[data-id="${id}"]`); 178 if (listItemsAll.length > 0) { 179 180 if (id === 'all') { 181 182 listItemsAll.forEach((listItem) => listItem.classList.remove('c-results__item--off')); 183 184 } else { 185 186 listItemsAll.forEach((listItem) => listItem.classList.add('c-results__item--off')); 187 188 if (listItems.length > 0) { 189 190 listItems.forEach((listItem) => listItem.classList.remove('c-results__item--off')); 191 192 } 193 194 } 195 196 } 197 198} 199 200/** 201 * Get text 202 * 203 * @param {node} searchInstance 204 * 205 * @return {void} 206 */ 207const getText = (searchInstance) => { 208 209 const searchInput = searchInstance.querySelector('.js-search-input'); 210 211 let resultsTimeOut = null; 212 let searchQuery = ''; 213 214 const tabId = getPreTabId(searchInstance); 215 216 if (searchInput) { 217 218 searchInput.addEventListener('focus', (e) => { 219 220 if (e.target.value.length > 2) { 221 222 searchInstance.classList.add('c-ajax-search--on'); 223 224 } 225 226 }); 227 228 searchInput.addEventListener('input', (e) => { 229 230 clearTimeout(resultsTimeOut); 231 searchInstance.classList.add('c-ajax-search--on'); 232 searchQuery = e.target.value.replace(/(<([^>]+)>)/ig, ''); 233 234 if (searchQuery.length > 2) { 235 236 resultsTimeOut = setTimeout(() => { 237 238 getResults(searchInstance, searchQuery); 239 searchInstance.classList.add('c-ajax-search--on'); 240 241 }, 300); 242 243 } else { 244 245 searchInstance.classList.remove('c-ajax-search--on'); 246 selectNav(tabId, searchInstance); 247 searchFilter(tabId, searchInstance); 248 249 } 250 251 }); 252 253 } 254 255} 256 257/** 258 * Get Results 259 * 260 * @param {node} searchInstance 261 * @param {string} searchQuery 262 * 263 * @return {void} 264 */ 265const getResults = (searchInstance, searchQuery) => { 266 267 // Disable for global WP variables 268 // eslint-disable-next-line no-undef 269 const instanceVars = fz_ajaxsearch_phpvars; 270 271 const tabId = getPreTabId(searchInstance); 272 273 const searchInput = searchInstance.querySelector('.js-search-input'); 274 const searchResults = searchInstance.querySelector('.js-search-results'); 275 276 searchInstance.classList.add('c-ajax-search--loading'); 277 278 fetch(instanceVars.ajaxUrl, { 279 method: 'POST', 280 headers: { 281 'Content-Type': 'application/x-www-form-urlencoded', 282 }, 283 body: new URLSearchParams({ 284 action: 'get_ajax_search_results', 285 bn: instanceVars.security, 286 s: searchQuery, 287 }), 288 }).then((response) => { 289 290 return response.json(); 291 292 }).then((response) => { 293 294 if (searchInput.value === response.data.s) { 295 296 if (response.data.results !== '') { 297 298 searchResults.innerHTML = `<ul class="c-results"> ${response.data.results} </ul>`; 299 300 searchFilter(tabId, searchInstance); 301 302 } 303 304 } 305 searchInstance.classList.remove('c-ajax-search--loading'); 306 307 }).catch(() => { 308 309 searchInstance.classList.remove('c-ajax-search--loading'); 310 311 }); 312 313} 314 315/** 316 * Get preselected tab id 317 * 318 * @param {node} searchInstance 319 * 320 * @return {string} 321 */ 322 323const getPreTabId = (searchInstance) => { 324 325 let tabId = 'all'; 326 if (searchInstance.dataset.tabId) { 327 328 tabId = searchInstance.dataset.tabId; 329 330 const tabIdExist = searchInstance.querySelector(`.js-search-nav-link[data-id="${tabId}"]`); 331 if (!tabIdExist) { 332 tabId = 'all'; 333 } 334 335 } 336 337 return tabId; 338 339} 340 341ajaxSearch()
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.