1((win, doc) => { 2 'use strict'; 3 4 const MODELS_DATA = { 5 TITLE: 'namePlusAlias', 6 DESCRIPTION: 'salesProductName', 7 OVERVIEW_LINK: 'overviewUrl', 8 DISCONTINUED: 'discontinuedFlag', 9 THUMBNAIL: 'thumbnail', 10 DIALOG_LINK: 'dimensionsUrl', 11 DATA_SHEET_LINK: 'dataSheetUrl', 12 DATA_CAD_LINK: 'cadUrl', 13 MANUALS_LINK: 'manualsUrl' 14 }; 15 16 const GLOBAL_SETTINGS = { 17 SITE_ID: win.kpi_siteSettings.siteId ? win.kpi_siteSettings.siteId : null, 18 SITE_LANG: win.kpi_siteSettings.siteLang ? win.kpi_siteSettings.siteLang : null, 19 ORIGINAL_DOMAIN: win.kpi_originalDomain ? win.kpi_originalDomain : null 20 }; 21 22 const SETTINGS_ID = { 23 GROUP: win.kpi_currentGroupId ? win.kpi_currentGroupId : null, 24 TYPE: win.kpi_currentTypeId ? win.kpi_currentTypeId : null, 25 SERIES: win.kpi_currentSeriesId ? win.kpi_currentSeriesId : null 26 }; 27 28 const API_PATH = { 29 MODELS: `${GLOBAL_SETTINGS.ORIGINAL_DOMAIN}/data/api/seriesModels?` 30 }; 31 32 const PREFIX = { 33 COOKIE: encodeURIComponent(GLOBAL_SETTINGS.ORIGINAL_DOMAIN.split('www.keyence.')[1]) 34 }; 35 36 const CONFIG = { 37 SITE_API_PARAM: 'siteID', 38 LANGUAGE_API_PARAM: 'languageID', 39 GROUP_API_PARAM: 'groupID', 40 TYPE_API_PARAM: 'typeID', 41 SERIES_API_PARAM: 'seriesID', 42 CATEGORY_PARAM: 'productTypeID', 43 SELECT_CATEGORY_COOKIE_NAME: `kpi_has_selectCategory_${PREFIX.COOKIE}_modelTypes` 44 }; 45 46 class Utility { 47 static getTextOnly(textItem) { 48 return textItem.replace(/(<([^>]+)>)/gi, ''); 49 } 50 51 static getParam(paramName) { 52 const url = new URLSearchParams(win.location.search); 53 54 return url.get(paramName); 55 } 56 57 static getCheckedData(items) { 58 const selectedDataArray = []; 59 60 items.forEach((item) => { 61 selectedDataArray.push(item.value); 62 }); 63 64 return selectedDataArray; 65 } 66 67 static getJoinedArray(arrayItem) { 68 if (!Array.isArray(arrayItem) || !arrayItem.length) { 69 return ''; 70 } 71 72 return arrayItem.join(','); 73 } 74 75 static setCookie(cookieName, cookieValue) { 76 const date = new Date(); 77 let path; 78 79 if (win.suz_LanguagePath) { 80 path = `${win.suz_LanguagePath}/`; 81 } else { 82 path = '/'; 83 } 84 85 date.setDate(date.getDate() + 90); 86 doc.cookie = `${cookieName}=${cookieValue}; expires=${date.toUTCString()}; path=${path}`; 87 } 88 89 static getCookieValue(name) { 90 const cookies = doc.cookie.split(';'); 91 92 if (!name) { 93 return false; 94 } 95 96 if (!cookies.some((item) => item.trim().startsWith(`${name}=`))) { 97 return false; 98 } 99 100 const targetCookie = cookies.find((item) => item.trim().startsWith(`${name}=`)); 101 102 return targetCookie.split('=')[1]; 103 } 104 105 static setElementText(element, object, objectKey) { 106 if (element && element.nodeType === Node.ELEMENT_NODE) { 107 if (object.hasOwnProperty(objectKey) === false || !object[objectKey]) { 108 element.remove(); 109 } else { 110 element.textContent = Utility.getTextOnly(object[objectKey]); 111 } 112 } 113 } 114 115 static setElementLink(element, object, objectKey) { 116 if (element && element.nodeType === Node.ELEMENT_NODE) { 117 if (object.hasOwnProperty(objectKey) === false || !object[objectKey]) { 118 element.removeAttribute('href'); 119 } else { 120 element.href = object[objectKey]; 121 } 122 } 123 } 124 } 125 126 class SelectModelsType { 127 constructor() { 128 this.selectors = { 129 modelsList: '.js-outputModelsData-list', 130 switchItemsTarget: '.js-outputModelsData-switchItemsTarget', 131 imageTarget: '.js-outputModelsData-image', 132 discontinuedTarget: '.js-outputModelsData-discontinued', 133 overviewLinkTarget: '.js-outputModelsData-overviewLink', 134 titleTarget: '.js-outputModelsData-title', 135 descriptionTarget: '.js-outputModelsData-description', 136 dialogButtonTarget: '.js-outputModelsData-dialogButton', 137 dialogTarget: '.js-outputModelsData-dialog', 138 dataSheetLinkTarget: '.js-outputModelsData-dataSheetLink', 139 cadLinkTarget: '.js-outputModelsData-cadLink', 140 manualsLinkTarget: '.js-outputModelsData-manualsLink' 141 }; 142 143 this.elementIdNames = { 144 filterModelsTypes: 'js-filterModelsTypes',
145 categoryFilterTrigger: 'js-filterModelsTypes-categoryList', 146 excludeDiscontinuedNumberTarget: 'js-outputModelsData-excludeDiscontinuedNumber', 147 totalNumberTarget: 'js-outputModelsData-totalNumber', 148 modelsTemplate: 'js-outputModelsData-template' 149 }; 150 151 this.filterModelsTypes = doc.getElementById(this.elementIdNames.filterModelsTypes); 152 this.categoryFilterTrigger = doc.getElementById(this.elementIdNames.categoryFilterTrigger); 153 this.excludeDiscontinuedNumberTarget = doc.getElementById(this.elementIdNames.excludeDiscontinuedNumberTarget); 154 this.totalNumberTarget = doc.getElementById(this.elementIdNames.totalNumberTarget); 155 this.modelsTemplate = doc.getElementById(this.elementIdNames.modelsTemplate); 156 this.modelsListTarget = doc.querySelector(this.selectors.modelsList); 157 this.categoryParamValue = ''; 158 this.cookieArray = []; 159 } 160 161 init() { 162 if (!this.filterModelsTypes || !this.categoryFilterTrigger || !this.modelsListTarget || !this.modelsTemplate) { 163 return; 164 } 165 166 this.allCheckBoxItem = this.filterModelsTypes.querySelector('[name="all"]'); 167 this.categoryCheckBoxItems = this.filterModelsTypes.querySelectorAll('[name="category"]'); 168 169 if (!this.allCheckBoxItem || !this.categoryCheckBoxItems.length) { 170 return; 171 } 172 173 this.updateCookies(); 174 this.attachChangeEvent(); 175 this.getAllCategoryValue(); 176 this.getFilterParam(); 177 this.updateTriggerStatus(); 178 this.setSelectedData(); 179 this.getApiData(); 180 this.setMutationObserver(); 181 } 182 183 updateCookies() { 184 const modelTypeCookie = Utility.getCookieValue(CONFIG.SELECT_CATEGORY_COOKIE_NAME); 185 186 if (!modelTypeCookie) { 187 Utility.setCookie(CONFIG.SELECT_CATEGORY_COOKIE_NAME, JSON.stringify(this.cookieArray)); 188 } 189 } 190 191 attachChangeEvent() { 192 this.allCheckBoxItem.addEventListener('change', this.setSelectedData.bind(this)); 193 this.categoryCheckBoxItems.forEach((item) => { 194 item.addEventListener('change', this.setSelectedData.bind(this)); 195 }); 196 } 197 198 getAllCategoryValue() { 199 this.allCategoryIdArray = Utility.getCheckedData(this.categoryCheckBoxItems); 200 201 if (this.allCategoryIdArray.length) { 202 this.allCategoryId = Utility.getJoinedArray(this.allCategoryIdArray); 203 } 204 } 205 206 getFilterParam() { 207 this.categoryParamValue = Utility.getParam(CONFIG.CATEGORY_PARAM); 208 } 209 210 updateTriggerStatus() { 211 if (this.categoryParamValue) { 212 this.changeChecked(this.categoryParamValue); 213 } else { 214 const categoryCookie = Utility.getCookieValue(CONFIG.SELECT_CATEGORY_COOKIE_NAME); 215 const categoryCookieArray = Utility.getJoinedArray(JSON.parse(categoryCookie)); 216 217 this.changeChecked(categoryCookieArray); 218 } 219 } 220 221 changeChecked(value) { 222 let checkbox = null; 223 224 this.categoryCheckBoxItems.forEach((item) => { 225 item.checked = false; 226 }); 227 228 value.split(',').forEach((data) => { 229 if (data === '') { 230 return; 231 } 232 233 checkbox = this.categoryFilterTrigger.querySelector(`[value="${data}"]`); 234 235 if (checkbox) { 236 checkbox.checked = true; 237 } 238 }); 239 240 const allCategoryFilterTrigger = this.categoryFilterTrigger.querySelectorAll('[name="category"]:checked'); 241 242 if (this.categoryCheckBoxItems.length === allCategoryFilterTrigger.length) { 243 this.allCheckBoxItem.checked = true; 244 } else { 245 if (!allCategoryFilterTrigger.length) { 246 this.allCheckBoxItem.checked = false; 247 this.allCheckBoxItem.indeterminate = false; 248 } else { 249 this.allCheckBoxItem.checked = false; 250 this.allCheckBoxItem.indeterminate = true; 251 } 252 } 253 } 254 255 setSelectedData() { 256 const checkedItems = this.categoryFilterTrigger.querySelectorAll('[name="category"]:checked'); 257 let checkedValueArray = []; 258 let checkedValue = ''; 259 260 if (checkedItems.length) { 261 checkedValueArray = Utility.getCheckedData(checkedItems); 262 checkedValue = Utility.getJoinedArray(checkedValueArray); 263 this.filterModelsTypes.dataset.selectedCategory = checkedValue; 264 Utility.setCookie(CONFIG.SELECT_CATEGORY_COOKIE_NAME, JSON.stringify(checkedValueArray)); 265 } else { 266 this.filterModelsTypes.dataset.selectedCategory = ''; 267 Utility.setCookie(CONFIG.SELECT_CATEGORY_COOKIE_NAME, JSON.stringify(this.cookieArray)); 268 } 269 } 270 271 getApiUrl() { 272 const apiUrl = new URL(API_PATH.MODELS); 273 const newParam = new URLSearchParams(''); 274 const paramCategory = Utility.getParam(CONFIG.CATEGORY_PARAM); 275 276 newParam.set(CONFIG.SITE_API_PARAM, GLOBAL_SETTINGS.SITE_ID); 277 newParam.set(CONFIG.LANGUAGE_API_PARAM, GLOBAL_SETTINGS.SITE_LANG); 278 newParam.set(CONFIG.GROUP_API_PARAM, SETTINGS_ID.GROUP); 279 newParam.set(CONFIG.TYPE_API_PARAM, SETTINGS_ID.TYPE); 280 newParam.set(CONFIG.SERIES_API_PARAM, SETTINGS_ID.SERIES); 281 282 if (paramCategory) { 283 newParam.set(CONFIG.CATEGORY_PARAM, paramCategory); 284 } else { 285 const categoryCookie = Utility.getCookieValue(CONFIG.SELECT_CATEGORY_COOKIE_NAME); 286 const categoryCookieArray = Utility.getJoinedArray(JSON.parse(categoryCookie)); 287 288 if (categoryCookieArray) { 289 newParam.set(CONFIG.CATEGORY_PARAM, categoryCookieArray); 290 } else { 291 newParam.delete(CONFIG.CATEGORY_PARAM); 292 } 293 } 294 295 this.newApiUrl = `${apiUrl}${newParam.toString()}`; 296 297 return this.newApiUrl; 298 } 299 300 getApiData() { 301 const apiUrl = this.getApiUrl(); 302 303 fetch(apiUrl).then((response) => { 304 if (!response.ok) { 305 throw new Error('Network response was not OK'); 306 } else { 307 return response.json(); 308 } 309 }).then((data) => { 310 this.totalCount = data.totalCount ? data.totalCount : 0; 311 this.count = data.count ? data.count : 0; 312 this.discontinuedCount = data.discontinuedCount ? data.discontinuedCount : 0; 313 this.modelsObjArray = data.models.length ? data.models : []; 314 this.setProductsNumber(); 315 this.setModelsHtml(); 316 }).catch((error) => { 317 console.error(error); 318 }); 319 } 320 321 updateDiscontinued(element) { 322 this.disconCookie = Utility.getCookieValue('kpi_discon'); 323 324 if (this.disconCookie === '1') { 325 element.setAttribute('aria-hidden', 'false'); 326 } else { 327 element.setAttribute('aria-hidden', 'true'); 328 } 329 } 330 331 setModelsHtml() { 332 const fragment = doc.createDocumentFragment(); 333 334 this.modelsListTarget.innerHTML = ''; 335 336 if (this.modelsObjArray.length === 0) { 337 return; 338 } 339 340 this.modelsObjArray.forEach((modelObj) => { 341 const modelsClone = this.modelsTemplate.content.cloneNode(true); 342 343 this.modelElems = { 344 discontinued: modelsClone.querySelector(this.selectors.discontinuedTarget), 345 switchItemsTarget: modelsClone.querySelector(this.selectors.switchItemsTarget), 346 image: modelsClone.querySelector(this.selectors.imageTarget), 347 overviewLink: modelsClone.querySelector(this.selectors.overviewLinkTarget), 348 title: modelsClone.querySelector(this.selectors.titleTarget), 349 description: modelsClone.querySelector(this.selectors.descriptionTarget), 350 dialogButton: modelsClone.querySelector(this.selectors.dialogButtonTarget), 351 dialog: modelsClone.querySelector(this.selectors.dialogTarget), 352 dataSheetLink: modelsClone.querySelector(this.selectors.dataSheetLinkTarget), 353 cadLink: modelsClone.querySelector(this.selectors.cadLinkTarget), 354 manualsLink: modelsClone.querySelector(this.selectors.manualsLinkTarget) 355 }; 356 357 Utility.setElementText(this.modelElems.title, modelObj, MODELS_DATA.TITLE); 358 Utility.setElementText(this.modelElems.description, modelObj, MODELS_DATA.DESCRIPTION); 359 Utility.setElementLink(this.modelElems.overviewLink, modelObj, MODELS_DATA.OVERVIEW_LINK); 360 Utility.setElementLink(this.modelElems.dataSheetLink, modelObj, MODELS_DATA.DATA_SHEET_LINK); 361 Utility.setElementLink(this.modelElems.cadLink, modelObj, MODELS_DATA.DATA_CAD_LINK); 362 Utility.setElementLink(this.modelElems.manualsLink, modelObj, MODELS_DATA.MANUALS_LINK); 363 364 if (this.modelElems.discontinued) { 365 if (modelObj.hasOwnProperty(MODELS_DATA.DISCONTINUED) === false || !modelObj[MODELS_DATA.DISCONTINUED]) { 366 this.modelElems.discontinued.remove(); 367 this.modelElems.switchItemsTarget.removeAttribute('data-switch-items-target'); 368 } else { 369 this.updateDiscontinued(this.modelElems.switchItemsTarget); 370 } 371 } 372 373 if (this.modelElems.image) { 374 if (modelObj.hasOwnProperty(MODELS_DATA.THUMBNAIL) === false || Object.keys(modelObj[MODELS_DATA.THUMBNAIL]).length === 0) { 375 if (!modelObj[MODELS_DATA.THUMBNAIL].url) { 376 this.modelElems.image.remove(); 377 } else { 378 if (!modelObj[MODELS_DATA.THUMBNAIL].alt) { 379 this.modelElems.image.alt = ''; 380 } 381 } 382 } else { 383 this.modelElems.image.src = modelObj[MODELS_DATA.THUMBNAIL].url; 384 this.modelElems.image.alt = modelObj[MODELS_DATA.THUMBNAIL].alt; 385 } 386 } 387 388 if (this.modelElems.dialogButton && this.modelElems.dialog) { 389 if (modelObj.hasOwnProperty(MODELS_DATA.DIALOG_LINK) === false || !modelObj[MODELS_DATA.DIALOG_LINK]) { 390 this.modelElems.dialogButton.disabled = true; 391 this.modelElems.dialog.remove(); 392 } else { 393 this.modelElems.dialogButton.disabled = false; 394 this.modelElems.dialog.dataset.modelCardDimensionsTemplateUrlValue = modelObj[MODELS_DATA.DIALOG_LINK]; 395 } 396 } 397 398 fragment.appendChild(modelsClone); 399 }); 400 401 this.modelsListTarget.append(fragment); 402 } 403 404 setProductsNumber() { 405 if (!this.totalNumberTarget || !this.excludeDiscontinuedNumberTarget) { 406 return; 407 } 408 409 this.totalNumberTarget.textContent = this.count; 410 this.excludeDiscontinuedNumberTarget.textContent = this.count - this.discontinuedCount; 411 } 412 413 setMutationObserver() { 414 const observerConfig = { 415 attributes: true, 416 attributeOldValue: true 417 }; 418 419 const callback = (record) => { 420 record.forEach((data) => { 421 if (!data) { 422 return; 423 } 424 425 if ((data.attributeName === 'data-selected-category') && 426 (data.oldValue !== data.target.dataset.selectedCategory)) { 427 this.updateFilterParam(); 428 this.getApiData(); 429 } 430 }); 431 }; 432 433 const observer = new MutationObserver(callback.bind(this)); 434 435 observer.observe(this.filterModelsTypes, observerConfig); 436 } 437 438 updateFilterParam() { 439 const urlSearchParams = new URLSearchParams(win.location.search); 440 const categoryFilterDate = this.filterModelsTypes.dataset.selectedCategory; 441 const baseUrl = urlSearchParams.toString(); 442 const urlHash = location.hash; 443 444 if (categoryFilterDate) { 445 urlSearchParams.set(CONFIG.CATEGORY_PARAM, categoryFilterDate); 446 } else { 447 urlSearchParams.delete(CONFIG.CATEGORY_PARAM); 448 } 449 450 if (baseUrl === urlSearchParams.toString()) { 451 return; 452 } 453 454 if (urlSearchParams.toString() === '') { 455 history.pushState(null, null, location.pathname + urlHash); 456 } else { 457 history.pushState(null, null, `?${urlSearchParams.toString()}${urlHash}`); 458 } 459 } 460 } 461 462 doc.addEventListener('DOMContentLoaded', () => { 463 if (win.selectModelsTypeComplete === true) { 464 return; 465 } 466 467 const selectModelsType = new SelectModelsType(); 468 469 selectModelsType.init(); 470 win.selectModelsTypeComplete = true; 471 });
472})(window, document);
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.