1excludedSearchParams = [ 2 "jtstartIndex", 3 "jtpageSize", 4 "jtsorting", 5 "clientid", 6 "isexternalrequest", 7 "featuredonly", 8 "defaultradiusvalue", 9 "islocationspagesearch", 10 "isinternational", 11 "uselocation", 12 "usegoogleplaces", 13 "usebingautosuggest", 14 "requestedinputs", 15]; 16 17multiSelectSearchParams = ["categoryid", "industryid", "familyid"]; 18 19function shouldAddParamToUrl(key, value, inputKeys, excludedKeys) { 20 if (value == null || value === undefined || value === "" || value === "undefined" || value === "null") { 21 return false; 22 } 23 24 if (Array.isArray(value)) { 25 if (value.length === 0) return false; 26 } 27 28 const valueType = typeof value; 29 if ( 30 !Array.isArray(value) && 31 valueType !== "string" && 32 valueType !== "number" && 33 valueType !== "boolean" 34 ) { 35 return false; 36 } 37 if (valueType === "string" && value.trim() === "") { 38 return false; 39 } 40 if (valueType === "number" && isNaN(value)) { 41 return false; 42 } 43 44 const normalizedKey = key.toLowerCase(); 45 46 let mappedKey; 47 48 switch (normalizedKey) { 49 case "brandname": 50 mappedKey = "adbrandid"; 51 break; 52 case "geolocationstring": 53 mappedKey = "geolocation"; 54 break; 55 case "adlocationtypeid": 56 mappedKey = "locationname"; 57 break; 58 case "radius": 59 mappedKey = inputKeys.find((key) => key.toLowerCase().includes("radius")) || "radius"; 60 break; 61 default: 62 mappedKey = normalizedKey; 63 } 64 65 return !excludedKeys.includes(mappedKey); 66} 67 68function buildQueryParams(data, inputKeys, excludedKeys) { 69 const params = new URLSearchParams(); 70 71 if (!data) return params; 72 73 const addParam = (key, value) => { 74 if (shouldAddParamToUrl(key, value, inputKeys, excludedKeys)) { 75 const lowerKey = key.toLowerCase(); 76 const isMultiSelect = multiSelectSearchParams.includes(lowerKey); 77 78 if (lowerKey.includes("geolocation") && !value.includes("_")) { 79 var coordinatesValue = $("#GeolocationString").val(); 80 var inputValue = $("#geolocation_value").val(); 81 if (inputValue != null && inputValue != "") { 82 value = `${coordinatesValue}_${inputValue}`; 83 } 84 } 85 86 // Split comma-separated string into array if applicable 87 if (isMultiSelect && typeof value === "string" && value.includes(",")) { 88 value = value 89 .split(",") 90 .map((v) => v.trim()) 91 .filter((v) => v.length > 0); 92 } 93 94 if (lowerKey === "remotejobs" && (value === "true" || value === true)) { 95 value = "true"; // Ensure the value is a string "true" 96 } else if (lowerKey === "remotejobs" && (value === "false" || value === false)) { 97 return; 98 } 99 100 const existingValues = params.getAll(lowerKey); 101 const tryAddValue = (v) => { 102 if (!existingValues.includes(v)) params.append(lowerKey, v); 103 }; 104 105 if (Array.isArray(value)) { 106 value.forEach((v) => (isMultiSelect ? tryAddValue(v) : params.append(lowerKey, v))); 107 } else { 108 if (isMultiSelect) { 109 tryAddValue(value); 110 } else { 111 params.append(lowerKey, value); 112 } 113 } 114 } 115 }; 116 117 if (Array.isArray(data)) { 118 data.forEach(({ name, value }) => addParam(name, value)); 119 } else { 120 Object.entries(data) 121 .forEach(([key, value]) => addParam(key, value)); 122 } 123 124 // Append preserved external params (captured once on initial page load) 125 if (window._externalParams) { 126 for (const [key, value] of window._externalParams) { 127 if (!params.has(key)) { 128 params.append(key, value); 129 } 130 } 131 } 132 133 return params; 134} 135 136function getFormResponseUrl($element, inputKeys, excludedKeys) { 137 var searchUrl = `${window.location.host}/search/searchjobs`; 138 var dataObject = core.common.getSearchFormKeyValues($element); 139 var params = buildQueryParams(dataObject, inputKeys, excludedKeys); 140 var hasParams = Boolean(params.size || params.toString()); 141 return hasParams ? `${searchUrl}?${params.toString()}` : searchUrl; 142} 143 144function getFormData($element) { 145 const dataObject = core.common.getSearchFormKeyValues($element); 146 147 const geolocate = dataObject.find((item) => item.name === "GeolocationString"); 148 if (geolocate?.value && !geolocate.value.includes("_")) { 149 const inputValue = $("#geolocation_value").val(); 150 if (inputValue !== null && inputValue !== "") { 151 geolocate.value += `_${inputValue}`; 152 } 153 } 154 155 return dataObject; 156} 157 158function getFormViewModel($element) {
159 const keyValues = getFormData($element); 160 161 const model = {}; 162 163 keyValues.forEach(({ name, value }) => { 164 if (value === "" || value === null || value === undefined) return; 165 166 const arrayFields = ["CategoryID", "IndustryID", "FamilyID"]; 167 168 if (model[name] !== undefined) { 169 if (!Array.isArray(model[name])) { 170 model[name] = [model[name]]; 171 } 172 model[name].push(value); 173 } else { 174 model[name] = arrayFields.includes(name) ? [value] : value; 175 } 176 }); 177 178 return model; 179} 180 181function submitFloatForm(e, formType) { 182 window.trackFormSubmission(formType); 183 if (formType == "static") { 184 window.history.replaceState(null, null, window.location.pathname); 185 return true; 186 } 187 e.preventDefault(); 188 189 function doFloatSubmit() { 190 var inputs = window.expectedInputs || []; 191 var submitter = e.submitter || document.activeElement || e.target; 192 var searchUrl = getFormResponseUrl($(submitter), inputs, excludedSearchParams); 193 if (searchUrl) { 194 window.location = "//" + searchUrl; 195 } 196 } 197 198 if (typeof window.geocodeBeforeSubmit === 'function') { 199 window.geocodeBeforeSubmit().then(doFloatSubmit); 200 } else { 201 doFloatSubmit(); 202 } 203 return false; 204} 205 206function setLinkLoading(link, isLoading) { 207 if (isLoading) { 208 link.classList.add("loading"); 209 link.setAttribute("aria-busy", "true"); 210 link.setAttribute("aria-disabled", "true"); 211 link.setAttribute("tabindex", "-1"); 212 link.setAttribute("aria-label", "Loading..."); 213 link.style.pointerEvents = "none"; // Disable pointer events 214 } else { 215 link.classList.remove("loading"); 216 link.removeAttribute("aria-busy"); 217 link.removeAttribute("aria-disabled"); 218 link.removeAttribute("tabindex"); 219 link.removeAttribute("aria-label"); 220 link.style.pointerEvents = ""; // Re-enable pointer events 221 } 222} 223 224function setUpPaginationLinks(params) { 225 document.querySelectorAll(".pagination a.page-link").forEach((link) => { 226 link.addEventListener("click", function (event) { 227 event.preventDefault(); 228 setLinkLoading(this, true); 229 const page = this.getAttribute("data-page"); 230 params.set("page", page); 231 getPageResults(page, params, this); 232 }); 233 }); 234} 235 236function getPageResults(page, params, clickedElement) { 237 const requestPage = typeof page === "string" ? parseInt(page, 10) : page; 238 if (isNaN(requestPage) || requestPage < 1) { 239 page = 1; 240 } 241 if (page > 1) { 242 params.set("page", page); 243 } 244 const fetchUrl = `${window.location.origin}/search/searchresultslist?${params.toString()}`; 245 const jobResultsContainer = document.querySelector(".job-results.job-list"); 246 if (!jobResultsContainer) { 247 return; 248 } 249 const jobListingsContainer = jobResultsContainer.querySelector(".job-listings-container"); 250 const paginationContainer = jobResultsContainer.querySelector(".job-listings-pagination"); 251 252 jobResultsContainer.classList.add("loading"); 253 254 fetch(fetchUrl) 255 .then(async (response) => { 256 if (!response.ok) { 257 const text = await response.text(); 258 throw new Error(`HTTP error: ${response.status} - ${text.substring(0, 200)}`); 259 } 260 return response.json(); 261 }) 262 .then((data) => { 263 if (clickedElement && clickedElement.classList) { 264 setLinkLoading(clickedElement, false); 265 } 266 jobResultsContainer.classList.remove("loading"); 267 268 if (jobListingsContainer) { 269 jobListingsContainer.innerHTML = data.jobsHtml; 270 } else { 271 jobResultsContainer.insertAdjacentHTML("afterbegin", data.jobsHtml); 272 } 273 if (paginationContainer) { 274 paginationContainer.innerHTML = data.paginationHtml; 275 } else { 276 jobResultsContainer.insertAdjacentHTML("beforeend", data.paginationHtml); 277 } 278 279 const newPageUrl = new URL(window.location.href); 280 // Replace all search parameters with the new ones 281 const paramsForFetch = new URLSearchParams(params); 282 if (page > 1) { 283 paramsForFetch.set("page", page.toString()); 284 } else { 285 paramsForFetch.delete("page"); 286 } 287 newPageUrl.search = paramsForFetch.toString(); 288 289 window.history.pushState({ path: newPageUrl.href }, "", newPageUrl.href); 290 setUpPaginationLinks(paramsForFetch); 291 }) 292 .catch((error) => { 293 console.error("Error fetching results:", error); 294 jobResultsContainer.classList.remove("loading"); 295 jobListingsContainer.innerHTML = 296 "<p class='error'>An error occurred while fetching the results. Please try again later.</p>"; 297 if (clickedElement && clickedElement.classList) { 298 setLinkLoading(clickedElement, false); 299 } 300 if (paginationContainer && paginationContainer.innerHTML) { 301 paginationContainer.innerHTML = ""; 302 } 303 }); 304} 305 306function getSearchParams(data) { 307 const inputs = window.expectedInputs || []; 308 return buildQueryParams(data, inputs, excludedSearchParams); 309}
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.