// form inputs const recordSizeInputs = document.querySelectorAll("input[name='record-size']"); const rpmInputs = document.querySelectorAll("input[name='record-rpm']"); const amountInputs = document.querySelectorAll("input[name='record-amount']"); const recordTypeInputs = document.querySelectorAll("input[name='record-type']"); const jacketTypeInputs = document.querySelectorAll("input[name='jacket-type']"); const labelTypeInputs = document.querySelectorAll("input[name='label-type']"); const innerSleeveTypeInputs = document.querySelectorAll( "input[name='sleeve-type']" ); const printedInsertTypeInputs = document.querySelectorAll( "input[name='insert-type']" ); const outerWrapTypeInputs = document.querySelectorAll( "input[name='outerwrap-type']" ); const recordColorInput = document.querySelector("input[name='record-color']"); const effectColorInput = document.querySelector("input[name='effect-color']"); const effectColorTwoInput = document.getElementById("effect-color-2"); const effectColorThreeInput = document.getElementById("effect-color-3"); const recordCuttingInputs = document.querySelectorAll( "input[name='record-cutting']" ); const labelColorInputs = document.querySelectorAll("input[name='label-color']"); const downloadCardsTypeInputs = document.querySelectorAll( "input[name='download-card-type']" ); const waveTestPressingsInput = document.querySelector( "input[name='wave-test-pressings']" ); const recordOpacityInputs = document.querySelectorAll( "input[name='record-opacity']" ); const recordWeightInputs = document.querySelectorAll( "input[name='record-weight']" ); const jacketColorInputs = document.querySelectorAll( "input[name='jacket-color']" ); const jacketFinishInputs = document.querySelectorAll( "input[name='jacket-finish']" ); const innerSleeveColorInputs = document.querySelectorAll( "input[name='sleeve-color']" ); const innerSleeveFinishInputs = document.querySelectorAll( "input[name='inner-sleeve-finish']" ); const printedInsertSidesInputs = document.querySelectorAll( "input[name='insert-sides']" ); const printedInsertColorInputs = document.querySelectorAll( "input[name='insert-color']" ); const printedInsertFinishInputs = document.querySelectorAll( "input[name='insert-finish']" ); const projectTitleInput = document.getElementById("project-title"); const recordColorDisplayContainer = document.querySelector( ".record-color-display-container" ); const recordEffectDisplayContainer = document.querySelector( ".record-effect-display-container" ); const innerSleevePrintedColorOptionsContainer = document.getElementById( "printed-sleeve-color-options" ); const innerSleevePaperColorOptionsContainer = document.getElementById( "paper-sleeve-color-options" ); const innerSleeveUploadContainer = document.getElementById( "inner-sleeve-upload-container" ); const shortRunRecordTypeContainer = document.getElementById( "short-run-record-type-options" ); const recordOpacityOptionsContainer = document.getElementById( "record-opacity-options-container" ); const testPressingsInputContainer = document.getElementById( "test-pressings-input-container" ); const recordTypeStandardLabels = document.querySelectorAll( ".record-type-standard-label" ); const recordTypeColorDisplay = document.getElementById( "record-type-color-display" ); const recordTypeEffectDisplay = document.getElementById( "record-type-effect-display" ); const recordTypeEffectDisplayTwo = document.getElementById( "record-type-effect-display-two" ); const recordTypeEffectDisplayThree = document.getElementById( "record-type-effect-display-three" ); const standardColorPickerContainers = document.querySelectorAll( ".builder-record-color-picker" ); const splatterColorPickerContainer = document.querySelector( ".builder-splatter-color-picker" ); const swirlColorPickerContainer = document.querySelector( ".builder-swirl-color-picker" ); const jacketFrontUpload = document.querySelector( "input[name='jacket-front-upload']" ); const labelFrontUpload = document.querySelector( "input[name='label-front-upload']" ); const innerSleeveUpload = document.querySelector("input[name='sleeve-upload']"); const printedInsertUpload = document.querySelector( "input[name='insert-upload']" ); const jacketFrontFilenameDisplay = document.getElementById( "jacket-front-upload-file-display" ); const removeJacketFrontImage = document.getElementById( "remove-jacket-front-image" ); const labelFrontFilenameDisplay = document.getElementById( "label-front-upload-file-display" ); const removeLabelFrontImage = document.getElementById( "remove-label-front-image" ); const sleeveFilenameDisplay = document.getElementById( "sleeve-upload-file-display" ); const removeSleeveImage = document.getElementById("remove-sleeve-image"); const insertFilenameDisplay = document.getElementById( "insert-upload-file-display" ); const removeInsertImage = document.getElementById("remove-insert-image"); const minQtyDisplay = document.getElementById("min-qty-display"); const maxQtyDisplay = document.getElementById("max-qty-display"); const testPressingsInput = document.querySelector( "input[name='test-pressings']" ); const quantityInput = document.querySelector("input[name='record-quantity']"); const testPressingsDisplay = document.querySelector("#test-pressings-display"); const quantityDisplay = document.querySelector("#qty-value-display"); // modal selectors const closeModalButton = document.getElementById("close-breakdown-modal"); const modalBackground = document.querySelector(".modal-background"); const pricingBreakdownButton = document.getElementById( "pricing-breakdown-button" ); const breakdownContainer = document.querySelector( ".builder-breakdown-container" ); const continueEditingButton = document.getElementById( "continue-editing-button" ); const builderSubmitButton = document.getElementById("builder-submit-button"); // Add the lastUsedInput variable declaration let lastUsedInput = "desktop"; // 'desktop' or 'mobile' // pricing breakdown selectors const orderTotalDisplay = document.getElementById("order-total-display"); const orderTotalPerUnitDisplay = document.getElementById( "order-total-per-unit" ); const projectTitleDisplay = document.getElementById("project-title-display"); const sliderTotalPriceDisplay = document.getElementById( "slider-total-price-display" ); const sliderTotalPriceDisplayPerUnit = document.getElementById( "slider-total-price-per-unit" ); // mobile display components const mobileSliderContainer = document.getElementById( "mobile-slider-container" ); const mobileQuantityInput = document.getElementById("record-quantity-mobile"); const quantityValueDisplayMobile = document.getElementById( "qty-value-display-mobile" ); const minQtyDisplayMobile = document.getElementById("min-qty-display-mobile"); const maxQtyDisplayMobile = document.getElementById("max-qty-display-mobile"); const sliderTotalPriceDisplayMobile = document.getElementById( "slider-total-price-display-mobile" ); const sliderTotalPriceDisplayPerUnitMobile = document.getElementById( "slider-total-price-per-unit-mobile" ); const pricingBreakdownButtonMobile = document.getElementById( "pricing-breakdown-button-mobile" ); const mobileQtyActiveDisplay = document.getElementById( "mobile-qty-active-display" ); // breakdown display selectors const masteringBreakdownDisplay = document.getElementById( "mastering-breakdown-display" ); const setupFeeBreakdownDisplay = document.getElementById( "setup-fee-breakdown-display" ); const cuttingFeeBreakdownDisplay = document.getElementById( "cutting-fee-breakdown-display" ); const platingFeeBreakdownDisplay = document.getElementById( "plating-fee-breakdown-display" ); const stampersFeeBreakdownDisplay = document.getElementById( "stampers-fee-breakdown-display" ); const stampersCountDisplay = document.getElementById("stampers-count-display"); const stampersPriceDisplay = document.getElementById("stampers-price-display"); const testPressingsFeeBreakdownDisplay = document.getElementById( "test-pressings-fee-breakdown-display" ); const centerLabelFeeBreakdownDisplay = document.getElementById( "center-labels-fee-breakdown-display" ); const recordsFeeBreakdownDisplay = document.getElementById( "records-fee-breakdown-display" ); const innerSleeveFeeBreakdownDisplay = document.getElementById( "inner-sleeve-fee-breakdown-display" ); const jacketFeeBreakdownDisplay = document.getElementById( "jacket-fee-breakdown-display" ); const insertFeeBreakdownDisplay = document.getElementById( "insert-fee-breakdown-display" ); const outerwrapFeeBreakdownDisplay = document.getElementById( "outerwrap-fee-breakdown-display" ); const downloadCardsFeeBreakdownDisplay = document.getElementById( "download-cards-fee-breakdown-display" ); const miscFeeBreakdownDisplay = document.getElementById( "misc-fee-breakdown-display" ); const insertionFeeBreakdownDisplay = document.getElementById( "insertion-fee-breakdown-display" ); const masteringBreakdownOptionDisplay = document.getElementById( "mastering-option-display" ); const masteringBreakdownOptionPriceDisplay = document.getElementById( "mastering-option-sub-price" ); const setupFeeBreakdownOptionDisplay = document.getElementById( "setup-option-display" ); const setupFeeBreakdownOptionPriceDisplay = document.getElementById( "setup-option-sub-price" ); const cuttingBreakdownOptionDisplay = document.getElementById( "cutting-option-display" ); const cuttingBreakdownOptionPriceDisplay = document.getElementById( "cutting-option-sub-price" ); const platingBreakdownOptionDisplay = document.getElementById( "plating-option-display" ); const platingBreakdownOptionPriceDisplay = document.getElementById( "plating-option-sub-price" ); const testPressingsInitialPriceDisplay = document.getElementById( "test-pressings-initial-sub-price" ); const numOfAdditionalPressingsDisplay = document.getElementById( "num-of-additional-pressings-display" ); const additionalTestPressingsPriceDisplay = document.getElementById( "test-pressings-additional-sub-price" ); const testPressingsShippingPriceDisplay = document.getElementById( "test-pressings-shipping-sub-price" ); const centerLabelBreakdownOptionDisplay = document.getElementById( "center-labels-option-display" ); const centerLabelBreakdownOptionPriceDisplay = document.getElementById( "center-labels-option-sub-price" ); const recordSizeBreakdownDisplay = document.getElementById( "record-size-breakdown-display" ); const recordWeightBreakdownDisplay = document.getElementById( "record-weight-breakdown-display" ); const recordTypeBreakdownDisplay = document.getElementById( "record-type-breakdown-display" ); const recordBreakdownOptionsPriceDisplay = document.getElementById( "record-option-sub-price" ); const sleeveTypeBreakdownDisplay = document.getElementById( "sleeve-type-breakdown-display" ); const sleeveColorBreakdownDisplay = document.getElementById( "sleeve-color-breakdown-display" ); const sleeveFinishBreakdownDisplay = document.getElementById( "sleeve-finish-breakdown-display" ); const sleeveBreakdownOptionPriceDisplay = document.getElementById( "sleeve-option-sub-price" ); const jacketTypeBreakdownDisplay = document.getElementById( "jacket-type-breakdown-display" ); const jacketColorBreakdownDisplay = document.getElementById( "jacket-color-breakdown-display" ); const jacketFinishBreakdownDisplay = document.getElementById( "jacket-finish-breakdown-display" ); const jacketBreakdownOptionPriceDisplay = document.getElementById( "jacket-option-sub-price" ); const insertTypeBreakdownDisplay = document.getElementById( "insert-type-breakdown-display" ); const insertSidesBreakdownDisplay = document.getElementById( "insert-sides-breakdown-display" ); const insertColorBreakdownDisplay = document.getElementById( "insert-color-breakdown-display" ); const insertFinishBreakdownDisplay = document.getElementById( "insert-finish-breakdown-display" ); const insertBreakdownOptionPriceDisplay = document.getElementById( "insert-option-sub-price" ); const outerwrapBreakdownOptionDisplay = document.getElementById( "outerwrap-option-display" ); const outerwrapBreakdownOptionPriceDisplay = document.getElementById( "outerwrap-option-sub-price" ); const downloadCardBreakdownOptionDisplay = document.getElementById( "download-card-option-display" ); const downloadCardBreakdownOptionPriceDisplay = document.getElementById( "download-card-option-sub-price" ); const insertionOfSleevePriceDisplay = document.getElementById( "insertion-of-sleeve-price-display" ); const insertionOfInsertPriceDisplay = document.getElementById( "insertion-of-insert-price-display" ); const insertionOfJacketPriceDisplay = document.getElementById( "insertion-of-jacket-price-display" ); const breakdownEffectColorOneDisplay = document.getElementById( "breakdown-effect-color-one" ); const breakdownEffectColorTwoDisplay = document.getElementById( "breakdown-effect-color-two" ); const breakdownEffectColorThreeDisplay = document.getElementById( "breakdown-effect-color-three" ); const breakdownBaseColorDisplay = document.getElementById( "breakdown-base-color-display" ); const breakdownRpmDisplay = document.getElementById("rpm-option-display"); // hidden form inputs for pricing const preFlightPriceInput = document.getElementById("pre-flight-price-input"); const setupPriceInput = document.getElementById("setup-price-input"); const cuttingPriceInput = document.getElementById("cutting-price-input"); const platingPriceInput = document.getElementById("plating-price-input"); const stampersPriceInput = document.getElementById("stampers-price-input"); const testPressingsPriceInput = document.getElementById( "test-pressings-price-input" ); const centerLabelPriceInput = document.getElementById( "center-label-price-input" ); const recordPriceInput = document.getElementById("record-price-input"); const innerSleevePriceIput = document.getElementById( "inner-sleeve-price-input" ); const jacketPriceInput = document.getElementById("jacket-price-input"); const insertPriceInput = document.getElementById("insert-price-input"); const downloadCardPriceInput = document.getElementById( "download-card-price-input" ); const outerwrapPriceInput = document.getElementById("outerwrap-price-input"); const insertionPriceInput = document.getElementById("insertion-price-input"); const miscPriceInput = document.getElementById("misc-price-input"); const totalPriceInput = document.getElementById("total-price-input"); const pricePerInputUnit = document.getElementById("price-per-unit-input"); const platingDisplayInput = document.getElementById("plating-display-input"); const additionalStampersCountInput = document.getElementById( "additional-stampers-count-input" ); const additionalTestPressingsInput = document.getElementById( "additional-test-pressings-input" ); const additionalTestPressingsPriceInput = document.getElementById( "additional-test-pressings-price-input" ); const testPressingsShippingFeeInput = document.getElementById( "test-pressings-shipping-fee-input" ); const insertionOfInnerSleevePriceInput = document.getElementById( "insertion-of-inner-sleeve-price-input" ); const insertionOfPrintedInsertPriceInput = document.getElementById( "insertion-of-printed-insert-price-input" ); const insertionOfJacketPriceInput = document.getElementById( "insertion-of-jacket-price-input" ); const testPressingsTotalPriceInput = document.getElementById( "test-pressings-total-price-input" ); const missingInfoDisplay = document.getElementById("missing-info-display"); const missingInfoContainer = document.getElementById("missing-info-container"); const jacketOptionsContainer = document.getElementById( "jacket-options-container" ); const labelUploadContainer = document.getElementById("label-options-container"); const labelColorOptionsContainer = document.getElementById( "blank-label-options-container" ); const sleeveOptionsContainer = document.getElementById( "sleeve-options-container" ); const insertOptionsContainer = document.getElementById( "insert-options-container" ); const jacketFinishContainer = document.getElementById("jacket-finish-options"); const innerSleeveFinishContainer = document.getElementById( "inner-sleeve-finish-options" ); const innerSleeveFinishOuterContainer = document.getElementById( "inner-sleeve-finish-outer-container" ); const insertFinishContainer = document.getElementById("insert-finish-options"); const shortRunRecordTypeColorContainer = document.getElementById( "short-run-record-type-color-container" ); const prepareToSubmit = document.getElementById("prepare-to-submit"); // visualizer selectors const jacketVisualDisplay = document.getElementById( "builder-jacket-front-display" ); const recordVisualDisplay = document.getElementById("builder-record-display"); const visualizerContainer = document.querySelector(".builder-right-container"); const recordVisualDisplayDouble = document.getElementById( "builder-record-display-double" ); // selectors for record length const rpm45OptimumDisplay = document.getElementById("45-rpm-optimum-display"); const rpm45MaxDisplay = document.getElementById("45-rpm-max-display"); const rpm33OptimumDisplay = document.getElementById("33-rpm-optimum-display"); const rpm33MaxDisplay = document.getElementById("33-rpm-max-display"); const singleVinylTotalDisplay = document.getElementById( "single-vinyl-total-display" ); const singleVinylPerSideDisplay = document.getElementById( "single-vinyl-per-side-display" ); const doubleVinylTotalDisplay = document.getElementById( "double-vinyl-total-display" ); const doubleVinylPerSideDisplay = document.getElementById( "double-vinyl-per-side-display" ); // User activity tracker const activityTracker = { jacketFrontUpload: false, innerSleeveUpload: false, }; // canvas selectors const canvas1 = document.getElementById("canvas-layer-one"); const canvas2 = document.getElementById("canvas-layer-two"); const canvas3 = document.getElementById("canvas-layer-three"); const canvas2Context = canvas2.getContext("2d", { willReadFrequently: true }); const canvas1Context = canvas1.getContext("2d", { willReadFrequently: true }); const canvas3Context = canvas3.getContext("2d", { willReadFrequently: true }); const layerOne = { imageData: null, initialState: null, canvas: canvas1, context: canvas1Context, }; const layerTwo = { imageData: null, initialState: null, canvas: canvas2, context: canvas2Context, }; const layerThree = { imageData: null, initialState: null, canvas: canvas3, context: canvas3Context, }; const effectUrls = { swirl: "https://cdn.prod.website-files.com/647500086bc1051dc12ba03d/6658bde86dc34818dc550bb7_65a7ec94419a58fe3aa20844_smoke.jpg", splatterLayerOne: "https://cdn.prod.website-files.com/647500086bc1051dc12ba03d/66f5923d87fcc26327e42da7_SplatterMockup_Layer_One.jpg", splatterLayerTwo: "https://cdn.prod.website-files.com/647500086bc1051dc12ba03d/66f5924041a5900937dc9c60_SplatterMockup_Layer_Two.jpg", splatterLayerThree: "https://cdn.prod.website-files.com/647500086bc1051dc12ba03d/66f5924279920d6110c6713f_SplatterMockup_Layer_Three.jpg", }; const recordVisualUrls = { noSelection: "https://cdn.prod.website-files.com/644d5e0d76ce89be1e16b703/66672d8908cf8ce18c618232_Group%201160444522.png", black: "https://cdn.prod.website-files.com/644d5e0d76ce89be1e16b703/667591a4e19865ea53df9d73_2024_EchoBase_Working_TopDown_Black.png", }; function setOffsetForVisualizer() { const height = window.getComputedStyle(visualizerContainer).height; visualizerContainer.style.transform = "translateY(0)"; visualizerContainer.style.top = `calc(100vh - ${height})`; } setOffsetForVisualizer(); window.addEventListener("resize", setOffsetForVisualizer); function init() { setElementsDisplay( [ recordColorDisplayContainer, recordEffectDisplayContainer, labelColorOptionsContainer, recordVisualDisplayDouble, ], "none" ); recordVisualDisplay.classList.add("record-visual-margin-left-none"); // setElementsDisplay(validOptions, "block"); setDefaultValues(); setRecordColorTypeBasedOnOpacity(); setRPMLengthDislayValues(); setDiscLengthDisplayValues(); } const selected = { recordSize: null, rpm: null, amount: null, recordType: null, jacketType: null, labelType: null, labelColor: null, innerSleeveType: null, printedInsertType: null, outerWrapType: null, recordOpacity: null, recordWeight: null, jacketColor: null, jacketFinish: null, innerSleeveColor: null, innerSleeveFinish: null, printedInsertSides: null, printedInsertColor: null, printedInsertFinish: null, testPressings: testPressingsInput.value, recordColorName: null, recordColorSku: null, effectColorName: null, effectColorSku: null, effectColorTwoName: null, effectColorTwoSku: null, effectColorThreeName: null, effectColorThreeSku: null, quantity: quantityInput.value, recordCutting: null, downloadCardType: null, orderType: "short run", waveTestPressings: null, interimRecordTypeElement: null, stampersCount: null, stampersPrice: null, }; init(); document.body.addEventListener("click", (e) => { let allVisibleElements = document.querySelectorAll(".visible"); document.body.style.overflow = "auto"; allVisibleElements.forEach((el) => { el.classList.remove("visible"); }); }); document.body.addEventListener("keydown", (e) => { if (e.key === "Escape") { let allVisibleElements = document.querySelectorAll(".visible"); document.body.style.overflow = "auto"; allVisibleElements.forEach((el) => { el.classList.remove("visible"); }); } }); function updateCustomRadioSelection(nodeList, name) { nodeList.forEach((node) => { if (node.checked) { selected[name] = node.value; node.parentElement.classList.add("selected-radio"); } else { node.parentElement.classList.remove("selected-radio"); } }); } function updateRadioSelection(nodeList, name) { nodeList.forEach((node) => { if (node.checked) { selected[name] = node.value; } }); } function setElementsDisplay(nodeList, display) { nodeList.forEach((node) => { node.style.display = display; }); } function clearInputs(nodeList, keys) { nodeList.forEach((node) => { node.parentElement.classList.remove("selected-radio"); if (node.type === "radio" || node.type === "checkbox") { node.checked = false; } else { node.value = ""; } for (let key of keys) { selected[key] = null; } }); } function setRecordColorTypeBasedOnOpacity() { if (!selected.recordOpacity) { return; } let allOptions = shortRunRecordTypeColorContainer.querySelectorAll( ".color-picker-option" ); if (selected.recordOpacity === "opaque") { allOptions.forEach((option) => { if (option.getAttribute("data-is-opaque") === "true") { setElementsDisplay([option.parentElement.parentElement], "block"); } else { setElementsDisplay([option.parentElement.parentElement], "none"); } }); } else { allOptions.forEach((option) => { if (option.getAttribute("data-is-opaque") === "true") { setElementsDisplay([option.parentElement.parentElement], "none"); } else { setElementsDisplay([option.parentElement.parentElement], "block"); } }); } } function setJacketTypeBasedOnDiscs() { if (selected.amount === "single") { let validOptions = []; validOptions.push( document.getElementById("single-pocket").parentElement.parentElement ); // euro-sleeve is only an option for orders of 100 or less if (selected.quantity <= 100) { validOptions.push( document.getElementById("euro-sleeve").parentElement.parentElement ); } setElementsDisplay(validOptions, "flex"); } else { let invalidOptions = []; invalidOptions.push( document.getElementById("single-pocket").parentElement.parentElement ); invalidOptions.push( document.getElementById("euro-sleeve").parentElement.parentElement ); setElementsDisplay(invalidOptions, "none"); if ( selected.jacketType === "euro-sleeve" || selected.jacketType === "single pocket" ) { clearInputs(jacketTypeInputs, ["jacketType"]); clearInputs(jacketColorInputs, ["jacketColor"]); } } } function setJacketSubOptions() { if (!selected.jacketType || selected.jacketType === "none") { return; } if (!selected.jacketColor) { let defaultInput = document.getElementById("black-white"); if (defaultInput) { defaultInput.checked = true; selected.jacketColor = defaultInput.value; } else { console.error("error finding default input for jacket color"); } } if (!selected.jacketFinish) { let defaultInput = document.getElementById("jacket-finish-semi-gloss"); if (defaultInput) { defaultInput.checked = true; selected.jacketFinish = defaultInput.value; } else { console.error("error finding default input for jacket finish"); } } } function setLabelSubOptions() { if (selected.labelType !== "blank") { return; } if (!selected.labelColor) { let defaultInput = document.getElementById("label-white"); if (defaultInput) { defaultInput.checked = true; selected.labelColor = defaultInput.value; } else { console.error("error finding default input for label color"); } } } function setSleeveSubOptions() { if (!selected.innerSleeveType || selected.innerSleeveType === "anti-static") { return; } if (selected.innerSleeveType === "printed") { if (!selected.innerSleeveColor) { let defaultInput = document.getElementById("full-color-2"); if (defaultInput) { defaultInput.checked = true; selected.innerSleeveColor = defaultInput.value; } else { console.error("error finding default input for inner sleeve color"); } } if (!selected.innerSleeveFinish) { let defaultInput = document.getElementById("inner-sleeve-semi-gloss"); if (defaultInput) { defaultInput.checked = true; selected.innerSleeveFinish = defaultInput.value; } else { console.error("error finding default input for inner sleeve finish"); } } } else { // paper and paper w/ poly lining have the same options if (!selected.innerSleeveColor) { let defaultInput = document.getElementById("white-3"); if (defaultInput) { defaultInput.checked = true; selected.innerSleeveColor = defaultInput.value; } else { console.error("error finding default input for inner sleeve color"); } } } } function setInsertSubOptions() { if (!selected.printedInsertType || selected.printedInsertType === "none") { return; } if (!selected.printedInsertSides) { let defaultInput = document.getElementById("one-sided"); if (defaultInput) { defaultInput.checked = true; selected.printedInsertSides = defaultInput.value; } else { console.error("error finding default input for printed insert sides"); } } if (!selected.printedInsertColor) { let defaultInput = document.getElementById("full-color-3"); if (defaultInput) { defaultInput.checked = true; selected.printedInsertColor = defaultInput.value; } else { console.error("error finding default input for printed insert color"); } } if (!selected.printedInsertFinish) { let defaultInput = document.getElementById("insert-semi-gloss"); if (defaultInput) { defaultInput.checked = true; selected.printedInsertFinish = defaultInput.value; } else { console.error("error finding default input for printed insert finish"); } } } function setInputsRequiredTrue(nodeList) { nodeList.forEach((node) => { if (node.type !== "file") { node.setAttribute("required", "true"); } }); } function setInputsRequiredFalse(nodeList) { nodeList.forEach((node) => { node.removeAttribute("required"); }); } function setDefaultValues() { recordCuttingInputs.forEach((input) => { if (input.value === "yes") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.recordCutting = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); recordSizeInputs.forEach((input) => { if (input.value === "12") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.recordSize = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); rpmInputs.forEach((input) => { if (input.value === "33") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.rpm = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); amountInputs.forEach((input) => { if (input.value === "single") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.amount = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); recordOpacityInputs.forEach((input) => { if (input.value === "opaque") { input.checked = true; selected.recordOpacity = input.value; } else { input.checked = false; } }); recordTypeInputs.forEach((input) => { if (input.id === "black") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.recordType = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); recordWeightInputs.forEach((input) => { if (input.value === "standard") { input.checked = true; selected.recordWeight = input.value; } else { input.checked = false; } }); jacketTypeInputs.forEach((input) => { if (input.value === "single pocket") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.jacketType = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); jacketColorInputs.forEach((input) => { if (input.value === "black & white") { input.checked = true; selected.jacketColor = input.value; } else { input.checked = false; } }); jacketFinishInputs.forEach((input) => { if (input.value === "semi-gloss") { input.checked = true; selected.jacketFinish = input.value; } else { input.checked = false; } }); labelTypeInputs.forEach((input) => { if (input.value === "full color") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.labelType = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); innerSleeveTypeInputs.forEach((input) => { if (input.value === "anti-static") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.innerSleeveType = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); printedInsertTypeInputs.forEach((input) => { if (input.value === "none") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.printedInsertType = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); downloadCardsTypeInputs.forEach((input) => { if (input.value === "none") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.downloadCardType = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); outerWrapTypeInputs.forEach((input) => { if (input.value === "polybag") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.outerWrapType = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); // hide options that are not available setElementsDisplay( [ recordColorDisplayContainer, recordEffectDisplayContainer, labelColorOptionsContainer, sleeveOptionsContainer, insertOptionsContainer, ], "none" ); setElementsDisplay( [ document.getElementById("black").parentElement.parentElement .parentElement, ], "flex" ); const notRequiredOptions = []; notRequiredOptions.push( ...labelColorOptionsContainer.querySelectorAll("input") ); notRequiredOptions.push(...sleeveOptionsContainer.querySelectorAll("input")); notRequiredOptions.push(...insertOptionsContainer.querySelectorAll("input")); clearInputs(notRequiredOptions, [ "printedInsertColor", "printedInsertSides", "printedInsertFinish", "labelColor", "innerSleeveColor", "innerSleeveFinish", ]); setInputsRequiredFalse(notRequiredOptions); const invalidOptions = []; invalidOptions.push(document.getElementById("7").parentElement.parentElement); invalidOptions.push( document.getElementById("splatter").parentElement.parentElement .parentElement ); invalidOptions.push( document.getElementById("swirl").parentElement.parentElement.parentElement ); invalidOptions.push( document.getElementById("insert-7x7").parentElement.parentElement ); invalidOptions.push( document.getElementById("insert-14x7").parentElement.parentElement ); invalidOptions.push( document.getElementById("gatefold").parentElement.parentElement ); setElementsDisplay(invalidOptions, "none"); recordVisualDisplay.style.backgroundImage = `url(${recordVisualUrls.black})`; } function setTestPressingsOptions() { clearInputs([waveTestPressingsInput], ["waveTestPressings"]); testPressingsInput.min = "5"; testPressingsInput.value = "5"; selected.testPressings = "5"; testPressingsDisplay.innerText = "5"; setElementsDisplay( [testPressingsInputContainer, waveTestPressingsInput.parentElement], "block" ); } function setJacketOptions() { if (selected.quantity <= 100) { setElementsDisplay( [document.getElementById("gatefold").parentElement.parentElement], "none" ); setElementsDisplay( [document.getElementById("euro-sleeve").parentElement.parentElement], "flex" ); if (selected.jacketType === "gatefold") { clearInputs(jacketTypeInputs, ["jacketType"]); } if (selected.recordSize === "7") { setElementsDisplay( [document.getElementById("wide-spine").parentElement.parentElement], "none" ); if (selected.jacketType === "wide-spine") { clearInputs(jacketTypeInputs, ["jacketType"]); } } else { setElementsDisplay( [document.getElementById("wide-spine").parentElement.parentElement], "flex" ); } } else { setElementsDisplay( [document.getElementById("euro-sleeve").parentElement.parentElement], "none" ); if (selected.jacketType === "euro-sleeve") { clearInputs(jacketTypeInputs, ["jacketType"]); } if (selected.recordSize === "7") { setElementsDisplay( [document.getElementById("wide-spine").parentElement.parentElement], "none" ); setElementsDisplay( [document.getElementById("gatefold").parentElement.parentElement], "none" ); if ( selected.jacketType === "wide-spine" || selected.jacketType === "gatefold" ) { clearInputs(jacketTypeInputs, ["jacketType"]); } } else { setElementsDisplay( [document.getElementById("gatefold").parentElement.parentElement], "flex" ); setElementsDisplay( [document.getElementById("wide-spine").parentElement.parentElement], "flex" ); } } } function setMockupDisplayDiscs() { if (!selected.amount || selected.amount === "single") { setElementsDisplay([recordVisualDisplayDouble], "none"); recordVisualDisplay.classList.add("record-visual-margin-left-none"); } else { let elementsWithMarginLeftNone = document.querySelectorAll( ".record-visual-margin-left-none" ); elementsWithMarginLeftNone.forEach((element) => { element.classList.remove("record-visual-margin-left-none"); }); let backgroundImage = recordVisualDisplay.style.backgroundImage; recordVisualDisplayDouble.classList.add("record-visual-margin-left-none"); recordVisualDisplayDouble.style.backgroundImage = backgroundImage; setElementsDisplay([recordVisualDisplayDouble], "flex"); } } function setRPMLengthDislayValues() { if (selected.recordSize === "12") { rpm33OptimumDisplay.innerText = "24 - 28"; rpm33MaxDisplay.innerText = "44"; rpm45OptimumDisplay.innerText = "18"; rpm45MaxDisplay.innerText = "24"; } else { rpm33OptimumDisplay.innerText = "5"; rpm33MaxDisplay.innerText = "9"; rpm45OptimumDisplay.innerText = "3"; rpm45MaxDisplay.innerText = "6"; } } function setDiscLengthDisplayValues() { if (selected.rpm === "33") { if (selected.recordSize == "12") { singleVinylTotalDisplay.innerText = "44"; singleVinylPerSideDisplay.innerText = "22"; doubleVinylTotalDisplay.innerText = "88"; doubleVinylPerSideDisplay.innerText = "22"; } else { singleVinylTotalDisplay.innerText = "18"; singleVinylPerSideDisplay.innerText = "9"; doubleVinylTotalDisplay.innerText = "36"; doubleVinylPerSideDisplay.innerText = "9"; } } else { if (selected.recordSize == "12") { singleVinylTotalDisplay.innerText = "30"; singleVinylPerSideDisplay.innerText = "15"; doubleVinylTotalDisplay.innerText = "60"; doubleVinylPerSideDisplay.innerText = "15"; } else { singleVinylTotalDisplay.innerText = "12"; singleVinylPerSideDisplay.innerText = "6"; doubleVinylTotalDisplay.innerText = "24"; doubleVinylPerSideDisplay.innerText = "6"; } } } // event listeners for custom radio buttons downloadCardsTypeInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(downloadCardsTypeInputs, "downloadCardType"); getDownloadCardsPrice(); getTotalPrice(); }); }); recordCuttingInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(recordCuttingInputs, "recordCutting"); getAllPrices(); getTotalPrice(); }); }); recordSizeInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(recordSizeInputs, "recordSize"); setRPMLengthDislayValues(); setDiscLengthDisplayValues(); if (selected.recordSize === "7") { const invalidOptions = []; invalidOptions.push(document.getElementById("heavyweight").parentElement); invalidOptions.push( document.getElementById("insert-12x12").parentElement.parentElement ); invalidOptions.push( document.getElementById("insert-24x12").parentElement.parentElement ); const validOptions = []; validOptions.push( document.getElementById("insert-7x7").parentElement.parentElement ); validOptions.push( document.getElementById("insert-14x7").parentElement.parentElement ); setElementsDisplay(invalidOptions, "none"); setElementsDisplay(validOptions, "flex"); // Add/remove classes for splatter-embed const splatterEmbed = document.getElementById("splatter-embed"); splatterEmbed.classList.remove("embed-container"); splatterEmbed.classList.add("hidden-embed"); const wideSpineEmbed = document.getElementById("wide-spine-embed"); wideSpineEmbed.classList.add("hidden-embed"); const gatefoldEmbed = document.getElementById("gatefold-embed"); gatefoldEmbed.classList.add("hidden-embed"); const antiStaticEmbed = document.getElementById("anti-static-embed"); antiStaticEmbed.classList.add("hidden-embed"); const euroSleeveEmbed = document.getElementById("euro-sleeve-embed"); euroSleeveEmbed.classList.add("hidden-embed"); if (selected.amount === "double") { const singlePocketEmbed = document.getElementById( "single-pocket-embed" ); singlePocketEmbed.classList.remove("hidden-embed"); } const twelveByTwelveInsert = document.getElementById("12x12-embed"); twelveByTwelveInsert.classList.add("hidden-embed"); const twentyFourByTwelveInsert = document.getElementById("24x12-embed"); twentyFourByTwelveInsert.classList.add("hidden-embed"); if (!activityTracker.jacketFrontUpload) { jacketTypeInputs.forEach((input) => { if (input.value === "none") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.jacketType = "none"; setElementsDisplay([jacketOptionsContainer], "none"); } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); } else { if ( selected.jacketType === "gatefold" || selected.jacketType === "wide spine" ) { jacketTypeInputs.forEach((input) => { if (input.value === "single pocket") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.jacketType = "single pocket"; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); } } if (!activityTracker.innerSleeveUpload) { innerSleeveTypeInputs.forEach((input) => { if (input.value === "paper") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.innerSleeveType = "paper"; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); // Show paper color options and select white setElementsDisplay([sleeveOptionsContainer], "block"); setElementsDisplay([innerSleevePaperColorOptionsContainer], "flex"); setElementsDisplay( [ innerSleevePrintedColorOptionsContainer, innerSleeveFinishOuterContainer, innerSleeveUploadContainer, ], "none" ); // Select white color const whiteInput = document.getElementById("white-3"); if (whiteInput) { whiteInput.checked = true; selected.innerSleeveColor = "white"; } // Make inputs required setInputsRequiredTrue(sleeveOptionsContainer.querySelectorAll("input")); setInputsRequiredFalse( innerSleeveFinishContainer.querySelectorAll("input") ); } else if (selected.innerSleeveType === "printed") { // If printed inner sleeve is selected, ensure semi-gloss is selected setSleeveSubOptions(); } // check to make sure none of the invalid selections are currently selected if (selected.recordWeight === "heavyweight") { clearInputs(recordWeightInputs, ["recordWeight"]); // Automatically select standard weight recordWeightInputs.forEach((input) => { if (input.value === "standard") { input.checked = true; selected.recordWeight = "standard"; } }); } // If splatter is selected, switch to black if (selected.recordType === "splatter") { recordTypeInputs.forEach((input) => { if (input.value === "black") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.recordType = "black"; // Update the mockup visualizer recordVisualDisplay.style.backgroundImage = `url(${recordVisualUrls.black})`; recordVisualDisplayDouble.style.backgroundImage = `url(${recordVisualUrls.black})`; // Clear any splatter effects clearEffects(); // Hide color and effect display containers document.getElementById( "record-color-code-display-container" ).style.display = "none"; document.getElementById( "record-effect-color-code-display-container" ).style.display = "none"; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); } if ( selected.printedInsertType === "12x12" || selected.printedInsertType === "24x12" ) { clearInputs(printedInsertTypeInputs, ["printedInsertType"]); } if (selected.innerSleeveType === "anti-static") { clearInputs(innerSleeveTypeInputs, ["innerSleeveType"]); } rpmInputs.forEach((input) => { if (input.value === "45") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.rpm = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); setDiscLengthDisplayValues(); } else { // record size === 12 or 10 setElementsDisplay( [document.getElementById("heavyweight").parentElement], "block" ); // Add/remove classes for splatter-embed const splatterEmbed = document.getElementById("splatter-embed"); splatterEmbed.classList.remove("hidden-embed"); splatterEmbed.classList.add("embed-container"); const wideSpineEmbed = document.getElementById("wide-spine-embed"); wideSpineEmbed.classList.remove("hidden-embed"); const gatefoldEmbed = document.getElementById("gatefold-embed"); gatefoldEmbed.classList.remove("hidden-embed"); const antiStaticEmbed = document.getElementById("anti-static-embed"); antiStaticEmbed.classList.remove("hidden-embed"); if (selected.amount === "double") { const singlePocketEmbed = document.getElementById( "single-pocket-embed" ); singlePocketEmbed.classList.add("hidden-embed"); } else { const euroSleeveEmbed = document.getElementById("euro-sleeve-embed"); euroSleeveEmbed.classList.remove("hidden-embed"); } const twelveByTwelveInsert = document.getElementById("12x12-embed"); twelveByTwelveInsert.classList.remove("hidden-embed"); const twentyFourByTwelveInsert = document.getElementById("24x12-embed"); twentyFourByTwelveInsert.classList.remove("hidden-embed"); const validOptions = []; validOptions.push( document.getElementById("sleeve-anti-static").parentElement .parentElement ); // Show splatter option again validOptions.push( document.getElementById("splatter").parentElement.parentElement .parentElement ); const invalidOptions = []; invalidOptions.push( document.getElementById("insert-7x7").parentElement.parentElement ); invalidOptions.push( document.getElementById("insert-14x7").parentElement.parentElement ); setElementsDisplay(invalidOptions, "none"); setElementsDisplay(validOptions, "flex"); // check to make sure none of the invalid selections are currently selected if ( selected.printedInsertType === "7x7" || selected.printedInsertType === "14x7" ) { clearInputs(printedInsertTypeInputs, ["printedInsertType"]); } // Automatically set RPM to 33 for 12-inch records if (selected.recordSize === "12") { rpmInputs.forEach((input) => { if (input.value === "33") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.rpm = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); setDiscLengthDisplayValues(); // Automatically set jacket type based on amount for 12-inch records jacketTypeInputs.forEach((input) => { if (selected.amount === "double" && input.value === "wide spine") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.jacketType = input.value; // Set default jacket color and finish when switching to wide spine jacketColorInputs.forEach((input) => { if (input.value === "black & white") { input.checked = true; input.classList.add("selected-radio"); selected.jacketColor = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); jacketFinishInputs.forEach((input) => { if (input.value === "semi-gloss") { input.checked = true; input.classList.add("selected-radio"); selected.jacketFinish = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); // Show jacket options container setElementsDisplay([jacketOptionsContainer], "block"); setInputsRequiredTrue( jacketOptionsContainer.querySelectorAll("input") ); } else if ( selected.amount === "single" && input.value === "single pocket" ) { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.jacketType = input.value; // Set default jacket color and finish when switching to single pocket jacketColorInputs.forEach((input) => { if (input.value === "black & white") { input.checked = true; input.classList.add("selected-radio"); selected.jacketColor = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); jacketFinishInputs.forEach((input) => { if (input.value === "semi-gloss") { input.checked = true; input.classList.add("selected-radio"); selected.jacketFinish = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); // Show jacket options container setElementsDisplay([jacketOptionsContainer], "block"); setInputsRequiredTrue( jacketOptionsContainer.querySelectorAll("input") ); } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); const innerSleeveTypeSelection = selected.innerSleeveType; if (innerSleeveTypeSelection === "paper") { innerSleeveTypeInputs.forEach((input) => { if (input.value === "anti-static") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.innerSleeveType = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); setElementsDisplay([sleeveOptionsContainer], "none"); setElementsDisplay( [ innerSleevePaperColorOptionsContainer, innerSleevePrintedColorOptionsContainer, innerSleeveFinishOuterContainer, innerSleeveUploadContainer, ], "none" ); } } } // setRecordTypeBasedOnSize(); setJacketOptions(); getAllPrices(); getTotalPrice(); }); }); rpmInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(rpmInputs, "rpm"); setDiscLengthDisplayValues(); }); }); amountInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(amountInputs, "amount"); // Handle single pocket visibility for 12-inch records if (selected.recordSize === "12") { const singlePocketContainer = document.querySelector( "input[value='single pocket']" ).parentElement.parentElement; const euroSleeveEmbed = document.getElementById("euro-sleeve-embed"); if (selected.amount === "double") { singlePocketContainer.classList.add("hidden-embed"); euroSleeveEmbed.classList.add("hidden-embed"); } else { singlePocketContainer.classList.remove("hidden-embed"); euroSleeveEmbed.classList.remove("hidden-embed"); } } // Automatically set jacket type to widespine for 12-inch double vinyl if (selected.recordSize === "12" && selected.amount === "double") { jacketTypeInputs.forEach((input) => { if (input.value === "wide spine") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.jacketType = input.value; // Set default jacket color and finish when switching to widespine jacketColorInputs.forEach((input) => { if (input.value === "black & white") { input.checked = true; input.classList.add("selected-radio"); selected.jacketColor = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); jacketFinishInputs.forEach((input) => { if (input.value === "semi-gloss") { input.checked = true; input.classList.add("selected-radio"); selected.jacketFinish = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); // Show jacket options container setElementsDisplay([jacketOptionsContainer], "block"); setInputsRequiredTrue( jacketOptionsContainer.querySelectorAll("input") ); } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); } else if (selected.recordSize === "12" && selected.amount === "single") { jacketTypeInputs.forEach((input) => { if (input.value === "single pocket") { input.checked = true; input.parentElement.classList.add("selected-radio"); selected.jacketType = input.value; // Set default jacket color and finish when switching to single pocket jacketColorInputs.forEach((input) => { if (input.value === "black & white") { input.checked = true; input.classList.add("selected-radio"); selected.jacketColor = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); jacketFinishInputs.forEach((input) => { if (input.value === "semi-gloss") { input.checked = true; input.classList.add("selected-radio"); selected.jacketFinish = input.value; } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); // Show jacket options container setElementsDisplay([jacketOptionsContainer], "block"); setInputsRequiredTrue( jacketOptionsContainer.querySelectorAll("input") ); } else { input.checked = false; input.parentElement.classList.remove("selected-radio"); } }); } setJacketTypeBasedOnDiscs(); setMockupDisplayDiscs(); getAllPrices(); getTotalPrice(); }); }); function showColorOptions(label) { let previouslyOpenedOptions = document.querySelectorAll(".visible"); previouslyOpenedOptions.forEach((option) => { option.classList.remove("visible"); }); clearEffectColorOptions(); clearSelectedClasses(); let colorPicker = label.parentElement.parentElement.querySelector( ".builder-record-color-picker" ) || label.parentElement.parentElement.querySelector( ".builder-splatter-color-picker" ) || label.parentElement.parentElement.querySelector( ".builder-swirl-color-picker" ); colorPicker.classList.add("visible"); } standardColorPickerContainers.forEach((container) => { container.addEventListener("click", (e) => { e.stopPropagation(); if (e.target.classList.contains("color-picker-option")) { setElementsDisplay([recordColorDisplayContainer], "block"); container.classList.remove("visible"); let colorName = e.target.getAttribute("data-name"); let colorSku = e.target.getAttribute("data-sku"); let imageUrl = e.target.getAttribute("data-image-url"); recordTypeColorDisplay.innerText = `${colorName} ${colorSku}`; recordColorInput.value = colorSku; recordVisualDisplay.style.backgroundImage = `url(${imageUrl})`; selected.recordColorName = colorName; selected.recordColorSku = colorSku; selected.recordType = selected.interimRecordTypeElement.value; selected.interimRecordTypeElement.checked = true; updateCustomRadioSelection(recordTypeInputs, "recordType"); setMockupDisplayDiscs(); getAllPrices(); getTotalPrice(); } }); }); const splatterOptions = { recordColorName: null, recordColorSku: null, splatterColorOneName: null, splatterColorOneSku: null, splatterColorTwoName: null, splatterColorTwoSku: null, splatterColorThreeName: null, splatterColorThreeSku: null, splatterHexColorOne: null, splatterHexColorTwo: null, splatterHexColorThree: null, imageUrl: null, }; function setRecordAndEffectInputValues() { recordColorInput.value = selected.recordColorName; effectColorInput.value = selected.effectColorName; effectColorTwoInput.value = selected.effectColorTwoName; effectColorThreeInput.value = selected.effectColorThreeName; } function clearEffectColorOptions() { Object.keys(splatterOptions).forEach((key) => { splatterOptions[key] = null; }); Object.keys(swirlOptions).forEach((key) => { swirlOptions[key] = null; }); } function clearSelectedClasses() { let selectedClasses = Array.from( document.querySelectorAll(".selected-effect-color") ); let selectedRecordColor = document.querySelector(".selected-record-color"); if (selectedRecordColor) { selectedClasses.push(selectedRecordColor); } selectedClasses.forEach((el) => { el.classList.remove("selected-effect-color"); el.classList.remove("selected-record-color"); }); } splatterColorPickerContainer.addEventListener("click", async (e) => { e.stopPropagation(); e.preventDefault(); if (e.target.classList.contains("record-color-option")) { splatterOptions.recordColorName = e.target.getAttribute("data-name"); splatterOptions.recordColorSku = e.target.getAttribute("data-sku"); splatterOptions.imageUrl = e.target.getAttribute("data-image-url"); let previouslySelected = document.querySelectorAll( ".selected-record-color" ); previouslySelected.forEach((el) => { el.classList.remove("selected-record-color"); }); e.target.classList.add("selected-record-color"); recordVisualDisplay.style.backgroundImage = `url(${splatterOptions.imageUrl})`; selected.recordColorName = splatterOptions.recordColorName; selected.recordColorSku = splatterOptions.recordColorSku; recordTypeColorDisplay.innerText = `${selected.recordColorName} ${selected.recordColorSku}`; setElementsDisplay([recordColorDisplayContainer], "block"); recordColorInput.value = selected.recordColorName; } else if (e.target.classList.contains("splatter-color-option")) { if (!splatterOptions.splatterColorOneName) { if (!splatterOptions.splatterColorThreeName) { e.target.classList.add("selected-effect-color"); } splatterOptions.splatterColorOneName = e.target.getAttribute("data-name"); splatterOptions.splatterColorOneSku = e.target.getAttribute("data-sku"); splatterOptions.splatterHexColorOne = e.target.getAttribute("data-color"); await initEffect( effectUrls.splatterLayerOne, layerOne, splatterOptions.splatterHexColorOne ); selected.effectColorName = splatterOptions.splatterColorOneName; selected.effectColorSku = splatterOptions.splatterColorOneSku; recordTypeEffectDisplay.innerText = `${selected.effectColorName} ${selected.effectColorSku}`; setElementsDisplay( [recordTypeEffectDisplayTwo, recordTypeEffectDisplayThree], "none" ); setElementsDisplay([recordTypeEffectDisplay], "flex"); setElementsDisplay([recordEffectDisplayContainer], "block"); effectColorInput.value = selected.effectColorName; } else if (!splatterOptions.splatterColorTwoName) { if (!splatterOptions.splatterColorThreeName) { e.target.classList.add("selected-effect-color"); } splatterOptions.splatterColorTwoName = e.target.getAttribute("data-name"); splatterOptions.splatterColorTwoSku = e.target.getAttribute("data-sku"); splatterOptions.splatterHexColorTwo = e.target.getAttribute("data-color"); await initEffect( effectUrls.splatterLayerTwo, layerTwo, splatterOptions.splatterHexColorTwo ); selected.effectColorTwoName = splatterOptions.splatterColorTwoName; selected.effectColorTwoSku = splatterOptions.splatterColorTwoSku; recordTypeEffectDisplayTwo.innerText = `${selected.effectColorTwoName} ${selected.effectColorTwoSku}`; setElementsDisplay([recordTypeEffectDisplayTwo], "flex"); setElementsDisplay([recordTypeEffectDisplayThree], "none"); effectColorTwoInput.value = selected.effectColorTwoName; } else if (!splatterOptions.splatterColorThreeName) { if (!splatterOptions.splatterColorThreeName) { e.target.classList.add("selected-effect-color"); } splatterOptions.splatterColorThreeName = e.target.getAttribute("data-name"); splatterOptions.splatterColorThreeSku = e.target.getAttribute("data-sku"); splatterOptions.splatterHexColorThree = e.target.getAttribute("data-color"); await initEffect( effectUrls.splatterLayerThree, layerThree, splatterOptions.splatterHexColorThree ); selected.effectColorThreeName = splatterOptions.splatterColorThreeName; selected.effectColorThreeSku = splatterOptions.splatterColorThreeSku; recordTypeEffectDisplayThree.innerText = `${selected.effectColorThreeName} ${selected.effectColorThreeSku}`; setElementsDisplay([recordTypeEffectDisplayThree], "flex"); effectColorThreeInput.value = selected.effectColorThreeName; } } else if ( e.target.id === "close-splatter-modal" && splatterOptions.recordColorName && splatterOptions.splatterColorOneName ) { splatterColorPickerContainer.classList.remove("visible"); } if (splatterOptions.recordColorName && splatterOptions.splatterColorOneName) { selected.recordType = selected.interimRecordTypeElement.value; selected.interimRecordTypeElement.checked = true; updateCustomRadioSelection(recordTypeInputs, "recordType"); } setMockupDisplayDiscs(); getAllPrices(); getTotalPrice(); }); const swirlOptions = { recordColorName: null, recordColorSku: null, swirlColorName: null, swirlColorSku: null, recordImageUrl: null, effectHexColor: null, }; swirlColorPickerContainer.addEventListener("click", (e) => { e.stopPropagation(); e.preventDefault(); if (e.target.classList.contains("record-color-option")) { swirlOptions.recordColorName = e.target.getAttribute("data-name"); swirlOptions.recordColorSku = e.target.getAttribute("data-sku"); let previouslySelected = document.querySelectorAll( ".selected-record-color" ); previouslySelected.forEach((el) => { el.classList.remove("selected-record-color"); }); swirlOptions.recordImageUrl = e.target.getAttribute("data-image-url"); e.target.classList.add("selected-record-color"); recordVisualDisplay.style.backgroundImage = `url(${swirlOptions.recordImageUrl})`; selected.recordColorName = swirlOptions.recordColorName; selected.recordColorSku = swirlOptions.recordColorSku; recordTypeColorDisplay.innerText = `${selected.recordColorName} ${selected.recordColorSku}`; recordColorInput.value = selected.recordColorName; setElementsDisplay([recordColorDisplayContainer], "block"); } else if (e.target.classList.contains("splatter-color-option")) { swirlOptions.swirlColorName = e.target.getAttribute("data-name"); swirlOptions.swirlColorSku = e.target.getAttribute("data-sku"); let previouslySelected = document.querySelectorAll( ".selected-effect-color" ); previouslySelected.forEach((el) => { el.classList.remove("selected-effect-color"); }); swirlOptions.effectHexColor = e.target.getAttribute("data-color"); e.target.classList.add("selected-effect-color"); initEffect(effectUrls.swirl, layerOne, swirlOptions.effectHexColor); selected.effectColorName = swirlOptions.swirlColorName; selected.effectColorSku = swirlOptions.swirlColorSku; recordTypeEffectDisplay.innerText = `${selected.effectColorName} ${selected.effectColorSku}`; effectColorInput.value = selected.effectColorName; setElementsDisplay([recordTypeEffectDisplay], "flex"); setElementsDisplay( [recordTypeEffectDisplayTwo, recordTypeEffectDisplayThree], "none" ); setElementsDisplay([recordEffectDisplayContainer], "block"); } else if ( e.target.id === "close-swirl-modal" && swirlOptions.recordColorName && swirlOptions.swirlColorName ) { swirlColorPickerContainer.classList.remove("visible"); } if (swirlOptions.recordColorName && swirlOptions.swirlColorName) { selected.recordType = selected.interimRecordTypeElement.value; selected.interimRecordTypeElement.checked = true; updateCustomRadioSelection(recordTypeInputs, "recordType"); } setMockupDisplayDiscs(); getAllPrices(); getTotalPrice(); }); recordTypeInputs.forEach((input) => { input.addEventListener("change", (e) => { e.stopPropagation(); setElementsDisplay( [recordColorDisplayContainer, recordEffectDisplayContainer], "none" ); clearSelectedColors(); clearEffects(); let selectedElement = document.querySelector( "input[name='record-type']:checked" ); if (selectedElement.value === "black") { setInputsRequiredFalse([recordColorInput, effectColorInput]); updateCustomRadioSelection(recordTypeInputs, "recordType"); recordVisualDisplay.style.backgroundImage = `url(${recordVisualUrls.black})`; } else { selected.interimRecordTypeElement = selectedElement; clearInputs(recordTypeInputs, ["recordType"]); showColorOptions(selectedElement.parentElement); } setMockupDisplayDiscs(); getAllPrices(); getTotalPrice(); }); }); jacketTypeInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(jacketTypeInputs, "jacketType"); let value = document.querySelector( "input[name='jacket-type']:checked" ).value; let allInputs = jacketOptionsContainer.querySelectorAll("input"); if (value === "none") { setElementsDisplay([jacketOptionsContainer], "none"); jacketVisualDisplay.style.backgroundImage = ""; clearInputs(allInputs, ["jacketColor", "jacketFinish"]); setInputsRequiredFalse(allInputs); // remove file upload display if any const fileUploadDisplays = jacketOptionsContainer.querySelectorAll( ".file-upload-display" ); setElementsDisplay(fileUploadDisplays, "none"); } else { setElementsDisplay([jacketOptionsContainer], "block"); setInputsRequiredTrue(allInputs); } setJacketSubOptions(); getInsertionPrice(); getJacketPrice(); getTotalPrice(); }); }); labelTypeInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(labelTypeInputs, "labelType"); let value = document.querySelector( "input[name='label-type']:checked" ).value; if (value === "blank") { let allInputs = labelUploadContainer.querySelectorAll("input"); setElementsDisplay([labelUploadContainer], "none"); setElementsDisplay([labelColorOptionsContainer], "block"); let requiredInputs = labelColorOptionsContainer.querySelectorAll("input"); setInputsRequiredTrue(requiredInputs); clearInputs(allInputs, []); setInputsRequiredFalse(allInputs); // remove file upload display if any const fileUploadDisplays = labelUploadContainer.querySelectorAll( ".file-upload-display" ); setElementsDisplay(fileUploadDisplays, "none"); } else { let allInputs = labelColorOptionsContainer.querySelectorAll("input"); let requiredInputs = labelUploadContainer.querySelectorAll("input"); setElementsDisplay([labelUploadContainer], "block"); setElementsDisplay([labelColorOptionsContainer], "none"); setInputsRequiredTrue(requiredInputs); clearInputs(allInputs, ["labelColor"]); setInputsRequiredFalse(allInputs); } setLabelSubOptions(); getCenterLabelPrice(); getTotalPrice(); }); }); innerSleeveTypeInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(innerSleeveTypeInputs, "innerSleeveType"); let value = document.querySelector( "input[name='sleeve-type']:checked" ).value; let allInputs = sleeveOptionsContainer.querySelectorAll("input"); if (value === "anti-static") { setElementsDisplay([sleeveOptionsContainer], "none"); clearInputs(allInputs, ["innerSleeveColor", "innerSleeveFinish"]); setInputsRequiredFalse(allInputs); // remove file upload display if any const fileUploadDisplays = sleeveOptionsContainer.querySelectorAll( ".file-upload-display" ); setElementsDisplay(fileUploadDisplays, "none"); } else if (value === "printed") { setElementsDisplay( [sleeveOptionsContainer, innerSleeveFinishOuterContainer], "block" ); clearInputs(allInputs, ["innerSleeveColor"]); setInputsRequiredTrue(allInputs); setElementsDisplay([innerSleevePrintedColorOptionsContainer], "flex"); setElementsDisplay([innerSleevePaperColorOptionsContainer], "none"); setElementsDisplay([innerSleeveUploadContainer], "block"); } else { // one of the paper options is selected if ( selected.innerSleeveColor !== "white" && selected.innerSleeveColor !== "black" ) { clearInputs(allInputs, ["innerSleeveColor", "innerSleeveFinish"]); } setInputsRequiredTrue(allInputs); clearInputs(innerSleeveUploadContainer.querySelectorAll("input"), []); const fileUploadDisplays = sleeveOptionsContainer.querySelectorAll( ".file-upload-display" ); setElementsDisplay([sleeveOptionsContainer], "block"); setElementsDisplay( [ innerSleevePrintedColorOptionsContainer, innerSleeveFinishOuterContainer, innerSleeveUploadContainer, ...fileUploadDisplays, ], "none" ); setElementsDisplay([innerSleevePaperColorOptionsContainer], "flex"); setInputsRequiredFalse( innerSleeveFinishContainer.querySelectorAll("input") ); } setSleeveSubOptions(); getInnerSleevePrice(); getTotalPrice(); }); }); printedInsertTypeInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(printedInsertTypeInputs, "printedInsertType"); let value = document.querySelector( "input[name='insert-type']:checked" ).value; let allInputs = insertOptionsContainer.querySelectorAll("input"); if (value === "none") { setElementsDisplay([insertOptionsContainer], "none"); clearInputs(allInputs, [ "printedInsertColor", "printedInsertSides", "printedInsertFinish", ]); setInputsRequiredFalse(allInputs); // remove file upload display if any const fileUploadDisplays = insertOptionsContainer.querySelectorAll( ".file-upload-display" ); setElementsDisplay(fileUploadDisplays, "none"); } else { setElementsDisplay([insertOptionsContainer], "block"); setInputsRequiredTrue(allInputs); } setInsertSubOptions(); getInsertionPrice(); getInsertPrice(); getTotalPrice(); }); }); outerWrapTypeInputs.forEach((input) => { input.addEventListener("change", () => { updateCustomRadioSelection(outerWrapTypeInputs, "outerWrapType"); getInsertionPrice(); getOuterwrapPrice(); getTotalPrice(); }); }); // event listeners for default radio buttons recordOpacityInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(recordOpacityInputs, "recordOpacity"); let typeInputs = shortRunRecordTypeContainer.querySelectorAll("input"); setElementsDisplay( [recordColorDisplayContainer, recordEffectDisplayContainer], "none" ); clearSelectedColors(); setMockupDisplayDiscs(); clearEffects(); if (selected.recordOpacity === "opaque") { for (let t of typeInputs) { if (t.value === "splatter" || t.value === "swirl") { setElementsDisplay( [t.parentElement.parentElement.parentElement], "none" ); } else { setElementsDisplay( [t.parentElement.parentElement.parentElement], "flex" ); } } // clear any previously selected options if (selected.recordType) { selected.recordType = null; for (let t of typeInputs) { t.checked = false; t.parentElement.classList.remove("selected-radio"); } } } else { for (let t of typeInputs) { if (t.value === "black") { setElementsDisplay( [t.parentElement.parentElement.parentElement], "none" ); } else { setElementsDisplay( [t.parentElement.parentElement.parentElement], "flex" ); } } // clear any previously selected options if (selected.recordType) { for (let t of typeInputs) { t.checked = false; t.parentElement.classList.remove("selected-radio"); } } } setRecordColorTypeBasedOnOpacity(); }); }); recordWeightInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(recordWeightInputs, "recordWeight"); getAllPrices(); getTotalPrice(); }); }); jacketColorInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(jacketColorInputs, "jacketColor"); getJacketPrice(); getTotalPrice(); }); }); jacketFinishInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(jacketFinishInputs, "jacketFinish"); getJacketPrice(); getTotalPrice(); }); }); innerSleeveColorInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(innerSleeveColorInputs, "innerSleeveColor"); getInnerSleevePrice(); getTotalPrice(); }); }); innerSleeveFinishInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(innerSleeveFinishInputs, "innerSleeveFinish"); getInnerSleevePrice(); getTotalPrice(); }); }); printedInsertSidesInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(printedInsertSidesInputs, "printedInsertSides"); getInsertPrice(); getTotalPrice(); }); }); printedInsertColorInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(printedInsertColorInputs, "printedInsertColor"); getInsertPrice(); getTotalPrice(); }); }); printedInsertFinishInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(printedInsertFinishInputs, "printedInsertFinish"); getInsertPrice(); getTotalPrice(); }); }); labelColorInputs.forEach((input) => { input.addEventListener("change", () => { updateRadioSelection(labelColorInputs, "labelColor"); }); }); waveTestPressingsInput.addEventListener("change", () => { selected.waveTestPressings = waveTestPressingsInput.checked; if (selected.waveTestPressings === true) { setElementsDisplay([testPressingsInputContainer], "none"); testPressingsInput.min = "0"; testPressingsInput.value = "0"; selected.testPressings = "0"; } else { setElementsDisplay([testPressingsInputContainer], "block"); testPressingsInput.min = "5"; testPressingsInput.value = "5"; selected.testPressings = "5"; testPressingsDisplay.innerText = "5"; } getTestPressingsPrice(); getTotalPrice(); }); // other inputs and ui testPressingsInput.addEventListener("input", () => { selected.testPressings = testPressingsInput.value; testPressingsDisplay.innerText = testPressingsInput.value; }); testPressingsInput.addEventListener("change", () => { getTestPressingsPrice(); getTotalPrice(); }); function getStepSize(quantity) { if (quantity < 1300) return 50; if (quantity < 2000) return 100; if (quantity < 18000) return 500; return 1000; } function roundToStep(quantity, step) { // For the highest range, round to nearest 1000 but allow 25000 if (quantity >= 20000) { const rounded = Math.round(quantity / 1000) * 1000; return rounded === 24000 && quantity > 24000 ? 25000 : rounded; } return Math.round(quantity / step) * step; } quantityInput.addEventListener("input", () => { const quantity = parseInt(quantityInput.value, 10); const step = getStepSize(quantity); const roundedQuantity = roundToStep(quantity, step); quantityInput.step = 50; // Always use step of 50 quantityInput.value = roundedQuantity; selected.quantity = roundedQuantity; // Update mobile input to match mobileQuantityInput.value = selected.quantity; updateSliders(); }); mobileQuantityInput.addEventListener("input", () => { mobileQtyActiveDisplay.classList.add("active"); const quantity = parseInt(mobileQuantityInput.value, 10); const step = getStepSize(quantity); const roundedQuantity = roundToStep(quantity, step); mobileQuantityInput.step = 50; // Always use step of 50 mobileQuantityInput.value = roundedQuantity; selected.quantity = roundedQuantity; // Update desktop input to match quantityInput.value = selected.quantity; updateSliders(); }); function updateSliders() { // desktop slider quantityDisplay.innerText = selected.quantity; let x = selected.quantity - quantityInput.min; let y = quantityInput.max - quantityInput.min; let d = (x / y) * 95; quantityDisplay.style.left = `${d}%`; // mobile slider quantityValueDisplayMobile.innerText = selected.quantity; x = selected.quantity - mobileQuantityInput.min; y = mobileQuantityInput.max - mobileQuantityInput.min; d = (x / y) * 95; quantityValueDisplayMobile.style.left = `${d}%`; // mobile active container mobileQtyActiveDisplay.innerText = selected.quantity; x = selected.quantity - mobileQuantityInput.min; y = mobileQuantityInput.max - mobileQuantityInput.min; d = (x / y) * 95; mobileQtyActiveDisplay.style.left = Math.min(`${d}`, 75) + "%"; } quantityInput.addEventListener("change", () => { setJacketOptions(); getAllPrices(); getTotalPrice(); }); mobileQuantityInput.addEventListener("change", () => { setJacketOptions(); getAllPrices(); getTotalPrice(); mobileQtyActiveDisplay.classList.remove("active"); }); // file upload logic jacketFrontUpload.addEventListener("change", () => { let file = jacketFrontUpload.files[0]; activityTracker.jacketFrontUpload = true; if (file) { let imageUrl = URL.createObjectURL(file); setElementsDisplay([jacketFrontFilenameDisplay.parentElement], "block"); jacketFrontFilenameDisplay.innerText = file.name; jacketVisualDisplay.style.backgroundImage = `url(${imageUrl})`; } else { setElementsDisplay([jacketFrontFilenameDisplay.parentElement], "none"); jacketVisualDisplay.style.backgroundImage = ""; } }); labelFrontUpload.addEventListener("change", () => { let file = labelFrontUpload.files[0]; if (file) { setElementsDisplay([labelFrontFilenameDisplay.parentElement], "block"); labelFrontFilenameDisplay.innerText = file.name; } else { setElementsDisplay([labelFrontFilenameDisplay.parentElement], "none"); } }); innerSleeveUpload.addEventListener("change", () => { let file = innerSleeveUpload.files[0]; activityTracker.innerSleeveUpload = true; if (file) { setElementsDisplay([sleeveFilenameDisplay.parentElement], "block"); sleeveFilenameDisplay.innerText = file.name; } else { setElementsDisplay([sleeveFilenameDisplay.parentElement], "none"); } }); printedInsertUpload.addEventListener("change", () => { let file = printedInsertUpload.files[0]; if (file) { setElementsDisplay([insertFilenameDisplay.parentElement], "block"); insertFilenameDisplay.innerText = file.name; } else { setElementsDisplay([insertFilenameDisplay.parentElement], "none"); } }); // upload file remove event listeners removeJacketFrontImage.addEventListener("click", () => { jacketFrontUpload.value = ""; setElementsDisplay([jacketFrontFilenameDisplay.parentElement], "none"); jacketVisualDisplay.style.backgroundImage = ""; }); removeLabelFrontImage.addEventListener("click", () => { labelFrontUpload.value = ""; setElementsDisplay([labelFrontFilenameDisplay.parentElement], "none"); }); removeSleeveImage.addEventListener("click", () => { innerSleeveUpload.value = ""; setElementsDisplay([sleeveFilenameDisplay.parentElement], "none"); }); removeInsertImage.addEventListener("click", () => { printedInsertUpload.value = ""; setElementsDisplay([insertFilenameDisplay.parentElement], "none"); }); function clearSelectedColors() { recordVisualDisplay.style.backgroundImage = `url(${recordVisualUrls.noSelection})`; recordColorInput.value = ""; effectColorInput.value = ""; effectColorTwoInput.value = ""; effectColorThreeInput.value = ""; selected.recordColorName = null; selected.recordColorSku = null; selected.effectColorName = null; selected.effectColorSku = null; selected.effectColorTwoName = null; selected.effectColorTwoSku = null; selected.effectColorThreeName = null; selected.effectColorThreeSku = null; setElementsDisplay( [ recordTypeEffectDisplay, recordTypeEffectDisplayTwo, recordTypeEffectDisplayThree, recordColorDisplayContainer, ], "none" ); } // modal logic pricingBreakdownButton.addEventListener("click", (e) => { e.stopPropagation(); e.preventDefault(); document.body.style.overflow = "hidden"; modalBackground.classList.add("visible"); updatePricingBreakdownDisplays(); }); pricingBreakdownButtonMobile.addEventListener("click", (e) => { e.stopPropagation(); e.preventDefault(); document.body.style.overflow = "hidden"; modalBackground.classList.add("visible"); updatePricingBreakdownDisplays(); }); builderSubmitButton.addEventListener("click", () => { document.body.style.overflow = "auto"; modalBackground.classList.remove("visible"); }); continueEditingButton.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); document.body.style.overflow = "auto"; modalBackground.classList.remove("visible"); }); function formatPrice(num) { num = parseFloat(num); if (isNaN(num)) { return "0.00"; } return num.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2, }); } function updatePricingBreakdownDisplays() { projectTitleDisplay.innerText = projectTitleInput.value || "Project Title"; masteringBreakdownDisplay.innerText = "$" + formatPrice(preFlightPrice); setupFeeBreakdownDisplay.innerText = "$" + formatPrice(setupPrice); cuttingFeeBreakdownDisplay.innerText = "$" + formatPrice(cuttingPrice); platingFeeBreakdownDisplay.innerText = "$" + formatPrice(platingPrice); stampersFeeBreakdownDisplay.innerText = "$" + formatPrice(stampersPrice); stampersCountDisplay.innerText = "$" + formatPrice(stampersPrice); testPressingsFeeBreakdownDisplay.innerText = "$" + formatPrice( testPressingsPrice + additionalTestPressingsPrice + testPressingsShippingPrice ); centerLabelFeeBreakdownDisplay.innerText = "$" + formatPrice(centerLabelsPrice); recordsFeeBreakdownDisplay.innerText = "$" + formatPrice(recordPrice); innerSleeveFeeBreakdownDisplay.innerText = "$" + formatPrice(innerSleevePrice); jacketFeeBreakdownDisplay.innerText = "$" + formatPrice(jacketsPrice); insertFeeBreakdownDisplay.innerText = "$" + formatPrice(insertsPrice); outerwrapFeeBreakdownDisplay.innerText = "$" + formatPrice(outerwrapPrice); downloadCardsFeeBreakdownDisplay.innerText = "$" + formatPrice(downloadCardsPrice); miscFeeBreakdownDisplay.innerText = "$" + formatPrice(miscPrice); insertionFeeBreakdownDisplay.innerText = "$" + formatPrice(insertionPrice); // update sub-item prices masteringBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(preFlightPrice); setupFeeBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(setupPrice); cuttingBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(cuttingPrice); platingBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(platingPrice); testPressingsInitialPriceDisplay.innerText = "$" + formatPrice(testPressingsPrice); additionalTestPressingsPriceDisplay.innerText = "$" + formatPrice(additionalTestPressingsPrice); testPressingsShippingPriceDisplay.innerText = "$" + formatPrice(testPressingsShippingPrice); centerLabelBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(centerLabelsPrice); recordBreakdownOptionsPriceDisplay.innerText = "$" + formatPrice(recordPrice); sleeveBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(innerSleevePrice); jacketBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(jacketsPrice); insertBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(insertsPrice); outerwrapBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(outerwrapPrice); downloadCardBreakdownOptionPriceDisplay.innerText = "$" + formatPrice(downloadCardsPrice); insertionOfSleevePriceDisplay.innerText = "$" + formatPrice(insertionOfInnerSleevePrice); insertionOfInsertPriceDisplay.innerText = "$" + formatPrice(insertionOfPrintedInsertPrice); insertionOfJacketPriceDisplay.innerText = "$" + formatPrice(insertionOfJacketPrice); // update inner text of all sub-item displays breakdownRpmDisplay.innerText = selected.rpm + " RPM"; if (selected.recordColorName) { breakdownBaseColorDisplay.parentElement.parentElement.parentElement.style.display = "flex"; breakdownBaseColorDisplay.innerText = selected.recordColorName; } else { breakdownBaseColorDisplay.parentElement.parentElement.parentElement.style.display = "none"; } if (selected.effectColorName) { breakdownEffectColorOneDisplay.parentElement.parentElement.parentElement.style.display = "flex"; breakdownEffectColorOneDisplay.innerText = selected.effectColorName; } else { breakdownEffectColorOneDisplay.parentElement.parentElement.parentElement.style.display = "none"; } if (selected.effectColorTwoName) { breakdownEffectColorTwoDisplay.parentElement.parentElement.parentElement.style.display = "flex"; breakdownEffectColorTwoDisplay.innerText = selected.effectColorTwoName; } else { breakdownEffectColorTwoDisplay.parentElement.parentElement.parentElement.style.display = "none"; } if (selected.effectColorThreeName) { breakdownEffectColorThreeDisplay.parentElement.parentElement.parentElement.style.display = "flex"; breakdownEffectColorThreeDisplay.innerText = selected.effectColorThreeName; } else { breakdownEffectColorThreeDisplay.parentElement.parentElement.parentElement.style.display = "none"; } if (preFlightPrice === 0) { masteringBreakdownDisplay.parentElement.style.display = "none"; masteringBreakdownOptionDisplay.parentElement.style.display = "none"; } else { masteringBreakdownDisplay.parentElement.style.display = "flex"; masteringBreakdownOptionDisplay.parentElement.style.display = "flex"; } if (setupPrice === 0) { setupFeeBreakdownDisplay.parentElement.style.display = "none"; setupFeeBreakdownOptionDisplay.parentElement.style.display = "none"; } else { setupFeeBreakdownDisplay.parentElement.style.display = "flex"; setupFeeBreakdownOptionDisplay.parentElement.style.display = "flex"; setupFeeBreakdownOptionDisplay.innerText = toTitleCase(selected.amount) + " LP"; } if (cuttingPrice === 0) { cuttingFeeBreakdownDisplay.parentElement.style.display = "none"; cuttingBreakdownOptionDisplay.parentElement.style.display = "none"; } else { cuttingFeeBreakdownDisplay.parentElement.style.display = "flex"; cuttingBreakdownOptionDisplay.parentElement.style.display = "flex"; cuttingBreakdownOptionDisplay.innerText = toTitleCase("Laquer"); // cuttingBreakdownOptionDisplay.innerText = toTitleCase( // selected.recordCutting // ); } if (platingPrice === 0) { platingFeeBreakdownDisplay.parentElement.style.display = "none"; platingBreakdownOptionDisplay.parentElement.style.display = "none"; platingDisplayInput.value = "None"; } else { platingFeeBreakdownDisplay.parentElement.style.display = "flex"; platingBreakdownOptionDisplay.parentElement.style.display = "flex"; platingBreakdownOptionDisplay.innerText = "2-Step Plating"; platingDisplayInput.value = "2-Step Plating"; } if (stampersPrice === 0) { stampersFeeBreakdownDisplay.parentElement.style.display = "none"; stampersCountDisplay.parentElement.style.display = "none"; } else { stampersFeeBreakdownDisplay.parentElement.style.display = "flex"; stampersCountDisplay.parentElement.style.display = "flex"; stampersCountDisplay.innerText = `${selected.stampersCount} Additional Stampers`; stampersPriceDisplay.innerText = "$" + formatPrice(stampersPrice); additionalStampersCountInput.value = selected.stampersCount; } if (testPressingsPrice === 0) { testPressingsFeeBreakdownDisplay.parentElement.style.display = "none"; testPressingsInitialPriceDisplay.parentElement.style.display = "none"; } else { testPressingsFeeBreakdownDisplay.parentElement.style.display = "flex"; testPressingsInitialPriceDisplay.parentElement.style.display = "flex"; } if (additionalTestPressingsPrice === 0) { additionalTestPressingsPriceDisplay.parentElement.style.display = "none"; } else { additionalTestPressingsPriceDisplay.parentElement.style.display = "flex"; numOfAdditionalPressingsDisplay.innerText = selected.testPressings - 5; } if (testPressingsShippingPrice === 0) { testPressingsShippingPriceDisplay.parentElement.style.display = "none"; } else { testPressingsShippingPriceDisplay.parentElement.style.display = "flex"; } if (centerLabelsPrice === 0) { centerLabelFeeBreakdownDisplay.parentElement.style.display = "none"; centerLabelBreakdownOptionDisplay.parentElement.style.display = "none"; } else { centerLabelFeeBreakdownDisplay.parentElement.style.display = "flex"; centerLabelBreakdownOptionDisplay.parentElement.style.display = "flex"; centerLabelBreakdownOptionDisplay.innerText = toTitleCase( selected.labelType ); } if (recordPrice === 0) { recordsFeeBreakdownDisplay.parentElement.style.display = "none"; recordBreakdownOptionsPriceDisplay.parentElement.style.display = "none"; } else { recordsFeeBreakdownDisplay.parentElement.style.display = "flex"; recordBreakdownOptionsPriceDisplay.parentElement.style.display = "flex"; recordSizeBreakdownDisplay.innerText = selected.recordSize + " Inch"; recordWeightBreakdownDisplay.innerText = toTitleCase(selected.recordWeight); recordTypeBreakdownDisplay.innerText = toTitleCase(selected.recordType); } if (innerSleevePrice === 0) { innerSleeveFeeBreakdownDisplay.parentElement.style.display = "none"; sleeveBreakdownOptionPriceDisplay.parentElement.style.display = "none"; } else { innerSleeveFeeBreakdownDisplay.parentElement.style.display = "flex"; sleeveBreakdownOptionPriceDisplay.parentElement.style.display = "flex"; sleeveTypeBreakdownDisplay.innerText = toTitleCase( selected.innerSleeveType ); sleeveColorBreakdownDisplay.innerText = toTitleCase( selected.innerSleeveColor ); sleeveFinishBreakdownDisplay.innerText = toTitleCase( selected.innerSleeveFinish ); } if (jacketsPrice === 0) { jacketFeeBreakdownDisplay.parentElement.style.display = "none"; jacketBreakdownOptionPriceDisplay.parentElement.style.display = "none"; } else { jacketFeeBreakdownDisplay.parentElement.style.display = "flex"; jacketBreakdownOptionPriceDisplay.parentElement.style.display = "flex"; jacketTypeBreakdownDisplay.innerText = toTitleCase(selected.jacketType); jacketColorBreakdownDisplay.innerText = toTitleCase(selected.jacketColor); jacketFinishBreakdownDisplay.innerText = toTitleCase(selected.jacketFinish); } if (insertsPrice === 0) { insertFeeBreakdownDisplay.parentElement.style.display = "none"; insertBreakdownOptionPriceDisplay.parentElement.style.display = "none"; } else { insertFeeBreakdownDisplay.parentElement.style.display = "flex"; insertBreakdownOptionPriceDisplay.parentElement.style.display = "flex"; insertTypeBreakdownDisplay.innerText = toTitleCase( selected.printedInsertType ); insertSidesBreakdownDisplay.innerText = toTitleCase( selected.printedInsertSides ); insertColorBreakdownDisplay.innerText = toTitleCase( selected.printedInsertColor ); insertFinishBreakdownDisplay.innerText = toTitleCase( selected.printedInsertFinish ); } if (outerwrapPrice === 0) { outerwrapFeeBreakdownDisplay.parentElement.style.display = "none"; outerwrapBreakdownOptionPriceDisplay.parentElement.style.display = "none"; } else { outerwrapFeeBreakdownDisplay.parentElement.style.display = "flex"; outerwrapBreakdownOptionPriceDisplay.parentElement.style.display = "flex"; outerwrapBreakdownOptionDisplay.innerText = toTitleCase( selected.outerWrapType ); } if (downloadCardsPrice === 0) { downloadCardsFeeBreakdownDisplay.parentElement.style.display = "none"; downloadCardBreakdownOptionPriceDisplay.parentElement.style.display = "none"; } else { downloadCardsFeeBreakdownDisplay.parentElement.style.display = "flex"; downloadCardBreakdownOptionPriceDisplay.parentElement.style.display = "flex"; downloadCardBreakdownOptionDisplay.innerText = toTitleCase( selected.downloadCardType ); } if (miscPrice === 0) { miscFeeBreakdownDisplay.parentElement.style.display = "none"; } else { miscFeeBreakdownDisplay.parentElement.style.display = "flex"; } if (insertionPrice === 0) { insertionFeeBreakdownDisplay.parentElement.style.display = "none"; } else { insertionFeeBreakdownDisplay.parentElement.style.display = "flex"; } if (insertionOfInnerSleevePrice === 0) { insertionOfSleevePriceDisplay.parentElement.style.display = "none"; } else { insertionOfSleevePriceDisplay.parentElement.style.display = "flex"; } if (insertionOfPrintedInsertPrice === 0) { insertionOfInsertPriceDisplay.parentElement.style.display = "none"; } else { insertionOfInsertPriceDisplay.parentElement.style.display = "flex"; } if (insertionOfJacketPrice === 0) { insertionOfJacketPriceDisplay.parentElement.style.display = "none"; } else { insertionOfJacketPriceDisplay.parentElement.style.display = "flex"; } orderTotalDisplay.innerText = "$" + formatPrice(totalPrice); orderTotalPerUnitDisplay.innerText = "$" + formatPrice(totalPrice / selected.quantity) + "/copy"; } closeModalButton.addEventListener("click", (e) => { e.stopPropagation(); document.body.style.overflow = "auto"; modalBackground.classList.remove("visible"); }); breakdownContainer.addEventListener("click", (e) => { e.stopPropagation(); }); modalBackground.addEventListener("click", (e) => { e.stopPropagation(); }); function checkRequiredInputs() { // I am doing this so that clicking the missing section link will actually take you to the // input. Without it if the first input is hidden it will not work let requiredInputs = Array.from( document.querySelectorAll("input[required]") ).filter((el) => { return ( window.getComputedStyle(el.parentElement.parentElement).display !== "none" && window.getComputedStyle(el.parentElement.parentElement.parentElement) .display !== "none" ); }); let usedInputs = new Set(); let isComplete = true; requiredInputs.forEach((input) => { if (!input.checkValidity() && !usedInputs.has(input.getAttribute("name"))) { isComplete = false; usedInputs.add(input.getAttribute("name")); setElementsDisplay([missingInfoContainer], "block"); let arrow = ` `; let p = document.createElement("p"); p.innerHTML = arrow + "  " + input.getAttribute("name").replaceAll("-", " "); p.classList.add("missing-info-p"); missingInfoDisplay.appendChild(p); p.addEventListener("click", () => scollToInput(input)); } }); if (isComplete) { updatePricingBreakdownDisplays(); modalBackground.classList.add("visible"); } } prepareToSubmit.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); setElementsDisplay([missingInfoContainer], "none"); Array.from(missingInfoDisplay.children).forEach((child) => { child.parentElement.removeChild(child); }); checkRequiredInputs(); }); function scollToInput(node) { let yOffset = node.getBoundingClientRect().y; let y = window.scrollY; window.scroll({ left: 0, top: y + yOffset - 200, behavior: "smooth" }); } // pricing logic let prices = null; let preFlightPrice = 0; let setupPrice = 0; let cuttingPrice = 0; let platingPrice = 360; let stampersPrice = 0; let testPressingsPrice = 0; let additionalTestPressingsPrice = 0; let testPressingsShippingPrice = 0; let centerLabelsPrice = 0; let recordPrice = 0; let innerSleevePrice = 0; let jacketsPrice = 0; let insertsPrice = 0; let downloadCardsPrice = 0; let outerwrapPrice = 0; let insertionPrice = 0; let insertionOfInnerSleevePrice = 0; let insertionOfPrintedInsertPrice = 0; let insertionOfJacketPrice = 0; let miscPrice = 0; let totalPrice = 0; const defaultBreakpoints = [ "100", "200", "300", "400", "500", "750", "1000", "1500", "2000", "3000", "4000", "5000", "6000", "7000", "8000", "9000", "10000", "12500", "15000", "17500", "20000", "25000", ]; const superiorBreakpoints = [ "100", "150", "200", "250", "300", "400", "500", "750", "1000", "1250", "1500", "1750", "2000", "2500", "5000", "7500", "10000", ]; function getDefaultBreakpoint(num) { num = parseInt(num); if (num < parseInt(defaultBreakpoints[0])) { return defaultBreakpoints[0]; } for (let i = 1; i < defaultBreakpoints.length; i++) { if (num < parseInt(defaultBreakpoints[i])) { return defaultBreakpoints[i - 1]; } } return defaultBreakpoints.at(-1); } function getSuperiorBreakpoint(num) { num = parseInt(num); if (num < parseInt(superiorBreakpoints[0])) { return superiorBreakpoints[0]; } for (let i = 1; i < superiorBreakpoints.length; i++) { if (num < parseInt(superiorBreakpoints[i])) { return superiorBreakpoints[i - 1]; } } return superiorBreakpoints.at(-1); } async function fetchPrices() { try { const res = await fetch( "https://echobase-backend-v9fx.onrender.com/record-builder" ); if (!res.ok) { console.error("Backend returned an error:", res.status); prices = null; return; } const data = await res.json(); if (!data?.data?.board1 || !Array.isArray(data.data.board1)) { console.error("Invalid data format. Expected board1 array."); prices = null; return; } const board = data.data.board1[0]; const items = board?.items_page?.items ?? []; prices = {}; items.forEach((item) => { const idCol = item.column_values.find((el) => el.id === "text__1"); const priceCol = item.column_values.find((el) => el.id === "numbers__1"); if (idCol && priceCol) { prices[idCol.text] = priceCol.text; } }); getAllPrices(); getTotalPrice(); } catch (err) { console.error("Fetch failed:", err); prices = null; } } function getPreFlightPrice() { if (!prices || !selected.amount) { preFlightPrice = 0; return; } // we are only using echobase pricing for the preflight price if (selected.amount === "single") { preFlightPrice = parseFloat(prices["PF001"]); } else if (selected.amount === "double") { preFlightPrice = parseFloat(prices["PF002"]); } else { preFlightPrice = parseFloat(prices["PF003"]); } if (isNaN(preFlightPrice)) { console.error("error getting pre flight price"); preFlightPrice = 0; } } function getSetupFeePrice() { if (!prices || !selected.amount) { setupPrice = 0; return; } let baseFee = 0; if (selected.quantity <= 100) { baseFee = parseFloat(prices["SU002"]); } else { baseFee = parseFloat(prices["SU001"]); } if (selected.amount === "single") { setupPrice = baseFee; } else if (selected.amount === "double") { setupPrice = baseFee * 2; } else { setupPrice = baseFee * 3; } if (isNaN(setupPrice)) { console.error("error getting set up fee price"); setupPrice = 0; } } const cuttingMap = { 12: "12", 10: "12", 7: "07", lacquer: "LAC", }; function getCuttingPrice() { if (!prices || !selected.amount || selected.recordCutting === "no") { cuttingPrice = 0; return; } if (selected.amount === "single") { cuttingPrice = parseFloat(prices["CT001"]) * 2; } else if (selected.amount === "double") { cuttingPrice = parseFloat(prices["CT001"]) * 4; } else { cuttingPrice = parseFloat(prices["CT001"]) * 6; } if (isNaN(cuttingPrice)) { console.error("error getting cutting price"); cuttingPrice = 0; } } const platingMap = { 12: "12", 10: "12", 7: "07", lacquer: "LAC", }; function getPlatingPrice() { if ( !prices || !selected.amount || !selected.recordCutting || !selected.recordSize ) { platingPrice = 360; return; } if (selected.amount === "single") { platingPrice = parseFloat(prices["PLT001"]) * 2; } else if (selected.amount === "double") { platingPrice = parseFloat(prices["PLT001"]) * 4; } else { platingPrice = parseFloat(prices["PLT001"]) * 6; } if (isNaN(platingPrice)) { console.error("error getting plating price"); platingPrice = 0; } } const stampersMap = { standard: "140G", heavyweight: "180G", }; function getStampersPrice() { if (!prices || !selected.recordWeight) { stampersPrice = 0; return; } const stampersCount = Math.floor(selected.quantity / 1000); selected.stampersCount = stampersCount; stampersPrice = stampersCount * parseFloat(prices["AS001"]); selected.stampersPrice = stampersPrice; if (selected.amount === "double") { stampersPrice *= 2; } if (isNaN(stampersPrice)) { console.error("error getting stampers price"); stampersPrice = 0; } } function getTestPressingsPrice() { testPressingsPrice = 0; additionalTestPressingsPrice = 0; testPressingsShippingPrice = 0; if (!prices) { return; } if (selected.testPressings === "0") { return; } else { testPressingsPrice = parseFloat(prices["TP001"]); testPressingsShippingPrice = 0; if (selected.testPressings > 5) { let additionalTests = parseFloat(selected.testPressings) - 5; additionalTestPressingsPrice = parseFloat(prices["AT001"]) * additionalTests; } } if (selected.amount === "double") { testPressingsPrice *= 2; additionalTestPressingsPrice *= 2; } if (isNaN(testPressingsPrice)) { console.error("error getting test pressings price"); testPressingsPrice = 0; } if (isNaN(additionalTestPressingsPrice)) { console.error("error getting additional test pressings price"); additionalTestPressingsPrice = 0; } if (isNaN(testPressingsShippingPrice)) { console.error("error getting test pressings shipping price"); testPressingsShippingPrice = 0; } } const labelMap = { "black and white": "BW", "full color": "FC", }; function getCenterLabelPrice() { if (!prices || !selected.labelType) { centerLabelsPrice = 0; return; } if (selected.quantity <= 250) { let lookupNumber = "CL001"; centerLabelsPrice = parseFloat(prices[lookupNumber]); } else if (selected.quantity <= 500) { let lookupNumber = "CL002"; centerLabelsPrice = parseFloat(prices[lookupNumber]); } else if (selected.quantity <= 1000) { let lookupNumber = "CL003"; centerLabelsPrice = parseFloat(prices[lookupNumber]); } else { let labelsRemainingCount = selected.quantity - 1000; centerLabelsPrice = parseFloat(prices["CL003"]); while (labelsRemainingCount > 0) { labelsRemainingCount -= 1000; centerLabelsPrice += parseFloat(prices["CL004"]); } } if (selected.amount === "double") { centerLabelsPrice *= 2; } else if (selected.amount === "triple") { centerLabelsPrice *= 3; } if (isNaN(centerLabelsPrice)) { console.error("error getting center label price"); centerLabelsPrice = 0; } } const recordMap = { black: "CB", color: "SC", splatter: "SP", swirl: "SW", 7: "07R", 12: "12R", 10: "12R", standard: "SV", heavyweight: "HV", }; function getRecordPrice() { if ( !prices || !selected.recordSize || !selected.recordType || !selected.recordWeight ) { recordPrice = 0; return; } let useShortRunPricing = false; let lookupNumber = recordMap[selected.recordWeight] + recordMap[selected.recordType] + recordMap[selected.recordSize]; recordPrice = parseFloat(prices[lookupNumber]) * parseFloat(selected.quantity); if (selected.amount === "double") { recordPrice *= 2; } if (isNaN(recordPrice)) { console.error("error getting record price"); recordPrice = 0; } } const innerSleeveMap = { paper: "SP", "paper w/ poly lining": "PP", "anti-static": "AS", printed: "PI", white: "WH", black: "BL", "black & white": "BW", "full color": "FC", 12: "12R", 10: "12R", 7: "07R", }; function getInnerSleevePrice() { if (!prices || !selected.innerSleeveType) { innerSleevePrice = 0; return; } let lookupNumber = ""; const priceBreakPoint = getSuperiorBreakpoint(selected.quantity); if (selected.innerSleeveType === "paper") { if (selected.innerSleeveColor === "white") { lookupNumber = "SI001"; } else { lookupNumber = "SI002"; } } else if (selected.innerSleeveType === "anti-static") { lookupNumber = "SI005"; } else { lookupNumber = `${innerSleeveMap[selected.innerSleeveType]}${ innerSleeveMap[selected.recordSize] }FC${priceBreakPoint}-SUP`; } innerSleevePrice = parseFloat(prices[lookupNumber]) * parseFloat(selected.quantity); let upcharge; if (selected.innerSleeveFinish === "gloss") { upcharge = parseFloat(prices[`MISC-FG${priceBreakPoint}`]) * parseFloat(selected.quantity); innerSleevePrice = innerSleevePrice + upcharge; } else if (selected.innerSleeveFinish === "matte") { upcharge = parseFloat(prices[`MISC-MA${priceBreakPoint}`]) * parseFloat(selected.quantity); innerSleevePrice = innerSleevePrice + upcharge; } else if (selected.innerSleeveFinish === "reverse board") { upcharge = parseFloat(prices[`MISC-RB${priceBreakPoint}`]) * parseFloat(selected.quantity); innerSleevePrice = innerSleevePrice + upcharge; } if (selected.amount === "double") { innerSleevePrice *= 2; } if (isNaN(innerSleevePrice)) { console.error("error getting inner sleeve price"); innerSleevePrice = 0; } } const jacketMap = { "single pocket": "SP", "wide spine": "WS", gatefold: "GF", "euro-sleeve": "ES", 12: "12R", 10: "12R", 7: "07R", "black & white": "BW", "full color": "FC", }; const finishMap = { gloss: "FG", matte: "MA", "reverse board": "RB", "semi-gloss": "SG", }; function getJacketPrice() { if (!prices || !selected.jacketType || selected.jacketType === "none") { jacketsPrice = 0; return; } let priceBreakPoint = 0; let lookupNumber = ""; let finishLookUp = ""; if ( selected.jacketType === "single pocket" || selected.jacketType === "wide spine" || selected.jacketType === "gatefold" ) { priceBreakPoint = getSuperiorBreakpoint(selected.quantity); lookupNumber = `JKT${jacketMap[selected.jacketType]}${ jacketMap[selected.recordSize] }FC${getSuperiorBreakpoint(selected.quantity)}-SUP`; finishLookUp = `MISC-${ finishMap[selected.jacketFinish] }${getSuperiorBreakpoint(selected.quantity)}`; } else { priceBreakPoint = getDefaultBreakpoint(selected.quantity); lookupNumber = `JKT${jacketMap[selected.jacketType]}${ jacketMap[selected.recordSize] }FC${getDefaultBreakpoint(selected.quantity)}`; finishLookUp = `MISC-${ finishMap[selected.jacketFinish] }${getDefaultBreakpoint(selected.quantity)}`; } let upcharge = selected.jacketFinish === "semi-gloss" ? 0 : parseFloat( prices[`MISC-${finishMap[selected.jacketFinish]}${priceBreakPoint}`] ) * parseFloat(selected.quantity); jacketsPrice = parseFloat(prices[lookupNumber]) * selected.quantity + upcharge; if (isNaN(jacketsPrice)) { console.error("error getting jacket price"); jacketsPrice = 0; } } const insertMap = { "7x7": "7x7", "14x7": "14x7", "12x12": "12x12", "24x12": "24x12", "one sided": "1S", "two sided": "2S", "black & white": "BW", "full color": "FC", }; function getInsertPrice() { if (!prices || !selected.printedInsertType) { insertsPrice = 0; return; } let upcharge; let priceBreakPoint; if (selected.printedInsertType === "none") { insertsPrice = 0; } else { if (selected.printedInsertType === "12x12") { let lookupNumber = "INS" + insertMap[selected.printedInsertType] + "2S" + "FC" + getSuperiorBreakpoint(selected.quantity) + "-SUP"; insertsPrice = parseFloat(prices[lookupNumber]) * parseFloat(selected.quantity); priceBreakPoint = getSuperiorBreakpoint(selected.quantity); } else if (selected.printedInsertType === "24x12") { let lookupNumber = "INS" + insertMap[selected.printedInsertType] + "2S" + "FC" + getSuperiorBreakpoint(selected.quantity); insertsPrice = parseFloat(prices[lookupNumber]) * parseFloat(selected.quantity); priceBreakPoint = getSuperiorBreakpoint(selected.quantity); } else if (selected.printedInsertType === "14x7") { insertsPrice = 0; priceBreakPoint = getDefaultBreakpoint(selected.quantity); } else if (selected.printedInsertType === "7x7") { insertsPrice = 0; priceBreakPoint = getDefaultBreakpoint(selected.quantity); } else { insertsPrice = 0; } } if (selected.printedInsertFinish === "gloss") { upcharge = parseFloat(prices[`MISC-FG${priceBreakPoint}`]) * parseFloat(selected.quantity); insertsPrice = insertsPrice + upcharge; } else if (selected.printedInsertFinish === "matte") { upcharge = parseFloat(prices[`MISC-MA${priceBreakPoint}`]) * parseFloat(selected.quantity); insertsPrice = insertsPrice + upcharge; } else if (selected.printedInsertFinish === "reverse board") { upcharge = parseFloat(prices[`MISC-RB${priceBreakPoint}`]) * parseFloat(selected.quantity); insertsPrice = insertsPrice + upcharge; } if (isNaN(insertsPrice)) { console.error("error getting insert price"); insertsPrice = 0; } } function getDownloadCardsPrice() { if (!prices || !selected.downloadCardType) { downloadCardsPrice = 0; return; } if (selected.downloadCardType === "none") { downloadCardsPrice = 0; } else { downloadCardsPrice = parseFloat(prices["DLC001"]) * parseFloat(selected.quantity); } if (isNaN(downloadCardsPrice)) { console.error("error getting download cards price"); downloadCardsPrice = 0; } } function getOuterwrapPrice() { if (!prices || !selected.outerWrapType) { outerwrapPrice = 0; return; } if (selected.outerWrapType === "none") { outerwrapPrice = 0; return; } else { if (selected.outerWrapType === "none") { outerwrapPrice = 0; } else if (selected.outerWrapType === "shrinkwrap") { outerwrapPrice = parseFloat(prices["OW001"]) * parseFloat(selected.quantity); } else if (selected.outerWrapType === "polybag") { if (selected.quantity <= 100) { outerwrapPrice = parseFloat(prices["OW003"]) * parseFloat(selected.quantity); } else { outerwrapPrice = parseFloat(prices["OW002"]) * parseFloat(selected.quantity); } } } if (isNaN(outerwrapPrice)) { console.error("error getting outerwrap price"); outerwrapPrice = 0; } } function getInsertionPrice() { insertionPrice = 0; insertionOfInnerSleevePrice = 0; insertionOfPrintedInsertPrice = 0; insertionOfJacketPrice = 0; if (!prices) { return; } let lookupNumber = "IA001"; // first one is the sleeve which is always there if (selected.amount === "single") { insertionOfInnerSleevePrice = parseFloat(prices[lookupNumber]) * parseFloat(selected.quantity); } else if (selected.amount === "double") { insertionOfInnerSleevePrice = parseFloat(prices[lookupNumber]) * parseFloat(selected.quantity) * 2; } else { insertionOfInnerSleevePrice = parseFloat(prices[lookupNumber]) * parseFloat(selected.quantity) * 3; } if (selected.jacketType !== "none") { if (selected.amount === "single") { insertionOfJacketPrice = prices[lookupNumber] * parseFloat(selected.quantity); } else if (selected.amount === "double") { insertionOfJacketPrice = prices[lookupNumber] * parseFloat(selected.quantity) * 2; } else { insertionOfJacketPrice = prices[lookupNumber] * parseFloat(selected.quantity) * 3; } } if (selected.printedInsertType !== "none") { insertionOfPrintedInsertPrice = prices[lookupNumber] * parseFloat(selected.quantity); } insertionPrice = insertionOfInnerSleevePrice + insertionOfPrintedInsertPrice + insertionOfJacketPrice; if (isNaN(insertionPrice)) { console.error("error getting insertion price"); insertionPrice = 0; insertionOfInnerSleevePrice = 0; insertionOfPrintedInsertPrice = 0; insertionOfJacketPrice = 0; } } function getMiscPrice() { if (!prices) { miscPrice = 0; return; } } function getAllPrices() { getPreFlightPrice(); getSetupFeePrice(); getCuttingPrice(); getPlatingPrice(); getStampersPrice(); getTestPressingsPrice(); getCenterLabelPrice(); getRecordPrice(); getInnerSleevePrice(); getJacketPrice(); getInsertPrice(); getDownloadCardsPrice(); getOuterwrapPrice(); getInsertionPrice(); getMiscPrice(); } function getTotalPrice() { totalPrice = preFlightPrice + setupPrice + cuttingPrice + platingPrice + stampersPrice + testPressingsPrice + additionalTestPressingsPrice + testPressingsShippingPrice + centerLabelsPrice + recordPrice + innerSleevePrice + jacketsPrice + insertsPrice + downloadCardsPrice + outerwrapPrice + insertionPrice + miscPrice; sliderTotalPriceDisplay.innerText = "$" + formatPrice(totalPrice); sliderTotalPriceDisplayPerUnit.innerText = "$" + formatPrice(totalPrice / selected.quantity); sliderTotalPriceDisplayMobile.innerText = "$" + formatPrice(totalPrice); sliderTotalPriceDisplayPerUnitMobile.innerText = "$" + formatPrice(totalPrice / selected.quantity); // update hidden price inputs preFlightPriceInput.value = formatPrice(preFlightPrice); setupPriceInput.value = formatPrice(setupPrice); cuttingPriceInput.value = formatPrice(cuttingPrice); platingPriceInput.value = formatPrice(platingPrice); stampersPriceInput.value = formatPrice(stampersPrice); testPressingsPriceInput.value = formatPrice(testPressingsPrice); centerLabelPriceInput.value = formatPrice(centerLabelsPrice); recordPriceInput.value = formatPrice(recordPrice); innerSleevePriceIput.value = formatPrice(innerSleevePrice); jacketPriceInput.value = formatPrice(jacketsPrice); insertPriceInput.value = formatPrice(insertsPrice); downloadCardPriceInput.value = formatPrice(downloadCardsPrice); outerwrapPriceInput.value = formatPrice(outerwrapPrice); insertionPriceInput.value = formatPrice(insertionPrice); miscPriceInput.value = formatPrice(miscPrice); totalPriceInput.value = formatPrice(totalPrice); pricePerInputUnit.value = formatPrice( parseFloat(totalPrice) / parseFloat(selected.quantity) ); additionalTestPressingsPriceInput.value = formatPrice( additionalTestPressingsPrice ); testPressingsShippingFeeInput.value = formatPrice(testPressingsShippingPrice); insertionOfInnerSleevePriceInput.value = formatPrice( insertionOfInnerSleevePrice ); insertionOfPrintedInsertPriceInput.value = formatPrice( insertionOfPrintedInsertPrice ); insertionOfJacketPriceInput.value = formatPrice(insertionOfJacketPrice); testPressingsTotalPriceInput.value = formatPrice( testPressingsPrice + additionalTestPressingsPrice + testPressingsShippingPrice ); platingDisplayInput.value = "2-Step Plating"; additionalTestPressingsInput.value = Math.max(selected.testPressings - 5, 0); } fetchPrices(); function toTitleCase(str) { if (typeof str !== "string" || !str.length) { return str; } let arr = str.split(""); if (arr[0] !== " ") { arr[0] = arr[0].toUpperCase(); } for (let i = 1; i < arr.length; i++) { if (arr[i - 1] === " " || arr[i - 1] === "-") { arr[i] = arr[i].toUpperCase(); } } return arr.join(""); } window.Webflow ||= []; window.Webflow.push(() => { const form = document.getElementById("wf-form-Record-Builder-Form"); form.addEventListener("submit", () => { if (jacketFrontUpload.value === "") { jacketFrontUpload.value = "C:\fakepathVC_logo.png"; } // Update the quantity input value based on which input was last used if (lastUsedInput === "mobile") { quantityInput.value = mobileQuantityInput.value; } form.querySelectorAll("input").forEach((input) => { input.value = toTitleCase(input.value) || null; }); }); }); // canvas logic function initEffect(imageUrl, layerObject, color = "#000000") { return new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = "anonymous"; img.src = imageUrl; let containerWidth = layerObject.canvas.parentElement.parentElement.offsetWidth; if (containerWidth < 250) { layerObject.canvas.width = containerWidth - 5; layerObject.canvas.height = layerObject.canvas.width; } else { layerObject.canvas.width = containerWidth - 10; layerObject.canvas.height = layerObject.canvas.width; } img.onload = function () { const scaleX = layerObject.canvas.width / img.width; const scaleY = layerObject.canvas.height / img.height; const scale = Math.min(scaleX, scaleY); const newWidth = img.width * scale; const newHeight = img.height * scale; const x = (layerObject.canvas.width - newWidth) / 2; const y = (layerObject.canvas.height - newHeight) / 2; layerObject.context.drawImage(img, x, y, newWidth, newHeight); layerObject.imageData = layerObject.context.getImageData( 0, 0, layerObject.canvas.width, layerObject.canvas.height ); layerObject.initialState = [...layerObject.imageData.data]; changeEffectColor(layerObject, color); resolve(); }; img.onerror = function () { resolve(); }; }); } function changeEffectColor(layerObject, hex) { const data = layerObject.imageData.data; for (let i = 0; i < data.length; i += 4) { // for some reason there is a line on the top and bottom of canvas on some systems. This removes that if ( i <= layerObject.canvas.width * 4 || i > layerObject.canvas.height * layerObject.canvas.width * 4 - layerObject.canvas.width * 4 ) { data[i + 3] = 0; } else if ( layerObject.initialState[i] < 255 || layerObject.initialState[i + 1] < 255 || layerObject.initialState[i + 2] < 255 ) { let opacity = 255 - layerObject.initialState[i]; data[i + 3] = opacity; const { r, g, b } = hexToRGB(hex.substring(1)); if (r === undefined) { return; } data[i] = r; data[i + 1] = g; data[i + 2] = b; } else { data[i + 3] = 0; } } layerObject.context.putImageData(layerObject.imageData, 0, 0); } function clearEffects() { initEffect("", layerTwo); initEffect("", layerOne); initEffect("", layerThree); } function hexToRGB(hex) { const r = parseInt(hex.slice(0, 2), 16); const g = parseInt(hex.slice(2, 4), 16); const b = parseInt(hex.slice(4, 6), 16); return { r, g, b }; }