1(function ($) { 2 3 let localCache = { 4 data: {}, 5 remove: function (url) { 6 delete localCache.data[url]; 7 }, 8 exist: function (url) { 9 return localCache.data.hasOwnProperty(url) && localCache.data[url] !== null; 10 }, 11 get: function (url) { 12 return localCache.data[url]; 13 }, 14 set: function (url, cachedData, callback) { 15 localCache.remove(url); 16 localCache.data[url] = cachedData; 17 if ($.isFunction(callback)) callback(cachedData); 18 } 19 }; 20 21 function initSearchForm() { 22 23 const $searchForm = $(this), 24 $ajaxSearchParams = $('.ajax-search-params', $searchForm), 25 postTypes = $ajaxSearchParams.data('post-types'), 26 postTypesPpp = $ajaxSearchParams.data('post-types-ppp'), 27 resultTitle = $ajaxSearchParams.data('result-title'), 28 showAllText = $ajaxSearchParams.data('show-all'), 29 $searchSubmitIcon = $('.search-submit', $searchForm), 30 $searchInput = $('.search-field', $searchForm), 31 $searchResults = $('.ajax-search-results', $searchForm), 32 $selectCategory = $('.select-category', $searchForm), 33 $searchButtons = $('.search-buttons', $searchForm); 34 35 let ajax, ajaxActive = false; 36 37 const checkWidth = () => { 38 $searchForm.removeClass('columns-2').removeClass('columns-3').removeClass('columns-4'); 39 if ($searchForm.width() >= 1240) { 40 $searchForm.addClass('columns-4'); 41 } else if ($searchForm.width() >= 930) { 42 $searchForm.addClass('columns-3'); 43 } else if ($searchForm.width() >= 620) { 44 $searchForm.addClass('columns-2'); 45 } 46 if ($searchButtons.length) { 47 $searchInput.css('padding-right', ($searchButtons.outerWidth() + 5) + 'px'); 48 } 49 }; 50 51 const maybeInvert = () => { 52 formRect = $searchForm.get(0).getBoundingClientRect(); 53 if(formRect.top > 0 && formRect.top < $(window).height()) { 54 resultsRect = $searchResults.get(0).getBoundingClientRect(); 55 if(resultsRect.bottom > $(window).height()) { 56 $searchForm.addClass('invert-results'); 57 resultsRect = $searchResults.get(0).getBoundingClientRect(); 58 if(resultsRect.top < 0) { 59 $searchForm.removeClass('invert-results'); 60 } 61 } 62 } 63 }; 64 65 const ajaxMiniSearch = (query) => { 66 if (ajaxActive) { 67 ajax.abort(); 68 } 69 $searchForm.addClass('ajax-loading'); 70 71 let productCategory = $selectCategory.length ? $selectCategory.find('.current .text').data('term') : ''; 72 73 ajax = $.ajax({ 74 type: 'post', 75 url: thegem_search_form_data.ajax_url, 76 data: { 77 action: 'thegem_ajax_search_form', 78 search: query, 79 post_types: postTypes, 80 post_types_ppp: postTypesPpp, 81 product_category: productCategory, 82 result_title: resultTitle, 83 show_all_text: showAllText, 84 }, 85 beforeSend: function () { 86 if (localCache.exist(query + productCategory)) { 87 $searchForm.removeClass('ajax-loading'); 88 $searchForm.addClass('visible'); 89 maybeInvert(); 90 $searchResults.html(localCache.get(query + productCategory)); 91 return false; 92 } else { 93 ajaxActive = true; 94 } 95 }, 96 success: function (response) { 97 ajaxActive = false; 98 $searchResults.html(response); 99 $searchForm.removeClass('ajax-loading'); 100 $searchForm.addClass('visible'); 101 maybeInvert(); 102 localCache.set(query + productCategory, response); 103 } 104 }); 105 }; 106 107 const clearAjaxMinisearch = () => { 108 $searchInput.val(''); 109 $searchResults.html(''); 110 $searchSubmitIcon.removeClass('clear'); 111 $searchForm.removeClass('ajax-loading'); 112 if (ajaxActive) { 113 ajax.abort(); 114 ajaxActive = false; 115 } 116 }; 117 118 const submitAjax = () => { 119 let query = $searchInput.val(); 120 121 if (query.length > 0) { 122 $searchSubmitIcon.addClass('clear'); 123 } else { 124 $searchSubmitIcon.removeClass('clear'); 125 } 126 127 if (query.length > 2) { 128 ajaxMiniSearch(query); 129 } else { 130 if (ajaxActive) { 131 ajax.abort(); 132 ajaxActive = false; 133 } 134 $searchResults.html(''); 135 $searchForm.removeClass('ajax-loading'); 136 } 137 }; 138 139 $searchForm.on('submit', function (e) { 140 // e.preventDefault(); 141 // submitAjax(); 142 // $searchInput.blur(); 143 }); 144 145 $searchInput.on('keyup', function () { 146 submitAjax(); 147 }); 148 149 $searchInput.on('focus', function () { 150 $selectCategory.removeClass('active'); 151 }); 152 153 $searchSubmitIcon.on('click', function () { 154 if ($(this).hasClass('clear')) { 155 clearAjaxMinisearch(); 156 } 157 }); 158 159 $('.hamburger-toggle, #thegem-perspective .perspective-menu-close, .vertical-toggle').click(function () { 160 clearAjaxMinisearch(); 161 }); 162 163 $selectCategory.on('click', function () { 164 $(this).toggleClass('active'); 165 }); 166 167 $selectCategory.on('click', '.term', function () { 168 if (!$(this).hasClass('active')) { 169 $selectCategory.find('.current .text').html($(this).html()).data('term', $(this).data('term')); 170 $selectCategory.find('.term').removeClass('active'); 171 $(this).addClass('active'); 172 submitAjax(); 173 } 174 }); 175 176 $('body').on('click', function () { 177 $searchForm.removeClass('visible'); 178 $searchForm.removeClass('invert-results'); 179 $selectCategory.removeClass('active'); 180 }); 181 182 $searchForm.on('click', function (e) { 183 e.stopPropagation(); 184 $(this).addClass('visible'); 185 maybeInvert(); 186 }); 187 188 checkWidth(); 189 190 $(window).on('resize', function () { 191 checkWidth(); 192 }); 193 } 194 195 196 $.fn.initSearchForms = function () { 197 $(this).each(initSearchForm); 198 }; 199 200 $(function () { 201 $('.thegem-te-search-form.ajax-search-form').initSearchForms(); 202 }); 203 204})(jQuery);
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.