๐จ๐ง๐2-in-1 Measuring and Miter Saw Tool
${function() {
const variantData = data.variant || {"id":"1b5fa543-d8bf-48d7-b7dd-a0a3b7278a36","product_id":"c4fd035b-e26f-4375-9d9b-8594574106d1","title":"Buy 1","weight_unit":"kg","inventory_quantity":1000,"sku":"A002105415--Buy 1","barcode":"","position":1,"option1":"Buy 1","option2":"","option3":"","note":"","image":{"src":"\/\/img.staticdj.com\/b2ec1de6ca7e574b48276dc24d6a8b7f.png","path":"b2ec1de6ca7e574b48276dc24d6a8b7f.png","width":800,"height":800,"alt":"","aspect_ratio":1},"wholesale_price":[{"price":29.99,"min_quantity":1}],"weight":"0","compare_at_price":"27.99","price":"29.99","retail_price":"27.99","available":true,"url":"\/products\/miter-saw-tool-uk?variant=1b5fa543-d8bf-48d7-b7dd-a0a3b7278a36","available_quantity":999999999,"options":[{"name":"Qty","value":"Buy 1"}],"off_ratio":"0","flashsale_info":{"variant_id":"1b5fa543-d8bf-48d7-b7dd-a0a3b7278a36","product_id":"","quantity":0,"discount_id":"","limit_time":0,"limit_buy":0,"user_limit_buy":0,"discount_sales":0,"discount_sales_rate":"","discount_stock":0,"ends_at":0,"starts_at":0,"allow_oversold":"","allocation_method":"","price":"29.99","compare_at_price":"","discount_price":"29.99","customary_saved_price":"","customary_off_ratio":"","discount_saved_price":"","discount_off_ratio":"0","use_before_price":false,"before_price":"","title":"","properties":"","color_setting_promotional_copy":"","discount_quantity":0,"is_need_split":false},"sales":0};
const saveType = "amount";
const productLabelDiscountOn = false;
return `
-
${saveType == 'percentage'
? `-${variantData.off_ratio}%`
: `-`
}
`;
}()}
const TAG = "spz-custom-product-automatic";
class SpzCustomProductAutomatic extends SPZ.BaseElement {
constructor(element) {
super(element);
this.variant_id = '1b5fa543-d8bf-48d7-b7dd-a0a3b7278a36';
this.isRTL = SPZ.win.document.dir === 'rtl';
this.isAddingToCart_ = false; // ๅ ่ดญไธญ็ถๆ
}
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.init();
// ็ๅฌไบไปถ
this.bindEvent_();
}
async init() {
this.handleFitTheme();
const data = await this.getDiscountList();
this.renderApiData_(data);
}
async getDiscountList() {
const productId = 'c4fd035b-e26f-4375-9d9b-8594574106d1';
const variantId = this.variant_id;
const productType = 'default';
const reqBody = {
product_id: productId,
variant_id: variantId,
discount_method: "DM_AUTOMATIC",
customer: {
customer_id: window.C_SETTINGS.customer.customer_id,
email: window.C_SETTINGS.customer.customer_email
},
product_type: productType
}
const url = `/api/storefront/promotion/display_setting/text/list`;
const data = await this.xhr_.fetchJson(url, {
method: "post",
body: reqBody
}).then(res => {
return res;
}).catch(err => {
this.setContainerDisabled(false);
})
return data;
}
async renderDiscountList() {
this.setContainerDisabled(true);
const data = await this.getDiscountList();
this.setContainerDisabled(false);
// ้ๆฐๆธฒๆ ๆๅจ้ฎ้ขๅค็
this.renderApiData_(data);
}
clearDom() {
const children = this.element.querySelector('*:not(template)');
children && SPZCore.Dom.removeElement(children);
}
async renderApiData_(data) {
const parentDiv = document.querySelector('.automatic_discount_container');
const newTplDom = await this.getRenderTemplate(data);
if (parentDiv) {
parentDiv.innerHTML = '';
parentDiv.appendChild(newTplDom);
} else {
console.log('automatic_discount_container is null');
}
}
doRender_(data) {
const renderData = data || {};
return this.templates_
.findAndRenderTemplate(this.element, renderData)
.then((el) => {
this.clearDom();
this.element.appendChild(el);
});
}
async getRenderTemplate(data) {
const renderData = data || {};
return this.templates_
.findAndRenderTemplate(this.element, { ...renderData, isRTL: this.isRTL })
.then((el) => {
this.clearDom();
return el;
});
}
setContainerDisabled(isDisable) {
const automaticDiscountEl = document.querySelector('.automatic_discount_container_outer');
if(isDisable) {
automaticDiscountEl.setAttribute('disabled', '');
} else {
automaticDiscountEl.removeAttribute('disabled');
}
}
// ็ปๅฎไบไปถ
bindEvent_() {
window.addEventListener('click', (e) => {
let containerNodes = document.querySelectorAll(".automatic-container .panel");
let bool;
Array.from(containerNodes).forEach((node) => {
if(node.contains(e.target)){
bool = true;
}
})
// ๆฏๅฆpopover้ขๆฟ็นๅป่ๅด
if (bool) {
return;
}
if(e.target.classList.contains('drowdown-icon') || e.target.parentNode.classList.contains('drowdown-icon')){
return;
}
const nodes = document.querySelectorAll('.automatic-container');
Array.from(nodes).forEach((node) => {
node.classList.remove('open-dropdown');
})
// ๅ
ผๅฎนไธป้ข
this.toggleProductSticky(true);
})
// ็ๅฌๅไฝๅๅ
document.addEventListener('dj.variantChange', async(event) => {
// ้ๆฐๆธฒๆ
const variant = event.detail.selected;
if (variant.product_id == 'c4fd035b-e26f-4375-9d9b-8594574106d1' && variant.id != this.variant_id) {
this.variant_id = variant.id;
this.renderDiscountList();
}
});
}
// ๅ
ผๅฎนไธป้ข
handleFitTheme() {
// top ๅฑๆงๅฝฑๅๆๅจ
let productInfoEl = null;
if (window.SHOPLAZZA.theme.merchant_theme_name === 'Wind' || window.SHOPLAZZA.theme.merchant_theme_name === 'Flash') {
productInfoEl = document.querySelector('.product-info-body .product-sticky-container');
} else if (window.SHOPLAZZA.theme.merchant_theme_name === 'Hero') {
productInfoEl = document.querySelector('.product__info-wrapper .properties-content');
}
if(productInfoEl){
productInfoEl.classList.add('force-top-auto');
}
}
// ๅ
ผๅฎน wind/flash /hero ไธป้ข (stickyๅฑๆงๅฝฑๅ popover ๅฑ็บงๅฑ็คบ, ไผ่ขซๅ
ถไปๅ
็ด ่ฆ็)
toggleProductSticky(isSticky) {
let productInfoEl = null;
if (window.SHOPLAZZA.theme.merchant_theme_name === 'Wind' || window.SHOPLAZZA.theme.merchant_theme_name === 'Flash') {
productInfoEl = document.querySelector('.product-info-body .product-sticky-container');
} else if (window.SHOPLAZZA.theme.merchant_theme_name === 'Hero') {
productInfoEl = document.querySelector('.product__info-wrapper .properties-content');
}
if(productInfoEl){
if(isSticky) {
// ่ฟๅ่ฏฅไธป้ขๅๆ็stickyๅฑๆงๅผ
productInfoEl.classList.remove('force-position-static');
return;
}
productInfoEl.classList.toggle('force-position-static');
}
}
setupAction_() {
this.registerAction('handleDropdown', (invocation) => {
const discount_id = invocation.args.discount_id;
const nodes = document.querySelectorAll('.automatic-container');
Array.from(nodes).forEach((node) => {
if(node.getAttribute('id') != `automatic-${discount_id}`) {
node.classList.remove('open-dropdown');
}
})
const $discount_item = document.querySelector(`#automatic-${discount_id}`);
$discount_item && $discount_item.classList.toggle('open-dropdown');
// ๅ
ผๅฎนไธป้ข
this.toggleProductSticky();
});
// ๅ ่ดญไบไปถ
this.registerAction('handleAddToCart', (invocation) => {
// ้ปๆญขไบไปถๅๆณก
const event = invocation.event;
if (event) {
event.stopPropagation();
event.preventDefault();
}
// ๅฆๆๆญฃๅจๅ ่ดญไธญ๏ผ็ดๆฅ่ฟๅ
if (this.isAddingToCart_) {
return;
}
const quantity = invocation.args.quantity || 1;
this.addToCart(quantity);
});
}
// ๅ ่ดญๆนๆณ
async addToCart(quantity) {
// ่ฎพ็ฝฎๅ ่ดญไธญ็ถๆ
this.isAddingToCart_ = true;
const productId = 'c4fd035b-e26f-4375-9d9b-8594574106d1';
const variantId = this.variant_id;
const url = '/api/cart';
const reqBody = {
product_id: productId,
variant_id: variantId,
quantity: quantity
};
try {
const data = await this.xhr_.fetchJson(url, {
method: 'POST',
body: reqBody
});
// ่งฆๅๅ ่ดญๆๅๆ็คบ
this.triggerAddToCartToast_();
return data;
} catch (error) {
error.then(err=>{
this.showToast_(err?.message || err?.errors?.[0] || 'Unknown error');
})
} finally {
// ๆ ่ฎบๆๅๅคฑ่ดฅ๏ผ้ฝ้็ฝฎๅ ่ดญ็ถๆ
this.isAddingToCart_ = false;
}
}
showToast_(message) {
const toastEl = document.querySelector("#apps-match-drawer-add_to_cart_toast");
if (toastEl) {
SPZ.whenApiDefined(toastEl).then((apis) => {
apis.showToast(message);
});
}
}
// ่งฆๅๅ ่ดญๆๅๆ็คบ
triggerAddToCartToast_() {
// ๅฆๆไธป้ขๆ่ชๅทฑ็ๅ ่ดญๆ็คบ๏ผๅไธๆพ็คบ
const themeAddToCartToastEl = document.querySelector('#add-cart-event-proxy');
if (themeAddToCartToastEl) return;
// ๆพ็คบๅบ็จ็ๅ ่ดญๆๅๆ็คบ
this.showToast_("Added successfully");
}
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, SpzCustomProductAutomatic);
class SpzCustomDiscountBundle extends SPZ.BaseElement {
constructor(element) {
super(element);
}
isLayoutSupported(layout) {
return layout == SPZCore.Layout.LOGIC;
}
mountCallback() {
// ๅไธ้กตๅฏ่ฝๆๅคไธช block ๅ่ชๆธฒๆๆฌ snippet๏ผๅฏผ่ด้ป่พๅ
็ด spz-custom-discount-toast(#appsAddCartToastFunc) ้ๅคใ
// ไป
ไฟ็ DOM ไธญ็ฌฌไธไธชๅฎไพ๏ผๅ
ถไฝ้ๅคๅฎไพ็งป้ค่ช่บซ๏ผไฟ่ฏ้ป่พๅ
็ด ๅๅ
ถ action ๅผ็จ(appsAddCartToastFunc)ๅฏไธใ
const funcs = document.querySelectorAll('#appsAddCartToastFunc');
if (funcs.length > 1 && this.element !== funcs[0]) {
this.element.remove();
return;
}
// ๅ
จๅฑๆๆฃ toast ็ๅผนๅบ็นๅๆฃๅจๅคไธชๆจกๆฟ/็ปไปถ้๏ผๅซๅฃฐๆๅผ @atcError๏ผ๏ผๆ ๆณ้ไธๅจๅผนๅบๅๅ็ฝฎ๏ผ
// ๆ
ๆ่ฝฝๆถๅน็ญๅฐๅป้ๅนถๆๅฐ body๏ผๅ ่ดญ toast ๆนไธบๅผนๅบๅๆ้ๅป้๏ผ่ง showAddToCartToast๏ผ
this.ensureSingleToastInBody_('cart_match_discount_toast_wrap');
}
unmountCallback() {}
// ๅไธ้กต้ขๅฏ่ฝๆๅคไธช block ๅ่ชๆธฒๆๆฌ toast snippet๏ผๅฆๅ่ฏฆ็ discount_automatic + ่ดญ็ฉ่ฝฆๆฝๅฑ้็ๆๆฃๆจชๅน
๏ผ๏ผ
// ๅฏผ่ด toast ๅคๅฑๅบ็ฐ้ๅค idใ้ๅค id ไธ getElementById/querySelector ๅ SPZ ๅจไฝๅผ็จ้ฝๅชๅฝไธญ็ฌฌไธไธช๏ผ
// ไธ่ขซๅ
ณ่ฟๆฝๅฑ็้ฃไปฝไผ่ขซๆฝๅฑ็ transform/overflow ่ฃๅช/้ไฝใ่ฟ้ๅจๆ่ฝฝๆถๅน็ญๅป้๏ผ
// ๅชไฟ็ไธไปฝใ็งป้คๅคไฝ็๏ผๅนถๆไฟ็็ๆๅฐ body๏ผbody ๆฏ position:fixed ๆๅฎๅ
จ็่ฝ็น๏ผ้ฟๅ
่ขซไปปไฝ็ฅๅ
่ฃๅช๏ผใๅฏๅๅค่ฐ็จใ
ensureSingleToastInBody_(id) {
const els = Array.from(document.querySelectorAll('#' + id));
if (!els.length) return;
els.slice(1).forEach((el) => el.remove());
const keep = els[0];
if (keep.parentNode !== document.body) {
document.body.appendChild(keep);
}
}
// ไธป้ข่ดญ็ฉ่ฝฆๆฝๅฑๆฏๅฆๆๅผ
isInCartDrawer_() {
return !!document.querySelector('[data-section-type="cart_drawer"] spz-sidebar[open]');
}
setupAction_() {
this.registerAction('showAddToCartToast', () => {
// ๆฝๅฑๅ
ๅ ่ดญ๏ผไธป้ขๆฌๅฐฑไธไผๆๅ ่ดญๆๆ๏ผ็ปไธๅผนๆไปถ่ชๅทฑ็ toast
// ้ๆฝๅฑ๏ผไธป้ขๆๅ ่ดญไปฃ็ๅๆฒฟ็จไธป้ขๅ ่ดญๆๆ๏ผๅฆๅๆไปถๅ
ๅบ
const proxyEl = document.getElementById('add-cart-event-proxy');
const inDrawer = this.isInCartDrawer_();
if (!inDrawer && proxyEl) {
return;
}
// ๅผนๅบๅๆ้ๅป้ๅนถๆๅฐ body๏ผๅน็ญ๏ผ๏ผ้ฟๅ
้ๅค id ๅฝไธญ้ๅฏน่ฑกๆ่ขซๆฝๅฑ่ฃๅช/้ไฝ
this.ensureSingleToastInBody_('apps_add_cart_toast_wrap');
const toastEl = document.querySelector('#apps-match-drawer-add_to_cart_toast')
SPZ.whenApiDefined(toastEl).then((apis) => {
apis.showToast("Added successfully");
});
});
}
buildCallback() {
this.setupAction_();
};
}
SPZ.defineElement('spz-custom-discount-toast', SpzCustomDiscountBundle);
${function(){
const tipText = "Please select a {{ name }}".replace(/\{\{\s+name\s+\}\}/g, data);
return `${tipText}
`
}()}
Product was out of stock.
Product is unavailable.