See all offers
★ 40,000+ SATISFIED CUSTOMERS
★ 40,000+ SATISFIED CUSTOMERS
SPRING SALE: DISCOUNTS UP TO 60%
SPRING SALE: DISCOUNTS UP TO 60%
FREE SHIPPING
FREE SHIPPING
★ 40,000+ SATISFIED CUSTOMERS
SPRING SALE: DISCOUNTS UP TO 60%
FREE SHIPPING
★ 40,000+ SATISFIED CUSTOMERS
SPRING SALE: DISCOUNTS UP TO 60%
FREE SHIPPING
See all offers (3)
See all offers (3)
HOME
COLLECTIONS
WORLD CUP BALLS
BESTSELLERS
2025/26 KITS
RETRO
KIDS JERSEYS
LONGSLEEVE
SPECIAL JERSEYS
MYSTERY SHIRT
HOODIES
STUSSY JERSEYS
TRACKSUITS
POPULAR TEAMS
FC BARCELONA
REAL MADRID
FC BAYERN
ARSENAL
AJAX
LIVERPOOL
GALATASARAY
MANCHESTER UNITED
PSG
MANCHESTER CITY
NAPOLI
AC MILAN
INTER MILAN
PSV
CHELSEA
TOTTENHAM
ATLETICO MADRID
JUVENTUS
LEVERKUSEN
FEYENOORD
FIORENTINA
INTER MIAMI
COVENTRY CITY
BORUSSIA DORTMUND
HAMBURGER SV
FC SCHALKE 04
VFB STUTTGART
RB LEIPZIG
1. FSV MAINZ 05
1. FC KÖLN
INTER MIAMI
INTERNATIONAL
NETHERLANDS
GERMANY
BRAZIL
ARGENTINA
BELGIUM
SPAIN
PORTUGAL
ENGLAND
FRANCE
MOROCCO
ITALY
JAPAN
MEXICO
AUSTRIA
CANADA
UNITED STATES
ABOUT US
CONTACT
More links
Log in
Create an account
${(data.data && data.data.count) > 999 ? '999+' : (data.data && data.data.count)}
${(data.data && data.data.count) > 999 ? '999+' : (data.data && data.data.count)}
Search
HOME
COLLECTIONS
COLLECTIONS
WORLD CUP BALLS
BESTSELLERS
2025/26 KITS
RETRO
KIDS JERSEYS
LONGSLEEVE
SPECIAL JERSEYS
MYSTERY SHIRT
HOODIES
STUSSY JERSEYS
TRACKSUITS
POPULAR TEAMS
POPULAR TEAMS
FC BARCELONA
REAL MADRID
FC BAYERN
ARSENAL
AJAX
LIVERPOOL
GALATASARAY
MANCHESTER UNITED
PSG
MANCHESTER CITY
NAPOLI
AC MILAN
INTER MILAN
PSV
CHELSEA
TOTTENHAM
ATLETICO MADRID
JUVENTUS
LEVERKUSEN
FEYENOORD
FIORENTINA
INTER MIAMI
COVENTRY CITY
BORUSSIA DORTMUND
HAMBURGER SV
FC SCHALKE 04
VFB STUTTGART
RB LEIPZIG
1. FSV MAINZ 05
1. FC KÖLN
INTER MIAMI
INTERNATIONAL
INTERNATIONAL
NETHERLANDS
GERMANY
BRAZIL
ARGENTINA
BELGIUM
SPAIN
PORTUGAL
ENGLAND
FRANCE
MOROCCO
ITALY
JAPAN
MEXICO
AUSTRIA
CANADA
UNITED STATES
ABOUT US
CONTACT
Log in
${function() { if (data === undefined || typeof data !== 'string' || data == '') return ''; const searchEmpty = ("Your search for \"{test}\" did not yield any results.").replace('{test}', data); return `
View more
${searchEmpty}
`; }()}
Home
/
HOODIES
HOODIES
0 product
${function() { const product_total = data.total; const renderText = `{count} products`; if (product_total == 0) { return `0 product` } else if (product_total == 1) { return `1 product` } else { return renderText.replace('{count}', product_total) } }()}
Sorry, there are no products in this collection.
${function() { const freeAmount = 4999; const totalPrice = data?.total_price || data?.cart?.total_price || 0; const amountDiff = freeAmount - totalPrice; const percentDiff = (amountDiff > 0 ? (totalPrice / freeAmount * 100) : 100) + '%'; let tipText = `
Your order is free delivery
`; if (amountDiff > 0) { tipText = `
Spend
more and get free shipping!
`; } return `
${tipText}
`; }()}
${item.product_title}
${item.options.map(option => option.value).join(' / ')}
${(item.parsedProperties || []).map((propertie)=>{ if (propertie.isImage){ return `
${propertie.name}:
View image
` }else{ return `
${propertie.name}: ${propertie.value}
` } }).join('')}
*${item.quantity}
Free gift
${ (item.discount_applications || []).map(discount_item => { const discount_item_amount = discount_item.discount_amount || discount_item.amount || ''; return `
${discount_item.title}
(-
)
` }).join('') }
Remove
Cart
${ data.originData.message }
${function () { if (!data.originData) return ""; let { apply_scenario, discount_info, landing_page_info, threshold_category } = data.originData; const progressDom = `
`; const { mobile_layout, show_add_to_cart, show_discount_label } = landing_page_info.product_display; const isBXGY = discount_info.discount_type === "DT_CODE_BXGY"; const buyProductsDom = `
`; const obtainProductsDom = `
`; const is_obtain = threshold_category === 'THRESHOLD_CATEGORY_OBTAIN_PRODUCT' ? 'active' : ''; const tabsDom = `
${function(){ let liDom = ''; const items = [ { text: landing_page_info.product.buy_product.text, class: "", value: 1 }, { text: landing_page_info.product.obtain_product.text, class: "cart-coupon-code-modal-tab__obtain", value: 2, is_obtain } ]; for (item of items) { liDom += `
${ item.text }
` } return liDom; }()}
${buyProductsDom}
${obtainProductsDom}
`; return `
${progressDom} ${isBXGY ? tabsDom : `
${buyProductsDom}
`}
` }()}
const TAG = 'spz-custom-cart-coupon-code-utils'; class SpzCustomCartCouponCodeUtils extends SPZ.BaseElement { constructor(element) { super(element); } static deferredMount() { return false; } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { this.action_ = SPZServices.actionServiceForDoc(this.element); this.keepOpenGuardBound_ = false; this.registerAction('setSideBarHeight', this.setSideBarHeight_.bind(this)); this.onResize_ = this.setSideBarHeight_.bind(this); window.addEventListener('resize', this.onResize_); } detachedCallback() { if (this.onResize_) { window.removeEventListener('resize', this.onResize_); this.onResize_ = null; } } ensureKeepOpenGuard_($sideBar) { if (this.keepOpenGuardBound_) return; this.keepOpenGuardBound_ = true; const observer = new MutationObserver(() => { if ($sideBar.hasAttribute('open') && $sideBar.hasAttribute('hidden')) { $sideBar.removeAttribute('hidden'); this.setSideBarHeight_(); } }); observer.observe($sideBar, { attributes: true, attributeFilter: ['hidden', 'open'] }); } getOpenDrawer_() { return document.querySelector('[data-section-type="cart_drawer"] spz-sidebar[open]'); } setSideBarHeight_() { const $sideBar = document.querySelector('#cart-coupon-code-modal'); if (!$sideBar) return; this.ensureKeepOpenGuard_($sideBar); const windowHeight = window.innerHeight; const $drawer = this.getOpenDrawer_(); if (!$drawer) { $sideBar.style.setProperty('max-height', windowHeight * 0.9 + 'px', 'important'); $sideBar.style.removeProperty('height'); $sideBar.style.removeProperty('width'); $sideBar.classList.remove('cart-coupon-code-modal--in-drawer'); return; } const drawerHeight = (windowHeight - 40) + 'px'; $sideBar.style.setProperty('max-height', drawerHeight, 'important'); $sideBar.style.setProperty('height', drawerHeight, 'important'); $sideBar.classList.add('cart-coupon-code-modal--in-drawer'); const rect = $drawer.getBoundingClientRect(); if (rect.width > 0) { $sideBar.style.setProperty('width', rect.width + 'px', 'important'); } } } SPZ.defineElement(TAG, SpzCustomCartCouponCodeUtils);
${function(){ const settings_product_image_hover_on = true; const variantShowLimit = 4; const private_id = 'product-tmpl-' + Math.random().toFixed(6).slice(-6); const product_variants = data.variants || []; const product_id = data.id; const images = data.images || []; const image = data.image || {}; const imageWidth = image.width; let imageHeight = image.height; const price = Number(data.price_min); let compareAtPrice = Number(data.compare_at_price); const type = data.type; const isMock = data.isMock; let product_image_hover_on = false; for (item of product_variants) { const vcap = Number(item.compare_at_price); if (item.price == price && vcap > compareAtPrice) { compareAtPrice = vcap; } } let second_image = null; if (settings_product_image_hover_on) { for (img of images.slice(1)) { if (img.src && img.src.indexOf('video=') === -1) { second_image = img; product_image_hover_on = true; break; } } } const sold_label_on = !data.available; let sale_label_on = false; if (compareAtPrice > price && data.available) { sale_label_on = true; } const diffPrice = compareAtPrice - price; return `
${function(){ return `
` }() }
SOLD OUT
SALE
${data.title}
-
${data.available ? `
` : ''}
`; }()}
const carousel = document.getElementById('marketing-quick-view-images'); const selector = document.getElementById('marketing-quick-view-thumb-images'); const resizeObserver = new ResizeObserver(entries => { for (let entry of entries) { const { height } = entry.contentRect; selector.style.height = height + 'px'; } }); resizeObserver.observe(carousel);
${function(){ const variantsNamesSet = new Set(data.options.map((opt) => opt.name.toLowerCase()) || []); const handleName = (name) => name.replace(/\/|\\|\s|\'|\"|`|\<|\>/g, ''); const mouseoutevent = data.options.map((opt) => `@${handleName(opt.name)}Mouseout="qv-selected-render-${opt.id}.rerender(data=event,redo=true);"`).join(' '); const mouseoverevent = data.options.map((opt) => `@${handleName(opt.name)}Mouseover="qv-selected-render-${opt.id}.rerender(data=event,redo=true);"`).join(' '); const variants = data?.variants?.map((item) => item.image.path) || []; const productData = data; const images = data.images; const selectedVariant = data.variants.find(v => v.available) || data.variants[0]; const selectedIndex = !!selectedVariant ? images.findIndex(img => img.src === (selectedVariant.image && selectedVariant.image.src)) : 0; const initialSlide = selectedIndex === -1 ? 0 : selectedIndex; return `
${images.map((image, index) => `
`).join('')}
${images.map(image => `
`).join('')} ${images.length > 1 ? `
` : ''}
${data.title}
Price
${function() { const origin = "view"; const product = (origin === 'shop' ? data.product : data) || {}; const selectedVariant = product.variants.find(v => v.available) || product.variants[0]; return !!selectedVariant ? `
Save
` : `
-
`; }()}
Quantity
${selectedVariant.available ? "Add to cart" : "SOLD OUT"}
Buy it now
Product was out of stock.
Product is unavailable.
-
${function() { const MAX_INVENTORY = 999999; const product0 = Object.prototype.toString.call(data) == '[object Array]' ? data[0] : (data.product || data); const inventoryQty = product0.inventory_quantity; const inventoryPolicy = product0.inventory_policy; const inventoryTracking = product0.inventory_tracking; const lowStock = 5; const selectedVariant = product0.variants.find(v => v.available) || product0?.variants[0]; const selectedVariantAvailableQuantity = selectedVariant && selectedVariant.available_quantity; let actualInventory = inventoryQty; if ((inventoryTracking && inventoryPolicy == 'continue') || !inventoryTracking) { actualInventory = MAX_INVENTORY; } return `
Avaliability:
Product was out of stock.
in stock, ready to be shipped
Low stock
`; }()}
` }()}
${function(){ return (data.product.options || []).map((option, index) => { const optionName = option.name || ''; const optionId = option.id || ''; return `
${optionName}:
${data.selectedValues[optionName]}
${option.values.map((value,idx) => { const selected = data.selectedValues[optionName] == value ? 'checked' : ''; let thumbImage = null; return `
${value}
` }).join('')}
` }).join('') }()}
${function(){ const { currentOptName, originData: { selectData, value } } = data; const optionValue = selectData ? selectData[currentOptName].value[0] : value; return `
${optionValue}
` }()}
Save
-
${function(){ const productData = data.product; const selectedVariant = productData.variants.find(v => v.available) || productData.variants[0]; const product_options = productData.options.filter(Boolean) || []; const handleName = (name) => name.replace(/\/|\\|\s|\'|\"|`|\<|\>/g, ''); const mouseoutevent = productData.options.map((opt) => `@${handleName(opt.name)}Mouseout="qs-selected-render-${opt.id}.rerender(data=event,redo=true);"`).join(' '); const mouseoverevent = productData.options.map((opt) => `@${handleName(opt.name)}Mouseover="qs-selected-render-${opt.id}.rerender(data=event,redo=true);"`).join(' '); return `
Price
${function() { const origin = "shop"; const product = (origin === 'shop' ? data.product : data) || {}; const selectedVariant = product.variants.find(v => v.available) || product.variants[0]; return !!selectedVariant ? `
Save
` : `
-
`; }()}
Quantity
${selectedVariant.available ? "Add to cart" : "SOLD OUT"}
Buy it now
Product was out of stock.
Product is unavailable.
-
${function() { const MAX_INVENTORY = 999999; const product0 = Object.prototype.toString.call(data) == '[object Array]' ? data[0] : (data.product || data); const inventoryQty = product0.inventory_quantity; const inventoryPolicy = product0.inventory_policy; const inventoryTracking = product0.inventory_tracking; const lowStock = 5; const selectedVariant = product0.variants.find(v => v.available) || product0?.variants[0]; const selectedVariantAvailableQuantity = selectedVariant && selectedVariant.available_quantity; let actualInventory = inventoryQty; if ((inventoryTracking && inventoryPolicy == 'continue') || !inventoryTracking) { actualInventory = MAX_INVENTORY; } return `
Avaliability:
Product was out of stock.
in stock, ready to be shipped
Low stock
`; }()}
` }()}
${function(){ return (data.product.options || []).map((option, index) => { const optionName = option.name || ''; const optionId = option.id || ''; return `
${optionName}:
${data.selectedValues[optionName]}
${option.values.map((value,idx) => { const selected = data.selectedValues[optionName] == value ? 'checked' : ''; let thumbImage = null; return `
${value}
` }).join('')}
` }).join('') }()}
${function(){ const { currentOptName, originData: { selectData, value } } = data; const optionValue = selectData ? selectData[currentOptName].value[0] : value; return `
${optionValue}
` }()}
Save
-
const TAG = 'spz-custom-marketing-utils'; class SpzCustomMarketingUtils extends SPZ.BaseElement { constructor(element) { super(element); } static deferredMount() { return false; } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } mountCallback() { this.ensureToastInBody_('coupon-code-toast-wrap'); } showCouponCodeToast_(message) { this.ensureToastInBody_('coupon-code-toast-wrap'); const toastEl = document.getElementById('coupon-code-toast'); if (!toastEl) return; SPZ.whenApiDefined(toastEl).then((apis) => { apis.showToast(message); }); } ensureToastInBody_(id) { const wrapEl = document.getElementById(id); if (!wrapEl) return; if (!wrapEl.closest('[data-section-type="cart_drawer"]')) return; if (wrapEl.parentNode !== document.body) { document.body.appendChild(wrapEl); } } buildCallback() { this.registerAction('addToCartTrigger', (invocation) => { window.$ && $(document).trigger('dj.common.cart.change'); window.$ && $(document).trigger('dj.addToCart', invocation.event.detail); }); this.registerAction('showAddToCartToast', () => { this.showCouponCodeToast_("Added successfully"); }); } } SPZ.defineElement(TAG, SpzCustomMarketingUtils);
Discount code
Apply
${function(){ if (data.status === 'APPLY_STATUS_SUCCESS' || !data.message) { return `
` } return `
${data.originData.message}
Add
` }()}
${data.map( item => { return `
${item}
` }).join('')}
Below discount codes are unavailable
${data.map( item => { return `
${item}
` }).join('')}
${function(){ const code_data = data.originData.list; if (!code_data || !code_data.length) return ''; const recommendDom = `
Recommend discount codes
`; const discountCodeListDom = code_data.map( item => { item.end_at = item.end_at == -1 ? item.end_at : item.end_at * 1000; item.start_at *= 1000; return `
${item.discount_text}
-
${item.code}
` }).join(''); return `
${recommendDom}
${discountCodeListDom}
${recommendDom}
${discountCodeListDom}
` }()}
Add note
Write something here to seller.
${(data.data && data.data.note) ? data.data.note : (data.note || data.value || '')}
Discount
${data.total_discount > 0 ? '-' : ''}
Subtotal
Taxes and shipping calculated at checkout
Check out
Your shopping cart is empty
Continue shopping
You may also like
${ (function(){ const popupList = originData.popupList; return popupList?.length && popupList.map(item => { if(item.placement_template === "PT_POPUP_BUY_X_GET_Y"){ const parseConfig = item.parseConfig; const shopUrl = `https://${parseConfig.button.url}`; let modalSize = ''; if(+parseConfig.width.value <= 600){ modalSize = 'small'; } else if(+parseConfig.width.value > 600 && +parseConfig.width.value <= 800){ modalSize = 'middle'; } else { modalSize = 'large'; } const imagePosition = parseConfig.image.position; const wrapHeightMap = { small: 'min-height:360px;', middle: 'min-height:480px;', large: 'min-height:600px;' }; const image_size_top_map = { small: 'height:208px;', middle: 'height:295px;', large: 'height:346px;' }; const content_size_right_map = { small: 'padding-top: 68px;', middle: 'padding-top: 72px;', large: 'padding-top: 76px;' }; const content_size_top_map = { small: 'padding: 20px 16px;', middle: 'padding: 40px 16px;', large: 'padding: 40px 16px;' }; positionMap = { top: { imageStyle:`width:100%;${image_size_top_map[modalSize]}`, contentStyle:`margin-top:0;padding: 16px;${content_size_top_map[modalSize]}`, wrapStyle: 'flex-direction:column;', }, left: { imageStyle:'width:50%;height:100%;', contentStyle:`width:50%;padding:16px;${content_size_right_map[modalSize]}`, wrapStyle: 'flex-direction:row;', }, right: { imageStyle:'width:50%;height:100%;', contentStyle:'width:50%;padding:16px;margin-top:0;', wrapStyle: 'flex-direction:row-reverse;' }, none: { imageStyle:'display: none', contentStyle:'width:100%;', wrapStyle: 'width:100%;' } } const keys = ['text_title','text_content','button']; let sortKeys = []; parseConfig.section.forEach(item => { if(keys.includes(item)){ sortKeys.push(item) } }) const maskPercent = item.parseConfig.mask.value/100; const backgroundImgStyle = (parseConfig.background.url && parseConfig.background.upload) ? `background-image:url(//img.staticdj.com/${parseConfig.background.url});background-size: cover;background-repeat: no-repeat;background-position: center;` : ''; const backgroundColorStyle = `background-color:${parseConfig.background.color || '#ffffff'}`; return `
${sortKeys.map(key => { if(key == 'text_title'){ return `
${parseConfig.text_title.value}
` }else if(key == 'text_content'){ return `
${parseConfig.text_content.value}
` }else if(key == 'button'){ return `
${parseConfig.button.text}
${parseConfig.button.text}
` } }).join('')}
` }else{ return '' } }).join(''); })() }
(function () { const TAG = "spz-custom-discount-popup-bxgy"; class SpzCustomPlacementPopup extends SPZ.BaseElement { constructor(element) { super(element); this.deviceTypeMap = { PD_PC_MOBILE: "PD_PC_MOBILE", PD_PC: "PD_PC", PD_MOBILE: "PD_MOBILE" }; this.reportEventMap = { PE_IMPRESSION: 'PE_IMPRESSION',//曝光事件 PE_CLICK: 'PE_CLICK',//点击事件 } this.popup_z_index = 1050; } static deferredMount() { return false; } buildCallback = () => { this.action_ = SPZServices.actionServiceForDoc(this.element); this.templates_ = SPZServices.templatesForDoc(this.element); this.xhr_ = SPZServices.xhrFor(this.win); this.setupAction_(); this.viewport_ = this.getViewport(); } mountCallback = () => { } // 节流处理 每5s内多次点击 算一次点击上报 throttleReport = this.win.SPZCore.Types.throttle( this.win, (data) => { this.reportData(data) }, 5000 ) // 上报数据 reportData = async(data) => { const reqBody = { placement_id: data.placement_id, event: data.event } this.xhr_.fetchJson(`/api/storefront/promotion/placement/data/report`, { method: "post", body: reqBody }).then((res)=>{ // todo ... }) } doRender_ = (data) => { const popupList = data.popupList || []; if(popupList.length){ // 内容配置 序列化字符转化 popupList.forEach(item => { item.parseConfig = JSON.parse(item.config); }) } return this.templates_ .findAndRenderTemplate(this.element, {popupList}) .then((el) => { const children = this.element.querySelector('*:not(template)'); children && SPZCore.Dom.removeElement(children); this.element.appendChild(el); }).then(() =>{ popupList.forEach(item => { // buy x get y 弹窗渲染 this.showPopup(item); }) }) } showPopup = async(itemData) => { // 展示弹窗 符合展示条件的弹窗 const $lightbox_item = document.querySelector(`#popup_bxgy_${itemData.id}`); $lightbox_item && SPZ.whenApiDefined($lightbox_item).then((api)=> { const isPC = this.viewport_.getWidth() >= 768; const isMobile = this.viewport_.getWidth() < 768; const isMatchPCDevice = itemData.device === this.deviceTypeMap.PD_PC_MOBILE || itemData.device === this.deviceTypeMap.PD_PC; const isMatchMobileDevice = itemData.device == this.deviceTypeMap.PD_PC_MOBILE || itemData.device === this.deviceTypeMap.PD_MOBILE; if((isPC && isMatchPCDevice) || (isMobile && isMatchMobileDevice)) { // 根据推送时间 延迟展示弹窗 setTimeout(() => { $lightbox_item.style.zIndex = this.popup_z_index; this.popup_z_index ++; api.open(); }, itemData.delay_seconds * 1000); } }) } setupAction_ = () => { this.registerAction('handleTrack', async(invocation) => { // 如果是主题编辑器则不用处理 if(window.top !== window.self) { return; } const data = invocation.args; const event = data.event; // 点击上报 节流处理 if(event === this.reportEventMap.PE_CLICK) { await this.throttleReport(data); } else { this.reportData(data); } }); this.registerAction('handleLinkto', (invocation) => { const url = invocation.args.url; const isNewOpen = invocation.args.isNewOpen; const target = isNewOpen ? '_blank' : '_self'; if(url) { window.open(url, target); } }); } triggerEvent_(name, data) { const event = SPZUtils.Event.create(this.win, `${ TAG }.${ name }`, data || {}); this.action_.trigger(this.element, name, event); } isLayoutSupported(layout) { return layout == SPZCore.Layout.CONTAINER; } } SPZ.defineElement(TAG, SpzCustomPlacementPopup) })()
(function () { const TAG = "spz-custom-discount-placement"; class SpzCustomDiscountPlacement extends SPZ.BaseElement { constructor(element) { super(element); this.placementTypeMap = { PTT_POPUP: "PTT_POPUP", PTT_BANNER: "PTT_BANNER" }; this.placementTemplateMap = { PT_POPUP_BUY_X_GET_Y: "PT_POPUP_BUY_X_GET_Y", PT_BANNER_BUY_X_GET_Y: "PT_BANNER_BUY_X_GET_Y" }; this.progressMap = { PROGRESS_ONGOING: "PROGRESS_ONGOING", PROGRESS_NOT_STARTED: "PROGRESS_NOT_STARTED", PROGRESS_FINISHED: "PROGRESS_FINISHED", PROGRESS_PAUSED: "PROGRESS_PAUSED" }; } static deferredMount() { return false; } buildCallback = () => { this.action_ = SPZServices.actionServiceForDoc(this.element); this.templates_ = SPZServices.templatesForDoc(this.element); this.xhr_ = SPZServices.xhrFor(this.win); this.setupAction_(); this.viewport_ = this.getViewport(); } mountCallback = () => { this.handlePlacement(); } // 上报数据 reportData = async(data) => { const reqBody = { placement_id: data.placement_id, event: data.event } const url = `/api/storefront/promotion/placement/data/report`; this.xhr_.fetchJson(url, { method: "post", body: reqBody }).then((res)=>{ // todo ... }) } // 资源位数据获取 getplacementList = async() => { const reqBody = { page_id: window.SHOPLAZZA.meta.page.template_type } const url = `/api/storefront/promotion/placement/list` const data = await this.xhr_.fetchJson(url, { method: "post", body: reqBody }) return data; } handlePlacement = async() => { const res = await this.getplacementList(); const BXGYPopupList = res.list.filter(item => (item.placement_type == this.placementTypeMap.PTT_POPUP && item.placement_template == this.placementTemplateMap.PT_POPUP_BUY_X_GET_Y)); if(BXGYPopupList.length) { const $spz_custom_popup_bxgy = document.querySelector('#spz_custom_popup_bxgy'); SPZ.whenApiDefined($spz_custom_popup_bxgy).then((api)=> { api.doRender_({popupList: BXGYPopupList}); }) } } doRender_ = (data) => { const renderData = data || {}; return this.templates_ .findAndRenderTemplate(this.element, renderData) .then((el) => { const children = this.element.querySelector('*:not(template)'); children && SPZCore.Dom.removeElement(children); this.element.appendChild(el); }) } setupAction_ = () => { this.registerAction('handleTrack', (invocation) => { const data = invocation.args; this.reportData(data) }); } triggerEvent_(name, data) { const event = SPZUtils.Event.create(this.win, `${ TAG }.${ name }`, data || {}); this.action_.trigger(this.element, name, event); } isLayoutSupported(layout) { return layout == SPZCore.Layout.CONTAINER; } } SPZ.defineElement(TAG, SpzCustomDiscountPlacement) })()
${function() { const force_image_size = "1"; const product_hover_on = true; const product_show_sale_label = false; const product_save_type = "amount"; const badge1 = ""; const badge2 = ""; const badge3 = ""; const product_title_mobile_hide = false; const product_title_style = "full"; const enable_collection_thumb_image = true; const variantNames = ["color"]; const thumbMaxNum = 4; const suffix_id = Math.random().toFixed(6).slice(-6); const url = data.withinUrl; const productId = data.id; const price = data.price; const productAvailable = data.available; const productVariants = data.variants || []; const images = data.images || []; const image = data.image || {}; const imageWidth = image.width; let imageHeight = image.height; let image2 = data.secondImage; let imageHoverOn = !!image2.src; if (force_image_size !== 'natural') { imageHeight = imageWidth * force_image_size; } let compareAtPrice = data.compare_at_price; let offRatio = data.off_ratio; let discountMaxUrl = url; const showFrom = data.price_min != data.price_max ? true : false; for (let i = 0; i < productVariants.length; i++) { const variant = productVariants[i]; if (variant.price == price && compareAtPrice < variant.compare_at_price) { compareAtPrice = variant.compare_at_price; offRatio = variant.off_ratio; variant.available && (discountMaxUrl = variant.withinUrl); } } const soldOutText = "Sold out"; let soldOn = false; let saleOn = false; if (productAvailable) { if (product_show_sale_label && +price < +compareAtPrice) { saleOn = true; } } else { soldOn = true; } const diffPrice = compareAtPrice - price; const saveLabelContent = product_save_type == 'percent' ? (offRatio + '%') : `
`; let saveText = "Save {off_ratio}"; saveText = saveText.replace('{off_ratio}', saveLabelContent); const productTitle = data.title; const variantValues = []; const showVariants = []; if (data.need_variant_image && enable_collection_thumb_image && variantNames.length > 0) { for (let i = 0; i < (data.options || []).length; i++) { const option = data.options[i]; const optionName = option.name.toLowerCase(); if (variantNames.includes(optionName)) { for (let j = 0; j < productVariants.length; j++) { const variant = productVariants[j]; const value = variant.options[i].value; if (!variantValues.includes(value)) { variantValues.push(value); showVariants.push(variant); } } break; } } } return `
${saleOn ? saveText : soldOutText}
${badge1}
${badge2}
${badge3}
${ "title" === 'subtitle' ? data.brief : data.title }
From
${saveText}
${showVariants.map((item, idx) => { let showMoreHtml = ''; if (idx == thumbMaxNum) { showMoreHtml += `
+${showVariants.length - thumbMaxNum}
`; } return ` ${showMoreHtml}
`; }).join('') }
`; }()}
${function() { const defaultSelectedVariant = data.variants.find(v => v.available) || data.variants[0]; const defaultIndex = !!defaultSelectedVariant ? data.images.findIndex(img => img.src == (defaultSelectedVariant.image && defaultSelectedVariant.image.src)) : -1; const initialSlide = defaultIndex == -1 ? 0 : defaultIndex; const attrs = data.images.length > 1 ? 'slide controls' : ''; return `
`; }()}
${data.title}
${data.brief}
${function() { const defaultSelectedVariant = data.variants.find(v => v.available) || data.variants[0]; return `
${("Save {off_ratio}").replace('{off_ratio}', ("amount") == 'percent' ? defaultSelectedVariant.off_ratio + '%' : `
` )}
-
`; }()}
${function(){ const defaultSelectedVariant = data.variants.find(v => v.available) || data.variants[0]; let status_lan = "Add to cart"; if ((defaultSelectedVariant && !defaultSelectedVariant.available) || (!defaultSelectedVariant && !data.available)) { status_lan = "Sold out"; } return `
Quantity
${status_lan}
Buy now
` }()}
${function() { return data.product.options.map((option, index) => { const optionName = option.name || ''; const optionId = option.id || ''; let isThumbImage = !!option.showThumbImage; const thumbStyle = "image_with_text"; const thumbType = isThumbImage ? thumbStyle.replace(/_/g, '-') : 'text'; const variantType = null; const selectedVariantVal = data.selectedOptions && data.selectedOptions.length && data.selectedOptions.find(v => v.name === optionName).value[0] || ''; const isSelected = (value) => { const selected = (data.selectedOptions || []).find(v => v.name === optionName); return selected && selected.value.length && selected.value[0] == value; }; const getThumbImage = (value) => { const options = data.product.options || []; const option = options.find(o => o.name === optionName); if (option.thumbImages) { const thumbImage = option.thumbImages.find(t => t.value === value); if (thumbImage && thumbImage.image) { return { src: thumbImage.image.src, alt: thumbImage.image.alt }; } } return {src: '', alt: ''}; }; return `
${optionName.slice(0, 1).toUpperCase() + optionName.slice(1).toLowerCase()} :
${selectedVariantVal}
${option.values.map((value, idx) => { return `
${value}
${value}
` }).join('')}
`; }).join(''); }()}
${data.value || ''}
${("Save {off_ratio}").replace('{off_ratio}', ("amount") == 'percent' ? data.variant.off_ratio + '%' : `
` )}
-
-