document.addEventListener("DOMContentLoaded", () => { if (!document.querySelector(`.ex-product.ex-a-1812988 .product-summary.label_${sp_labelId}`)) return; if (document.querySelector(".line-ref-wrapper")) return; const lineRefArr = []; let totalLines = 0; let totalCount = 0; const maxCount = 12; const productSummaryContainer = document.querySelectorAll(".ex-product .product-summary-row"); const productAddToCart = document.querySelectorAll(".product-shopping-actions-addtocart"); const replaceSymbols = (input) => input?.replaceAll(/[&/\\#,+()$~%.^'":*?<>{}]/g, "") || ""; const quantityCheck = (input) => { let tempInput = input.value.replace(/[^0-9]/g, ""); const index = Number(input.closest(".line-ref-element").dataset.index); let tempTotalCount = 0; lineRefArr.forEach((e, i) => i !== index - 1 && (tempTotalCount += +e.qty)); const maxAllowed = maxCount - tempTotalCount; if (!isNaN(tempInput)) { if (Number(tempInput) > maxAllowed) tempInput = maxAllowed; totalCount = tempTotalCount + Number(tempInput); } else tempInput = ""; return tempInput; }; const writeLineRef = () => { const value = lineRefArr .map((e, i) => `{Line ${i + 1}: Full Name - ${e.full_name}, Job Title - ${e.job_title}, Quantity - ${e.qty}}`) .join(" "); productAddToCart.forEach((e) => (e.querySelector("#lineref").value = value)); }; const addToLineRef = () => { const lastItem = lineRefArr[lineRefArr.length - 1]; const newLine = `Line ${lineRefArr.length}: Full Name - ${lastItem.full_name}, Job Title - ${lastItem.job_title}, Quantity - ${lastItem.qty}; `; productAddToCart.forEach((e) => { const lineRef = e.querySelector("#lineref"); lineRef.value += newLine; }); }; const updateLineRefArr = () => { const allLineRef = productSummaryContainer[0].querySelectorAll(".line-ref-element"); lineRefArr.length = 0; allLineRef.forEach((e) => { lineRefArr.push({ full_name: replaceSymbols(e.querySelector(".fullname-line input").value), job_title: replaceSymbols(e.querySelector(".job-line input").value), qty: replaceSymbols(e.querySelector(".quantity-line input").value), }); }); writeLineRef(); }; const syncInput = (index, inputName, value) => { const lineClass = inputName === "fullname" ? "fullname-line" : inputName === "jobtitle" ? "job-line" : "quantity-line"; const selector = `.line-ref-element[data-index="${index}"] .${lineClass} input`; document.querySelectorAll(selector).forEach((input) => { if (input.value !== value) input.value = value; }); }; const createLine = () => { totalLines += 1; totalCount += 1; lineRefArr.push({ full_name: "", job_title: "", qty: 1 }); addToLineRef(); const mDiv = document.createElement("div"); mDiv.className = "line-ref-element"; mDiv.dataset.index = totalLines; mDiv.innerHTML = `
Full Name:
Job Title:
Quantity:
`; return mDiv; }; const addLineRef = () => { if (totalCount >= maxCount) return; const line = createLine(); productSummaryContainer.forEach((e) => { const mWrapper = e.querySelector(".line-ref-wrapper"); const addBtn = mWrapper.querySelector(".addline-wrapper"); mWrapper.insertBefore(line.cloneNode(true), addBtn); }); }; const deleteLineRef = (index) => { totalLines -= 1; let tempQty = 0; productSummaryContainer.forEach((e) => { const mWrapper = e.querySelector(".line-ref-wrapper"); tempQty = Number(mWrapper.querySelector(`.line-ref-element[data-index="${index}"] .quantity-line input`).value); mWrapper.querySelector(`.line-ref-element[data-index="${index}"]`).remove(); mWrapper.querySelectorAll(".line-ref-element").forEach((el, i) => { el.dataset.index = i + 1; }); }); totalCount -= tempQty; updateLineRefArr(); }; // Initialize hidden inputs productAddToCart.forEach((item) => { item.insertAdjacentHTML("beforeend", ''); }); // Create initial wrapper const lineRefWrapper = document.createElement("div"); lineRefWrapper.className = "row line-ref-wrapper"; lineRefWrapper.innerHTML = `

Bespoke Card Text

`; lineRefWrapper.insertBefore(createLine(), lineRefWrapper.querySelector(".addline-wrapper")); // Setup each product summary container productSummaryContainer.forEach((e) => { e.append(lineRefWrapper.cloneNode(true)); const lineRefW = e.querySelector(".line-ref-wrapper"); lineRefW.querySelector(".addline-btn").addEventListener("click", (e) => { e.preventDefault(); setTimeout(addLineRef, 50); }); lineRefW.addEventListener("click", (e) => { if (e.target.matches(".line-ref-delete")) { const index = e.target.closest(".line-ref-element").dataset.index; deleteLineRef(index); } if (e.target.matches(".inc-qty") || e.target.matches(".decr-qty")) { const index = e.target.closest(".line-ref-element").dataset.index; const input = e.target.closest(".quantity-line").querySelector("input"); let tempTotalCount = 0; lineRefArr.forEach((e, i) => { if (i === index - 1) return; tempTotalCount += Number(e.qty); }); const maxAllowed = maxCount - tempTotalCount; if (e.target.matches(".inc-qty")) { if (Number(input.value) === maxAllowed) return; input.value = Number(input.value) + 1; } if (e.target.matches(".decr-qty")) { if (Number(input.value) === 1) return; input.value = Number(input.value) - 1; } totalCount = tempTotalCount + Number(input.value); updateLineRefArr(); } }); lineRefW.addEventListener("input", (e) => { if (e.target.tagName !== "INPUT") return; const index = e.target.closest(".line-ref-element").dataset.index; let inputValue = replaceSymbols(e.target.value); const inputName = e.target.name; if (inputName === "quantity") inputValue = quantityCheck(e.target); const fieldName = inputName === "fullname" ? "full_name" : inputName === "jobtitle" ? "job_title" : "quantity"; e.target.value = inputValue; lineRefArr[index - 1][fieldName] = inputValue; if (!e.target.closest(".mobile")) { syncInput(index, inputName, inputValue); updateLineRefArr(); } else { syncInput(index, inputName, inputValue); const desktopInput = document.querySelector( `.desktop .line-ref-element[data-index="${index}"] .${inputName === "fullname" ? "fullname-line" : "job-line"} input` ); desktopInput?.dispatchEvent(new Event("input", { bubbles: true })); } }); lineRefW.addEventListener("focusout", (e) => { if (e.target.name !== "quantity") return; const index = e.target.closest(".line-ref-element").dataset.index; const value = Number(e.target.value) || 1; syncInput(index, "quantity", value); const mobile = e.target.closest(".mobile"); mobile ? document .querySelector(`.desktop .line-ref-element[data-index="${index}"] .quantity-line input`) ?.dispatchEvent(new Event("input", { bubbles: true })) : updateLineRefArr(); totalCount = 0; lineRefArr.forEach((e, i) => { totalCount += Number(e.qty); }); }); }); });