https://www.alliedelectronics.com/mm5/json.mvc?Store_Code=Allied04…=mmx-category-carousel&T=9fc2de2b
1/** 2 * MMX / CATEGORY CAROUSEL 3 */ 4class MMX_CategoryCarousel extends MMX_Element { 5 6 static get props() { 7 let props = MMX.assign(MMX_CategoryCarousel.carouselProps, MMX_HeroSlider.props); 8 props['gap'].default = 32; 9 props['per-page'].default = '1,3,5'; 10 props['arrow-style'].default = 'button'; 11 props['nav-position'].default = 'none'; 12 props['wrap'].default = false; 13 props['autoplay'].default = false; 14 return props; 15 } 16 17 static carouselProps = { 18 'fallback-image': { 19 allowAny: true 20 }, 21 'image-fit': { 22 allowAny: true, 23 options: [ 24 'cover', 25 'contain', 26 'fill', 27 'none', 28 'scale-down' 29 ], 30 default: 'contain' 31 } 32 }; 33 34 styleResourceCodes = ['mmx-base', 'mmx-button', 'mmx-hero', 'mmx-hero-slider']; 35 loadedCategories = {}; 36 categories = []; 37 38 constructor() { 39 super(); 40 this.makeComponent(); 41 this.bindRevealElement(); 42 } 43 44 render() { 45 return /*html*/` 46 <div part="wrapper" class="mmx-category-carousel"> 47 <div part="title" class="mmx-category-carousel__title"> 48 <slot name="title"></slot> 49 </div> 50 ${this.renderCategories()} 51 </div> 52 `; 53 } 54 55 styles() { 56 return /*css*/` 57 slot[name="title"]::slotted(*) { 58 margin: 0 auto 3%; 59 } 60 `; 61 } 62 63 onDataChange() { 64 MMX.setElementAttributes(this, { 65 'data-per-page': this.data?.advanced?.slide_controls?.per_page?.value, 66 'data-per-move': this.data?.advanced?.slide_controls?.per_move?.value, 67 'data-peek': this.data?.advanced?.slide_controls?.peek?.value, 68 'data-size': this.data?.category_group?.image_size?.value, 69 'data-image-fit': this.data?.category_group?.image_fit?.value 70 }); 71 72 this.displayCategories(); 73 } 74 75 displayCategories() { 76 if (this.data?.category_group?.source?.value === 'manual') this.loadCategories(); 77 else if (this.data?.category_group?.source?.value === 'ids') this.loadCategoriesByIds(); 78 else this.loadChildCategories(); 79 } 80 81 loadCategoriesByIds() { 82 const categoryIds = this.data?.category_group?.categories?.ids ?? []; 83 84 if (MMX.arrayIsEmpty(categoryIds)) { 85 return; 86 } 87 88 this.categories = []; 89 this.setLifecycleReady(false); 90 91 const imageEnabled = this.data?.category_group?.category_image?.settings?.enabled; 92 const filters = [ 93 { 94 name: 'search', 95 value: [ 96 { 97 field: 'id', 98 operator: 'IN', 99 value: categoryIds 100 } 101 ] 102 } 103 ]; 104 105 if (imageEnabled) { 106 filters.push({ 107 name: 'ondemandcolumns', 108 value: [ 109 'CustomField_Values:cmp-cssui-cattitle:category_title_image', 110 'CustomField_Values:cmp-cssui-cattree:category_tree_image' 111 ] 112 }); 113 } 114 115 MMX.Runtime_JSON_API_Call({ 116 params: { 117 Function: 'Runtime_CategoryList_Load_Query', 118 Filter: filters 119 } 120 }) 121 .then(response => this.#onCategoriesLoaded(response?.data?.data, categoryIds)) 122 .catch(response => {}); 123 } 124 125 #getCategoriesToLoad() { 126 const children = this?.data?.category_group?.categories?.children; 127 128 if (!children?.length) { 129 return []; 130 } 131 132 return children.reduce((categories, child) => { 133 const category = child?.category?.category; 134 const code = category?.code; 135 136 if (!MMX.valueIsEmpty(code) && categories.findIndex(item => item.code === code) === -1 && MMX.isTruthy(child?.image?.category_image?.settings?.enabled)) { 137 categories.push(category); 138 } 139 140 return categories; 141 }, []); 142 } 143 144 getCategoryCodesToLoad() { 145 const categories = this.#getCategoriesToLoad(); 146 147 if (!categories?.length) { 148 return undefined; 149 } 150 151 return categories.map(category => category.code); 152 } 153 154 loadCategories() { 155 const categoryCodes = this.getCategoryCodesToLoad(); 156 157 if (!categoryCodes?.length) { 158 return; 159 } 160 161 this.setLifecycleReady(false); 162 163 MMX.Runtime_JSON_API_Call({ 164 params: { 165 Function: 'Runtime_CategoryList_Load_Query', 166 Filter: [ 167 { 168 name: 'search', 169 value: [ 170 { 171 field: 'code', 172 operator: 'IN', 173 value: categoryCodes 174 } 175 ] 176 }, 177 { 178 name: 'ondemandcolumns', 179 value: [ 180 'CustomField_Values:cmp-cssui-cattitle:category_title_image', 181 'CustomField_Values:cmp-cssui-cattree:category_tree_image' 182 ] 183 }, 184 ...MMX.cacheKeysFilters(this.#getCategoriesToLoad()) 185 ] 186 } 187 }) 188 .then(response => { 189 if(!response?.data?.data?.length) { 190 return; 191 } 192 193 response.data.data.forEach(category => { 194 this.loadedCategories[category.id] = category; 195 }); 196 197 this.forceUpdate(); 198 }) 199 .catch(response => {}); 200 } 201 202 loadChildCategories() { 203 if (MMX.valueIsEmpty(this?.data?.category_id)) { 204 return; 205 } 206 207 var filters = []; 208 209 if (this.data?.category_group?.category_image?.settings?.enabled) { 210 filters = [ 211 { 212 name: 'ondemandcolumns', 213 value: [ 214 'CustomField_Values:cmp-cssui-cattitle:category_title_image', 215 'CustomField_Values:cmp-cssui-cattree:category_tree_image' 216 ] 217 } 218 ]; 219 } 220 221 filters.push(...MMX.cacheKeysFilters(this.data?.category)); 222 223 this.categories = []; 224 this.setLifecycleReady(false); 225 226 MMX.Runtime_JSON_API_Call({ 227 params: { 228 Function: 'Runtime_CategoryList_Load_Query', 229 Parent_ID: this.data.category_id, 230 Filter: filters 231 } 232 }) 233 .then(response => this.#onCategoriesLoaded(response?.data?.data)) 234 .catch(response => {}); 235 } 236 237 #onCategoriesLoaded(categories = [], orderedIds = null) { 238 if (!categories.length) { 239 return; 240 } 241
242 categories.forEach(category => { 243 this.loadedCategories[category.id] = category; 244 }); 245 246 const ordered = orderedIds 247 ? orderedIds.map(id => this.loadedCategories[id]).filter(Boolean) 248 : categories; 249 250 ordered.forEach(category => { 251 this.categories.push(this.#buildCategoryItem(category)); 252 }); 253 254 this.forceUpdate(); 255 } 256 257 #buildCategoryItem(category) { 258 return { 259 category: { 260 category: { 261 link: category.url, 262 ...category, 263 }, 264 category_code: category.code 265 }, 266 image: { 267 category_image: { 268 image: { 269 value: this.data?.category_group?.category_image?.image?.value 270 }, 271 settings: { 272 enabled: this.data?.category_group?.category_image?.settings?.enabled 273 } 274 } 275 } 276 }; 277 } 278 279 renderCategories() { 280 var children; 281 282 if (this.data?.category_group?.source?.value === 'auto' || this.data?.category_group?.source?.value === 'ids') 283 { 284 children = this.categories; 285 } 286 else 287 { 288 children = MMX.copy(this?.data?.category_group?.categories?.children || []); 289 } 290 291 if (!children?.length) { 292 return ''; 293 } 294 295 return /*html*/` 296 <mmx-hero-slider 297 part="slider" 298 data-per-page="${this.getPropValue('per-page')}" 299 data-per-move="${this.getPropValue('per-move')}" 300 data-peek="${this.getPropValue('peek')}" 301 data-gap="${this.getPropValue('gap')}" 302 data-size="${this.getPropValue('size')}" 303 data-autoplay="${this.getPropValue('autoplay')}" 304 data-delay="${this.getPropValue('delay')}" 305 data-pause-on-hover="${this.getPropValue('pause-on-hover')}" 306 data-arrow-style="${this.getPropValue('arrow-style')}" 307 data-nav-position="${this.getPropValue('nav-position')}" 308 data-nav-button-size="${this.getPropValue('nav-button-size')}" 309 data-wrap="${this.getPropValue('wrap')}" 310 > 311 ${children.map(child => this.renderCategory(child)).join('')} 312 </mmx-hero-slider> 313 `; 314 } 315 316 renderCategory(child) { 317 // Skip unavailable/inactive categories 318 if(!child?.category?.category?.id) { 319 return ''; 320 } 321 322 const theme_available = this.data?.text_styles?.category_name?.typography_theme?.theme_available; 323 324 return /*html*/` 325 <mmx-hero 326 slot="hero_slide" 327 part="hero_slide" 328 data-fit="${MMX.encodeEntities(this.getPropValue('image-fit'))}" 329 data-href="${MMX.encodeEntities(child.category.category.link)}" 330 > 331 ${this.renderCategoryImage(child)} 332 <mmx-text 333 slot="heading" 334 part="hero_slide__heading" 335 data-theme="${MMX.encodeEntities(theme_available)}" 336 data-theme-class="${MMX.encodeEntities(this.data?.text_styles?.category_name?.typography_theme?.classname ?? '')}" 337 data-style="${this.data?.text_styles?.category_name?.style?.value ?? ''}" 338 data-align="${this.data?.text_styles?.align?.value ?? ''}" 339 > 340 ${this.renderLegacyStylesTemplate(theme_available, this.getStylesFromGroup(this.data?.text_styles?.category_name))} 341 ${this.renderThemeStylesheetTemplate(theme_available)} 342 ${child.category.category.name} 343 </mmx-text> 344 </mmx-hero> 345 `; 346 } 347 348 renderCategoryImage(child) { 349 let mobileSource = ''; 350 let tabletSource = ''; 351 352 child.image.url = this.getPropValue('fallback-image'); 353 354 // Custom Images 355 if (MMX.isTruthy(child?.image?.custom_image?.settings?.enabled) && child?.image?.custom_image?.image?.image?.length ) { 356 child.image.url = child.image.custom_image.image.image; 357 358 const mobileImage = this.#getResponsiveImageData('mobile', child?.image?.custom_image?.image); 359 360 if (mobileImage) { 361 mobileSource = /*html*/`<source 362 class="source__mobile" 363 media="(max-width: 39.999em)" 364 srcset="${MMX.encodeEntitiesURI(mobileImage.image)}" 365 width="${MMX.encodeEntities(mobileImage.width)}" 366 height="${MMX.encodeEntities(mobileImage.height)}" 367 >`; 368 } 369 370 const tabletImage = this.#getResponsiveImageData('tablet', child?.image?.custom_image?.image); 371 372 if (tabletImage) { 373 tabletSource = /*html*/`<source 374 class="source__tablet" 375 media="(max-width: 59.999em)" 376 srcset="${MMX.encodeEntitiesURI(tabletImage.image)}" 377 width="${MMX.encodeEntities(tabletImage.width)}" 378 height="${MMX.encodeEntities(tabletImage.height)}" 379 >`; 380 } 381 } 382 // Category Image (tree or title) 383 else if (MMX.isTruthy(child?.image?.category_image?.settings?.enabled)) { 384 const loadedCategory = this.loadedCategories[child.category.category.id]; 385 if (child?.image?.category_image?.image?.value === 'cattitle' && loadedCategory?.CustomField_Values?.['cmp-cssui-cattitle']?.category_title_image?.length) { 386 child.image.url = loadedCategory.CustomField_Values['cmp-cssui-cattitle'].category_title_image; 387 } 388 else if (child?.image?.category_image?.image?.value === 'cattree' && loadedCategory?.CustomField_Values?.['cmp-cssui-cattree']?.category_tree_image?.length) { 389 child.image.url = loadedCategory.CustomField_Values['cmp-cssui-cattree'].category_tree_image; 390 } 391 } 392 393 if(!child.image.url?.length) { 394 return ''; 395 } 396 397 return /*html*/` 398 <picture 399 slot="image" 400 part="hero_slide__image" 401 > 402 ${mobileSource} 403 ${tabletSource} 404 <img 405 src="${MMX.encodeEntitiesURI(child.image.url)}" 406 alt="${MMX.encodeEntities(child.image.custom_image?.image?.alt)}" 407 width="${MMX.encodeEntities(child.image.custom_image?.image?.width)}" 408 height="${MMX.encodeEntities(child.image.custom_image?.image?.height)}" 409 ${this.getLoadingAttributeString()} 410 > 411 </picture> 412 `; 413 } 414 415 #getResponsiveImageData(device, image) { 416 const responsiveImageData = image?.responsive_image_data?.[device]; 417 const responsiveImage = image?.responsive_images?.[device]; 418 419 if (!MMX.valueIsEmpty(responsiveImageData?.image)) { 420 return responsiveImageData; 421 } 422 else if (!MMX.valueIsEmpty(responsiveImage)) { 423 return { 424 image: responsiveImage 425 }; 426 } 427 else { 428 return undefined; 429 } 430 } 431 432 slider() { 433 return this.shadowRoot.querySelector('[part~="slider"]'); 434 } 435 436 revealElement(element) { 437 this.slider()?.revealElement(element); 438 } 439} 440 441if (!customElements.get('mmx-category-carousel')) { 442 customElements.define('mmx-category-carousel', MMX_CategoryCarousel); 443}
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.