A Treasure of Exotic Hardwoods

A Treasure of Exotic Hardwoods

As the old saw goes, “some days ya just get lucky!” Well, that is exactly what happened to me recently. A little background, first. As woodworkers, craftspeople, woodturners, etc., we have been intrigued with using some exotic hardwoods in our projects....
Wood Can Make All the Difference

Wood Can Make All the Difference

Wood is one of the world’s most beautiful natural resources. When in its natural state in a tree, it provides a beautiful landscaping element. But there’s more to wood than leaving it in its natural state. Wood makes for beautiful structures, both practical and...
Tradition at Barney & Carey

Tradition at Barney & Carey

We are certainly proud to be celebrating Barney and Carey’s 100th anniversary since opening on the banks of the Neponset River, Milton, in 1922. It was the former site of the old Neponset Coal Co. I found the original permit and plans for the deep water docks,...
Customizing Your Home with Handcrafted Furniture

Customizing Your Home with Handcrafted Furniture

There is nothing more satisfying than making a home uniquely yours. One of the ways to set your home apart from others is with custom furniture. What’s amazing about having handcrafted furniture is that that no two pieces will be exactly alike. Here are some qualities...
Characteristics of a Good Carpenter

Characteristics of a Good Carpenter

Carpentry is a dangerous profession. Woodworking involves a variety of different tools, including saws, drills, and nail guns. In the workshop, it is important to keep in mind that it only takes one moment of poor judgment to lose an eye, a finger, or more. As a...

Cabinet Order Summary

${customerInfoHTML} ${cabinetDetailsHTML} ${printContent} `); printWindow.document.close(); // Wait for content to load before printing printWindow.onload = function () { printWindow.print(); }; } // Set up form field listeners function setupFormListeners() { // Prevent duplicate listeners by removing existing ones first if (window.cabinetVisListenersSetup) { return; // Already setup, don't duplicate } // Listen for changes on all form inputs in the repeater sections const form = document.querySelector("#form_cab-price-calc"); if (form) { // Mark that we've setup listeners to prevent duplicates window.cabinetVisListenersSetup = true; // Use event delegation to catch changes in current and future repeater sections form.addEventListener("change", function (e) { if (e.target.name && e.target.name.includes("item_meta[42]")) { updateVisualization(); } // Also listen for material changes (field 105) if (e.target.name && e.target.name.includes("item_meta[105]")) { updateVisualization(); } // Also listen for type changes (field 45) if (e.target.name && e.target.name.includes("item_meta[45]")) { updateVisualization(); } // Also listen for delivery option changes if (e.target.name && e.target.name.includes("item_meta[113]")) { updateVisualization(); } }); form.addEventListener("input", function (e) { if (e.target.name && e.target.name.includes("item_meta[42]")) { updateVisualization(); } }); // Watch for repeater add/remove buttons const observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if ( mutation.addedNodes.length || mutation.removedNodes.length ) { // Check if repeater sections were added/removed const hasRepeaterChanges = Array.from( mutation.addedNodes, ) .concat(Array.from(mutation.removedNodes)) .some( (node) => node.nodeType === 1 && (node.classList?.contains( "frm_repeat_sec", ) || node.querySelector?.( ".frm_repeat_sec", )), ); if (hasRepeaterChanges) { setTimeout(updateVisualization, 100); // Small delay to ensure DOM is updated } } }); }); observer.observe(form, { childList: true, subtree: true, }); } } // Initialize function init() { const container = document.getElementById("sheetVis"); if (!container) { // If sheetVis doesn't exist yet, wait for it const observer = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.addedNodes.length) { Array.from(mutation.addedNodes).forEach( function (node) { if ( node.nodeType === 1 && (node.id === "sheetVis" || node.querySelector?.("#sheetVis")) ) { observer.disconnect(); // Stop observing updateVisualization(); setupFormListeners(); } }, ); } }); }); observer.observe(document.body, { childList: true, subtree: true, }); return; // Exit early if container not found } // Container exists, proceed normally updateVisualization(); setupFormListeners(); } // Handle Formidable Forms multi-step navigation function handleFormPageChange() { // Reset listener setup flag to allow re-initialization window.cabinetVisListenersSetup = false; // Small delay to ensure DOM is fully updated after page change setTimeout(function () { const container = document.getElementById("sheetVis"); if (container) { updateVisualization(); // Re-setup form listeners in case they were lost during navigation setupFormListeners(); } else { // If container doesn't exist, re-run full initialization init(); } }, 50); } // Additional fallback detection for form changes function setupGlobalFormWatcher() { // Watch for any significant DOM changes that might indicate form step changes const globalObserver = new MutationObserver(function (mutations) { let shouldReinit = false; mutations.forEach(function (mutation) { if (mutation.addedNodes.length > 0) { Array.from(mutation.addedNodes).forEach(function (node) { if (node.nodeType === 1) { // Check for form content changes or step navigation if ( node.classList?.contains("frm_form_content") || node.querySelector?.(".frm_form_content") || node.id === "form_cab-price-calc" || node.querySelector?.("#form_cab-price-calc") ) { shouldReinit = true; } } }); } }); if (shouldReinit) { handleFormPageChange(); } }); globalObserver.observe(document.body, { childList: true, subtree: true, }); } // Export global interface window.cabinetVis = { init: init, update: updateVisualization, getCabinets: extractCabinetData, handleFormPageChange: handleFormPageChange, debug: function () { console.log("Cabinet Visualization Debug Info:", { containerExists: !!document.getElementById("sheetVis"), formExists: !!document.querySelector("#form_cab-price-calc"), listenersSetup: !!window.cabinetVisListenersSetup, jQueryAvailable: typeof jQuery !== "undefined", cabinetCount: extractCabinetData().length, }); }, }; // Handle Formidable Forms multi-step navigation if (typeof jQuery !== "undefined") { jQuery(document).ready(function ($) { // Use both event delegation and direct binding for better compatibility $(document).on("frmPageChanged", function (event, form, response) { console.log( "Cabinet Vis: Formidable form page changed detected", ); handleFormPageChange(); }); // Also listen for form completion which might trigger on some step changes $(document).on("frmFormComplete", function (event, form, response) { setTimeout(function () { const container = document.getElementById("sheetVis"); if (container) { console.log( "Cabinet Vis: Form complete, updating visualization", ); updateVisualization(); } }, 100); }); }); } else { console.log( "Cabinet Vis: jQuery not available, relying on DOM observation for form changes", ); } // Setup global form watcher as fallback setupGlobalFormWatcher(); // Auto-initialize if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); } })();