//document.addEventListener("live-pricing-done", () => {
(() => {
if (!document.body.classList.contains("ex-product")) return;
const skuObj = {
IVCP0001: ["Google"],
IVCP0002: ["Facebook"],
IVCP0003: ["Facebook"],
IVCP0004: ["Google"],
IVCP0005: ["Google", "Facebook"],
IVCP0006: ["Google", "Facebook"],
};
let totalLines = 0;
let prodSku = (document.body?.className?.match(/\bex-sku-(\S+)/g) || []).map((key) => key.replace("ex-sku-", "").toUpperCase()).join();
const trashSvg = ``;
// If product SKU not in the list, return
if (!prodSku || !skuObj[prodSku]) return;
// Utility Functions
// Create new Add to Cart Button
const createAddCartButton = () => {
const btn = document.createElement("button");
btn.classList = "btn btn-primary btn-sm btn-add-to-cart btn-add-to-cart-new";
btn.setAttribute("type", "button");
btn.dataset.loadingText = " Adding";
btn.dataset.loadingComplete = " Added";
btn.textContent = "Add to basket";
return btn;
};
// Replace symbols for line reference
const replaceSymbols = (input) => input?.replaceAll(/[\\,+()$~^'"*<>{}]/g, "") || "";
// Remove all not digits symbols
const removeNotDigits = (input) => input?.replace(/[^0-9]/g, "") || "";
// Create line reference
const createlineRefWrapper = () => {
const lineRefWrapper = document.createElement("div");
lineRefWrapper.className = "row line-ref-wrapper";
lineRefWrapper.innerHTML = `
Customise Your Order
`;
return lineRefWrapper;
};
const createlineRefElement = (index) => {
const lineRefElement = document.createElement("div");
lineRefElement.className = "line-ref-element";
lineRefElement.dataset.index = index;
// Create delete button
const deleteBtn = document.createElement("button");
deleteBtn.className = "line-ref-delete";
deleteBtn.setAttribute("type", "button");
deleteBtn.setAttribute("aria-label", "Delete line");
deleteBtn.innerHTML = trashSvg;
// Create quantity button
const quantityLine = document.createElement("div");
quantityLine.className = "quantity-line";
quantityLine.innerHTML = `Quantity:
`;
// Create url inputs
skuObj[prodSku].forEach((service) => {
const line = document.createElement("div");
line.className = `review-line ${service.toLowerCase()}-review-line`;
line.innerHTML = `
${service} review URL:
`;
lineRefElement.append(line);
});
lineRefElement.append(quantityLine, deleteBtn);
return lineRefElement;
};
// Add new line reference
const addLineRef = () => {
totalLines += 1;
const line = createlineRefElement(totalLines);
const productSummaryContainer = document.querySelectorAll(".ex-product .product-summary");
productSummaryContainer.forEach((e) => {
const mWrapper = e.querySelector(".line-ref-wrapper");
const addBtn = mWrapper.querySelector(".addline-wrapper");
addBtn.classList.remove("error");
mWrapper.insertBefore(line.cloneNode(true), addBtn);
});
};
// Remove line reference
const deleteLineRef = (index) => {
totalLines -= 1;
const productSummaryContainer = document.querySelectorAll(".ex-product .product-summary");
productSummaryContainer.forEach((e) => {
const mWrapper = e.querySelector(".line-ref-wrapper");
mWrapper.querySelector(`.line-ref-element[data-index="${index}"]`).remove();
mWrapper.querySelectorAll(".line-ref-element").forEach((el, i) => {
el.dataset.index = i + 1;
});
});
};
// Helper function that returns a Promise which resolves when the event fires
const waitForEvent = (eventName, productId, lineRef, element = document) => {
return new Promise((resolve) => {
const handler = (event) => {
const eventTargetId = event.detail.item.item || NaN;
const eventLineRef = event.detail.item.line_ref || "";
const eventType = event.detail.type || "";
if (eventTargetId === productId && eventLineRef === lineRef && eventType === "add-item") {
element.removeEventListener(eventName, handler);
resolve(event);
}
};
element.addEventListener(eventName, handler);
});
};
// Add to cart all items
const addToCart = () => {
let isEmptyInput = false;
const allInputs = document.querySelectorAll(`.line-ref-wrapper input`);
// Check if there is any lines
if (allInputs.length === 0) {
document.querySelectorAll(".line-ref-wrapper .addline-wrapper").forEach((e) => {
e.classList.add("error");
});
return;
}
// Check if all lines have information
allInputs.forEach((e) => {
if (e.value !== "" && e.value !== "0") return;
e.classList.add("error");
isEmptyInput = true;
});
if (isEmptyInput) return;
const allBtn = document.querySelectorAll(".live-inventory-v2-add-to-cart-wrapper .btn-add-to-cart-new");
allBtn.forEach((e) => {
const text = e.dataset.loadingText;
if (text) e.innerHTML = text;
e.setAttribute("disabled", true);
});
const productAddToCart = document.querySelectorAll(".product-shopping-actions-addtocart");
const productSummaryContainer = document.querySelectorAll(".ex-product .product-summary");
const input = productAddToCart[0].querySelector(".buttons.group .inputquantity");
const button = productAddToCart[0].querySelector("#addItemToCart");
const lineRef = document.getElementById("lineref");
const lineRefElements = productSummaryContainer[0].querySelectorAll(".line-ref-element");
const productId = Number(button.closest(".product").dataset.itemId);
let linerefObg = {};
let qtyValue = 0;
for (let i = 0; i < lineRefElements.length; i++) {
linerefObg[`Plate ${i + 1}`] = {};
const e = lineRefElements[i];
const qty = e.querySelector('.quantity-line input[name="quantity"]').value;
qtyValue += Number(qty);
const allLineInputs = e.querySelectorAll('.review-line input[type="text"]');
allLineInputs.forEach((input) => {
linerefObg[`Plate ${i + 1}`][`${input.name[0].toUpperCase()}${input.name.slice(1)} review URL`] = input.value;
});
linerefObg[`Plate ${i + 1}`]["Quantity"] = qty;
}
linerefObg["Total Quantity"] = qtyValue;
input.value = qtyValue;
const formData = createFormData(linerefObg);
$.ajax({
method: "post",
url: "/ajax/upload-file",
data: formData,
processData: false,
contentType: false,
})
.then(async function (response) {
if (response.status == "success") {
const filepath = response.data.filepath;
if (!filepath) {
throw new Error("File path is missing in the response");
} else {
lineRef.value = `File URL: ${filepath}`;
button.dispatchEvent(new Event("click", { bubbles: true }));
const response = await waitForEvent("cart-total-update", productId, lineRef.value);
}
} else {
console.log("✗ Upload failed - status not success");
}
})
.catch(function (error) {
console.log("✗ Upload failed", error);
});
allBtn.forEach((e) => {
const text = e.dataset.loadingComplete;
if (text) e.innerHTML = text;
e.removeAttribute("disabled");
});
};
// create formData
const createFormData = (obj) => {
const title = document.querySelector(".product-name")?.textContent || "product";
const textContent = `Title: ${title}
Product SKU: ${document.querySelector(".product-summary")?.getAttribute("data-sku") || ""}
Date: ${new Date().toLocaleString()}
---
${JSON.stringify(obj, null, 2)}`;
// Create blob and file
const blob = new Blob([textContent], { type: "text/plain" });
const filename = `product-order_${Date.now()}`;
const file = new File([blob], `${filename}.txt`, { type: "text/plain" });
// Create FormData
const formData = new FormData();
formData.append("file", file); // Change 'file' to match your backend field name
formData.append("title", title);
formData.append("content", textContent);
return formData;
};
// Main Logic
const init = () => {
const productSummaryContainer = document.querySelectorAll(".ex-product .product-summary");
const productAddToCart = document.querySelectorAll(".product-shopping-actions-addtocart");
if (productSummaryContainer[0].querySelector(".line-ref-wrapper")) return;
totalLines = 0;
prodSku = productSummaryContainer[0]?.getAttribute("data-sku")?.toUpperCase() || prodSku;
// append hidden input for line reference to add to cart form if not exists
if (!document.getElementById("lineref")) {
productAddToCart[0].insertAdjacentHTML("beforeend", '');
}
// Create add to cart button
productAddToCart.forEach((e) => {
if (e.querySelector(".btn-add-to-cart-new")) return;
// Hide existing button and qty
e.querySelector("#addItemToCart")?.classList.add("hide");
e.querySelector(".qnt-count")?.classList.add("hide");
// Append new button
const liveInventoryWrapper = e.querySelector(".live-inventory-v2-add-to-cart-wrapper");
if (liveInventoryWrapper) {
const cartBtn = createAddCartButton();
liveInventoryWrapper.append(cartBtn);
liveInventoryWrapper.setAttribute("style", "max-width: 100%; width: 100%;");
cartBtn.addEventListener("click", (e) => {
addToCart();
});
}
});
for (let e of productSummaryContainer) {
if (e.querySelector(".line-ref-wrapper")) continue;
// Create main wrapper and insert
const lineRefWrap = createlineRefWrapper();
const productDetails = e.querySelector(".product-details-wrapper");
productDetails.after(lineRefWrap);
// Click event
lineRefWrap.addEventListener("click", (e) => {
const index = e.target.closest(".line-ref-element")?.dataset.index || "";
const input = e.target.closest(".quantity-line")?.querySelector("input") || null;
let value = 0;
if (e.target.matches(".line-ref-add")) {
e.preventDefault();
setTimeout(addLineRef, 50);
} else if (e.target.matches(".line-ref-delete")) {
e.preventDefault();
deleteLineRef(index);
} else if (e.target.matches(".inc-qty") || e.target.matches(".decr-qty")) {
if (e.target.matches(".inc-qty")) {
if (Number(input.value) === 999) return;
value = Number(input.value) + 1;
} else {
if (Number(input.value) === 1) return;
if (Number(input.value) < 1) {
value = 1;
return;
}
value = Number(input.value) - 1;
}
productSummaryContainer.forEach((el) => {
el.querySelector(`.line-ref-element[data-index="${index}"] .quantity-line input`).value = value;
});
}
});
// Input event
lineRefWrap.addEventListener("input", (e) => {
const index = e.target.closest(".line-ref-element")?.dataset.index || "";
if (e.target.tagName !== "INPUT") return;
if (e.target.getAttribute("name") === "quantity") {
productSummaryContainer.forEach((el) => {
const currInput = el.querySelector(`.line-ref-element[data-index="${index}"] .quantity-line input`);
currInput.value = removeNotDigits(e.target.value);
currInput.classList.remove("error");
});
} else {
const name = e.target.getAttribute("name");
productSummaryContainer.forEach((el) => {
const currInput = el.querySelector(`.line-ref-element[data-index="${index}"] input[name="${name}"]`);
currInput.value = replaceSymbols(e.target.value);
currInput.classList.remove("error");
});
}
});
}
addLineRef();
};
document.addEventListener("live-pricing-done", init);
document.addEventListener("live-inventory-done", init);
})();