PageSourceSearch

https://mtw.org/wp-content/themes/mtw/assets/js/website/missionary-search-module.js?ver=1.2

js mtw.org collected 2026-09-24 20:17:47 UTC 16,322 bytes, 406 lines download raw bytes

1const missionarySearchModule = (function () {
2    const $ = jQuery;
3
4    let init = function () {
5    
6        function checkUrlParameters() {
7            var urlParams = new URLSearchParams(window.location.search);
8            const ignoredParams = [
9                'utm_source',
10                'utm_medium',
11                'utm_campaign',
12                'utm_term',
13                'utm_content'
14            ];
15
16            for (const key of urlParams.keys()) {
17                if (!ignoredParams.includes(key)) {
18                    return true;
19                }
20            }
21            return false;
22        }
23        
24        if (checkUrlParameters()) {
25            // var offset = $('#filter-block').offset();
26            
27            const hash = '#filter-block';
28            if (hash) {
29                const targetElement = document.querySelector(hash);
30                if (targetElement) {
31                    setTimeout(() => {                        
32                        targetElement.scrollIntoView();
33                    }, 0)
34                    
35                }
36            }
37        }
38        renderSelectedTags();
39
40        // document.addEventListener('DOMContentLoaded', function() {
41            
42        // });
43
44
45        $(".missionary-modal-toggle").on("click", function () {
46            $(".modal").toggleClass("is-visible");
47            $("body").toggleClass("overflow-hidden");
48        });
49        $(".missionary-modal-close-btn").on("click", function () {
50            $(".modal").toggleClass("is-visible");
51            $("body").toggleClass("overflow-hidden");
52        });
53        $(".missionary-search-more-less-btn-class").on("click", function () {
54            let index = $(".missionary-search-more-less-btn-class").index(this);
55            $(".missionary-more-filters-class").eq(index).slideToggle();
56            let $span = $(this).find("span");
57            let $img = $(this).find("img");
58
59           
60
61            if ($span.text().trim() == "SHOW MORE") {
62                $span.text("SHOW LESS");
63                $img.addClass("rotate-180");
64            } else {
65                $span.text("SHOW MORE");
66                $img.removeClass("rotate-180");
67            }
68        });
69
70        // search 
71        var suggestionsClicked = false;
72        $('#missionarysearch ').on('keyup', function (e) {
73            var query = $(this).val();
74            var post_type = $(this).data('type');
75            var filter_type = $(this).data('filter-type');
76
77            $.ajax({
78                url: mtw_js_var.ajaxurl,
79                method: 'POST',
80                data: {
81                    'action': 'search_missionary',
82                    's': query,
83                    'post_type': post_type,
84                    'filter_type': filter_type
85                },
86                success: function (data) {
87                   
88                    $('#suggestions').html(data).show();
89                }
90            });
91
92        });
93
94        $('#missionarysearch').on('keydown', function (event) {
95            if (event.key === 'Enter') { // Check if the Enter key is pressed
96                event.preventDefault(); // Prevent the default form submission behavior
97        
98                var query = $(this).val();
99                var currentUrl = window.location.href;
100        
101                if (currentUrl.indexOf('search=') !== -1) {
102                    var updatedUrl = currentUrl.replace(/(search=)[^&]*/, '$1' + encodeURIComponent(query));
103                   
104                    updatedUrl = updatedUrl.replace('#filter-block', '');
105                    window.location.href = updatedUrl;
106                } else {
107                    var newUrl = currentUrl + (currentUrl.indexOf('?') !== -1 ? '&' : '?') + 'search=' + encodeURIComponent(query);
108                    newUrl = newUrl.replace('#filter-block', '');
109                    window.location.href = newUrl;
110                }
111            }
112        });
113        
114        // Trigger search on click of search icon (optional)
115        $('#searchIcon').on('click', function () {
116            performSearch();
117        });
118        
119        function performSearch() {
120            var query = $('#missionarysearch').val();
121            var currentUrl = window.location.href;
122        
123            if (currentUrl.indexOf('search=') !== -1) {
124                var updatedUrl = currentUrl.replace(/(search=)[^&]*/, '$1' + encodeURIComponent(query));
125                updatedUrl = updatedUrl.replace('/#filter-block', '');
126                window.location.href = updatedUrl;
127            } else {
128                var newUrl = currentUrl + (currentUrl.indexOf('?') !== -1 ? '&' : '?') + 'search=' + encodeURIComponent(query);
129                newUrl = newUrl.replace('/#filter-block', '');
130                window.location.href = newUrl;
131            }
132        }
133      
134
135        // Handle click event on #suggestions
136        $('#suggestions').on('click', function (e) {
137            suggestionsClicked = true;
138        });
139
140        // Handle click event on document
141        $(document).on('click', function (e) {
142            if (!suggestionsClicked) {
143                $('#suggestions').hide();
144            }
145            suggestionsClicked = false;
146        });
147
148        $('#suggestions').on('click', function (e) {
149            e.stopPropagation();
150        });
151
152        //remove tag
153        $(document).on('click', '.remove-tag', function (e) {
154            e.preventDefault();
155
156            const taxonomy = $(this).data('taxonomy');
157            const term = $(this).data('term');
158
159            // Uncheck the corresponding filter
160            $(`.filter-checkbox[data-taxonomy="${taxonomy}"][data-term="${term}"]`).prop('checked', false);
161
162            // Update URL and reload filtered results
163            const currentUrl = window.location.href;
164            const updatedUrl = selectremoveQueryStringParameter(currentUrl, taxonomy, term);
165            window.location.href = updatedUrl + '#filter-block';
166        });
167
168
169        // clear filter
170        $('.clear-filters').on('click', function () {
171            var removetaxonomy = $(this).data('taxonomy');
172            window.location.href = removeTaxonomyParameters(window.location.href, [removetaxonomy]) + '#filter-block';
173
174        });
175        $('.clear-filter').on('click', function () {
176            $('.filter-checkbox').prop('checked', false);
177            window.location.href = removeTaxonomyParameters(window.location.href, ['mtw_missionary_region', 'mtw_missionary_country', 'mtw_missionary_off_field', 'mtw_project_region', 'mtw_project_country', 'mtw_project_ministry_type', 'region', 'country', 'duration', 'way_to_serve', 'priority', 'trip_type', 'available_months', 'personnel_type', 'trip_dates', 'month', 'event_type', 'inperson_virtual', 'city', 'story_topic', 'search']) + '#filter-block';
178        });
179        // filter       
180        $(document).on('change', '.filter-checkbox', function () {
181            
182            if ($(this).prop('checked')) {
183                updateFilters();
184
185            } else {
186                var taxonomy = $(this).data('taxonomy');
187                var term = $(this).data('term');
188                var currentUrl = window.location.href;
189                currentUrl = currentUrl.replace(/\/page\/\d+/, '');
190                if (currentUrl.indexOf('#filter-block') !== -1) {
191                    // Remove #filter-block from the URL
192                    currentUrl = currentUrl.replace('/#filter-block', '');
193                    currentUrl = currentUrl.replace('&', '');
194                }
195                var updatedUrl = selectremoveQueryStringParameter(currentUrl, taxonomy, term);
196                var newUrl = updatedUrl + (updatedUrl.includes('/#filter-block') ? '' : '/#filter-block');
197
198                window.location.href = newUrl;
199            }
200
201        });
202        function updateFilters() {
203            var selectedFilters = $('.filter-checkbox:checked').map(function () {
204                return {
205                    taxonomy: $(this).data('taxonomy'),
206                    term: $(this).data('term')
207                };
208            }).get();
209            var currentUrl = window.location.href;
210            var updatedUrl = currentUrl.replace(/\/page\/\d+/, '');
211            var newUrl = updatedUrl.replace('/#filter-block', '');
212            updatedUrl = addOrUpdateQueryStringParameter(newUrl, selectedFilters);
213            window.location.href = updatedUrl;
214        }
215        // $(document).ready(function () {
216        //     if (window.location.hash) {
217        //         var targetSection = $(window.location.hash);
218        //         if (targetSection.length) {
219        //             $('html, body').animate({
220        //                 scrollTop: targetSection.offset().top
221        //             }, 1000); // You can adjust the animation duration
222        //         }
223        //     }
224        // });
225
226        // function addOrUpdateQueryStringParameter(url, filters) {
227        //     var urlParts = url.split('?');
228        //     var baseUrl = urlParts[0];
229        //     var queryString = '';
230
231        //     if (urlParts.length > 1) {
232        //         queryString = urlParts[1];
233        //     }
234        //     var params = {};
235        //     queryString.split('&').forEach(function (param) {
236        //         var keyValue = param.split('=');
237        //         if (keyValue.length === 2) {
238        //             var paramKey = decodeURIComponent(keyValue[0]);
239        //             var paramValue = decodeURIComponent(keyValue[1]);
240        //             params[paramKey] = paramValue.split(',');
241        //         }
242        //     });
243
244        //     filters.forEach(function (filter) {
245        //         var paramKey = encodeURIComponent(filter.taxonomy);
246        //         var paramValue = encodeURIComponent(filter.term);
247        //         if (params[paramKey]) {
248        //             if (typeof params[paramKey] === 'string') {
249        //                 params[paramKey] = [params[paramKey]];
250        //             }
251        //             if (!params[paramKey].includes(paramValue)) {
252        //                 params[paramKey].push(paramValue);
253        //             }
254        //         } else {
255        //             params[paramKey] = paramValue;
256        //         }
257        //     });
258        //     queryString = Object.keys(params).map(function (paramKey) {
259        //         return paramKey + '=' + (Array.isArray(params[paramKey]) ? params[paramKey].join(',') : params[paramKey]);
260        //     }).join('&');
261
262        //     var updatedUrl = baseUrl + (queryString ? '?' + queryString : '');
263        //     return updatedUrl;
264        // }
265        function addOrUpdateQueryStringParameter(url, filters) {
266            var urlParts = url.split('?');
267            var baseUrl = urlParts[0];
268            var queryString = '';
269        
270            if (urlParts.length > 1) {
271                queryString = urlParts[1];
272            }
273        
274            var params = {};
275            queryString.split('&').forEach(function (param) {
276                var keyValue = param.split('=');
277                if (keyValue.length === 2) {
278                    var paramKey = decodeURIComponent(keyValue[0]);
279                    var paramValue = decodeURIComponent(keyValue[1]);
280                    params[paramKey] = paramValue.split(',');
281                }
282            });
283        
284            filters.forEach(function (filter) {
285                var paramKey = encodeURIComponent(filter.taxonomy);
286                var paramValue = encodeURIComponent(filter.term);
287        
288                if (!params[paramKey] || !params[paramKey].includes(paramValue)) {
289                    // If the parameter doesn't exist or the value is not already present, add it
290                    params[paramKey] = params[paramKey] || [];
291                    params[paramKey].push(paramValue);
292                }
293            });
294        
295            queryString = Object.keys(params).map(function (paramKey) {
296                return paramKey + '=' + params[paramKey].join(',');
297            }).join('&');
298        
299            var updatedUrl = baseUrl + (queryString ? '?' + queryString : '');
300            return updatedUrl;
301        }
302        
303        function removeQueryStringParameter(url, parameter) {
304            return url.replace(new RegExp('/?' + parameter + '=[^&]*'), '');
305        }
306        function removeTaxonomyParameters(url, taxonomies) {
307            taxonomies.forEach(function (taxonomy) {
308                url = removeQueryStringParameter(url, taxonomy);
309            });
310            return url;
311        }
312
313        function selectremoveQueryStringParameter(url, taxonomy, term, expectedParams = ['regi
313on', 'duration', 'way_to_serve', 'country', 'priority', 'mtw_missionary_off_field', 'mtw_missionary_country', 'mtw_missionary_region', 'mtw_project_region', 'mtw_project_country', 'mtw_project_ministry_type']) {
314            const urlObject = new URL(url);
315            const rawQuery = decodeURIComponent(urlObject.search.slice(1));
316            const cleanedParams = new URLSearchParams();
317            console.log('function selectremoveQueryStringParameter call');
318            const normalize = val => val.trim().replace(/^\/+/, '').replace(/\/+$/, '');
319            const normalizedTerm = normalize(term);
320
321            expectedParams.forEach(param => {
322                const regex = new RegExp(`${param}=([^&]*)`, 'g');
323                let match;
324
325                while ((match = regex.exec(rawQuery)) !== null) {
326                    let rawValue = match[1];
327                    expectedParams.forEach(otherParam => {
328                        if (otherParam !== param && rawValue.includes(otherParam + '=')) {
329                            rawValue = rawValue.split(otherParam + '=')[0];
330                        }
331                    });
332
333                    let values = rawValue.split(',').map(normalize);
334                    if (param === taxonomy) {
335                        values = values.filter(v => v !== normalizedTerm);
336                    }
337
338                    if (values.length > 0) {
339                        const existing = cleanedParams.get(param);
340                        const combined = existing ? existing.split(',').concat(values) : values;
341                        cleanedParams.set(param, [...new Set(combined)].join(','));
342                    }
343                }
344            });
345
346            urlObject.search = cleanedParams.toString();
347            urlObject.pathname = urlObject.pathname.replace(/\/+/g, '/');
348
349            return urlObject.href;
350        }
351
352        function renderSelectedTags() {
353            console.log('renderSelectedTags function');
354            const container = $('#selected-filters');
355            container.empty(); // Clear existing tags
356
357            const seen = new Set(); // track duplicates
358
359            $('.filter-checkbox:checked').each(function () {
360                const taxonomy = $(this).data('taxonomy');
361                const term = $(this).data('term');
362                const key = taxonomy + ':' + term;
363
364                // Skip duplicate filters
365                if (seen.has(key)) return;
366                seen.add(key);
367
368                // Get label text from this label
369                const labelText = $(this)
370                    .closest('label')
371                    .contents()
372                    .filter(function () { return this.nodeType === 3; })
373                    .text()
374                    .trim();
375
376                const tag = $(`
377                    <div class="flex items-center text-gray-800 px-3 py-1 rounded-full lg:text-sm mr-2 mb-2 text-[0.87rem] bg-white">
378                        <span>${labelText}</span>
379                        <button class="ml-2 remove-tag text-gray-600 hover:text-red-600" 
380                                data-taxonomy="${taxonomy}" 
381                                data-term="${term}">
382                            ✕
383                        </button>
384                    </div>
385                `);
386
387                container.append(tag);
388            });
389        }
390
391
392    };
393    return {
394        init: init,
395    };
396})();
397
398document.addEventListener("DOMContentLoaded", function (event) {
399    window.addEventListener(
400        "load",
401        function (e) {
402            missionarySearchModule.init();
403        },
404        false
405    );
406});

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.