PageSourceSearch

https://www.smoobu.com/wp-content/themes/smoobu/vendor/fooz/ajax-search/assets/js/ajax-search.js?ver=2.0.32

js smoobu.com collected 2026-10-09 22:48:01 UTC 7,574 bytes, 341 lines download raw bytes

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.