1var hasPortfolioReviewUrlState = false; 2 3function getImageSearchSelectedSlug($select) { 4 var $selectedOption = $select.find("option:selected"); 5 return $selectedOption.attr("data-slug") || ""; 6} 7 8function buildImageSearchUrl($form, includePage, includeAjax) { 9 var segments = []; 10 var categorySlug = getImageSearchSelectedSlug( 11 $form.find("#spotlight_category_id") 12 ); 13 var countrySlug = getImageSearchSelectedSlug( 14 $form.find("#spotlight_country_id") 15 ); 16 var query = {}; 17 var q = $.trim($form.find('input[name="q"]').val() || ""); 18 var page = $.trim($form.find('input[name="page"]').val() || ""); 19 20 if (categorySlug) { 21 segments.push(categorySlug); 22 } 23 24 if (countrySlug) { 25 segments.push(countrySlug); 26 } 27 28 if (q) { 29 query.q = q; 30 } 31 32 if (includePage && page && page !== "1") { 33 query.page = page; 34 } 35 36 if (includeAjax) { 37 query.ajax = 1; 38 } 39 40 var url = "/image-search"; 41 if (segments.length) { 42 url += "/" + segments.join("/"); 43 } 44 45 var queryString = $.param(query); 46 if (queryString) { 47 url += "?" + queryString; 48 } 49 50 return url; 51} 52 53function SearchResults(search_form, results_container) { 54 this.search_form = search_form; 55 this.results_container = results_container; 56 this.page_input = this.search_form.find('input[name="page"]'); 57 58 this.setHistory(); 59 this.getItems(); 60 this.search_form.on("submit", _.bind(this.onFormSubmit, this)); 61 62 this.category_select = this.search_form.find($("#spotlight_category_id")); 63 this.category_select.select2({ 64 templateResult: _.bind(this.formatCategory, this), 65 }); 66 this.category_select.on( 67 "change", 68 _.bind(this.onCategorySelectChange, this) 69 ); 70 this.country_select = this.search_form.find($("#spotlight_country_id")); 71 this.country_select.select2(); 72 this.country_select.on("change", _.bind(this.onCountrySelectChange, this)); 73 74 this.ias = $.ias({ 75 container: ".portfolio-review-items", 76 item: ".portfolio-review-item", 77 pagination: "#pagination", 78 next: ".next", 79 }); 80 this.ias.on("render", _.bind(this.onIasRender, this)); 81 this.ias.on("rendered", _.bind(this.onIasRendered, this)); 82 this.ias.on("load", _.bind(this.onIasLoad, this)); 83 84 this.loadMemberSearch(); 85} 86 87SearchResults.prototype.onFormSubmit = function (e) { 88 e.preventDefault(); 89 this.submitSearch(); 90}; 91 92SearchResults.prototype.draw = function (data) { 93 this.data = data; 94 this.results_container.html(this.data); 95 96 this.ias.reinitialize(); 97 98 var items = this.results_container.find(".portfolio-review-items"); 99 this.drawItems(items); 100}; 101 102SearchResults.prototype.drawItems = function (items) { 103 var items_container = this.results_container.find(".portfolio-review-items"); 104 105 if (!items_container.length) { 106 $("#search-results-loading").hide(); 107 $(".image-search-preloading").hide(); 108 return; 109 } 110 111 items_container.masonry({ 112 gutter: 33, 113 transitionDuration: 0, 114 }); 115 items_container.masonry("reloadItems"); 116 items_container.masonry("layout"); 117 items_container.css({ 118 visibility: "visible", 119 opacity: 1, 120 }); 121 items_container.find(".portfolio-review-item").css({ opacity: 1 }); 122 123 $("#search-results-loading").hide(); 124 $(".image-search-preloading").hide(); 125 126 items_container.imagesLoaded().progress(function () { 127 items_container.masonry("layout"); 128 }); 129 130 const gallery = document.querySelector(".photo-gallery"); 131 if (gallery) { 132 const images = gallery.querySelectorAll("a"); 133 images.forEach((image) => { 134 const img = new Image(); 135 if (!image.hasAttribute("data-pswp-width")) { 136 img.src = image.href; 137 img.onload = function () { 138 image.setAttribute("data-pswp-width", this.width); 139 image.setAttribute("data-pswp-height", this.height); 140 }; 141 } 142 }); 143 } 144}; 145 146SearchResults.prototype.onCategorySelectChange = function () { 147 this.submitSearch(); 148 149 ga("create", "UA-578862-1", "auto"); 150 ga("send", "event", { 151 eventCategory: "Portfolio Review Category", 152 eventAction: "Search", 153 eventLabel: $("#spotlight_category_id option:selected").text(), 154 eventValue: parseInt( 155 $("#spotlight_category_id option:selected").val(), 156 10 157 ), 158 }); 159}; 160 161SearchResults.prototype.onCountrySelectChange = function () { 162 this.submitSearch(); 163 164 ga("create", "UA-578862-1", "auto"); 165 ga("send", "event", { 166 eventCategory: "Portfolio Review Country", 167 eventAction: "Search", 168 eventLabel: $("#spotlight_country_id option:selected").text(), 169 eventValue: parseInt( 170 $("#spotlight_country_id option:selected").val(), 171 10 172 ), 173 }); 174}; 175 176SearchResults.prototype.setHistory = function (data) { 177 var url = buildImageSearchUrl(this.search_form, true, false); 178 179 if (!window.history || !window.history.pushState) { 180 return; 181 } 182 183 if (hasPortfolioReviewUrlState) { 184 history.pushState({}, null, url); 185 } else { 186 history.replaceState({}, null, url); 187 hasPortfolioReviewUrlState = true; 188 } 189}; 190 191SearchResults.prototype.getItems = function () { 192 if (this.ajax) { 193 this.ajax.abort(); 194 } 195 this.ajax = true; 196 this.data = buildImageSearchUrl(this.search_form, true, true); 197 198 this.results_container.find(".portfolio-review-items").css({ 199 visibility: "hidden", 200 opacity: 0, 201 }); 202 $(".image-search-preloading").show(); 203 204 this.ajax = jQuery.ajax({ 205 method: "GET", 206 dataType: "html", 207 url: this.data, 208 success: _.bind(this.processResult, this), 209 error: _.bind(this.processNoResults, this), 210 }); 211}; 212 213SearchResults.prototype.onIasLoad = function (e) { 214 if (e.url.indexOf("?") > -1) { 215 e.url += "&ajax=1"; 216 } else { 217 e.url += "?ajax=1"; 218 } 219}; 220 221SearchResults.prototype.loadMemberSearch = function (e) { 222 const memberSearch = document.querySelector(".member-search-input"); 223 if (memberSearch) { 224 const suggestionItems = JSON.parse( 225 memberSearch.dataset.suggestionItems || "[]" 226 ); 227 const memberSearchInput = memberSearch.querySelector("input"); 228 229 const autoCompleteJS = new autoComplete({ 230 data: { 231 src: suggestionItems, 232 cache: true, 233 }, 234 resultsList: { 235 element: (list, data) => { 236 const info = document.createElement("p"); 237 if (data.results.length > 0) { 238 info.innerHTML = `Displaying <strong>${data.results.length}</strong> out of <strong>${data.matches.length}</strong> results`; 239 } else { 240 info.innerHTML = `Found <strong>${data.matches.length}</strong> matching results for <strong>"${data.query}"</strong>`; 241 } 242 list.prepend(info); 243 }, 244 noResults: true, 245 maxResults: 50, 246 tabSelect: true, 247 }, 248 resultItem: { 249 highlight: true, 250 }, 251 events: { 252 input: { 253 selection: (event) => { 254 memberSearchInput.value = 255 event.detail.selection.value; 256 this.submitSearch(); 257 }, 258 submit: (event) => { 259 this.submitSearch(); 260 }, 261 }, 262 }, 263 }); 264 const that = this; 265 memberSearchInput.addEventListener("keyup", function (event) { 266 if ( 267 event.keyCode === 13 && 268 (((!this.getAttribute("aria-activedescendant") || 269 this.getAttribute("aria-activedescendant") === "") && 270 this.parentElement.getAttribute("aria-expanded") === 271 "true") || 272 memberSearchInput.value === "") 273 ) { 274 that.submitSearch(); 275 } 276 }); 277 } 278}; 279 280SearchResults.prototype.onIasRender = function (items) { 281 $(items).css({ opacity: 0 }); 282 $(".image-search-preloading").show(); 283}; 284 285SearchResults.prototype.onIasRendered = function (items) { 286 this.drawItems(items); 287}; 288 289SearchResults.prototype.updateSearchField = function (e) { 290 this.submitSearch(); 291}; 292 293SearchResults.prototype.processResult = function (response) { 294 this.draw(response); 295}; 296 297SearchResults.prototype.processNoResults = function (response) { 298 $("#search-results-loading").hide(); 299 $(".image-search-preloading").hide(); 300 this.draw("No results."); 301}; 302 303SearchResults.prototype.resetPage = function () { 304 this.page_input.val(""); 305}; 306 307SearchResults.prototype.submitSearch = function () { 308 this.resetPage(); 309 this.setHistory(); 310 this.getItems(); 311}; 312 313SearchResults.prototype.formatCategory = function (option) { 314 if (!option.id) { 315 return option.text; 316 } 317 var lvl = 318 $('#spotlight_category_id option[value="' + option.id + '"]').data( 319 "lvl" 320 ) || 0; 321 if (lvl == 1) { 322 return $("<span><strong>" + option.text + "</strong>"); 323 } else if (lvl == 2) { 324 return $( 325 '<span style="display:inline-block;padding-left:15px;">' + 326 option.text + 327 "</span>)" 328 ); 329 } else if (lvl == 3) { 330 return $( 331 '<span style="display:inline-block;padding-left:25px;font-size:10px;">' + 332 option.text + 333 "</span>)" 334 ); 335 } else { 336 return $("<span>" + option.text + ""); 337 } 338}; 339 340(function ($) { 341 var portfolio_review = new SearchResults( 342 $("#portfolio-review-form"), 343 $(".portfolio-review-data-container") 344 ); 345})(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.