/*!
* AKTA Cleaning Supplies — Custom Enquiry System
* -----------------------------------------------
* Replaces Squarespace's shopping cart with a localStorage-based
* enquiry list, submitted through the existing Squarespace Form
* Block on /your-enquiry.
*
* Install: paste this entire file inside tags
* in Settings > Advanced > Code Injection > FOOTER (site-wide).
* See the installation guide for full details.
*
* No external dependencies. Safe to run on every page.
*/
(function () {
'use strict';
var STORAGE_KEY = 'akta_enquiry_list';
var ENQUIRY_PATH = '/your-enquiry';
var ADD_BUTTON_SELECTOR = '.sqs-add-to-cart-button';
var TITLE_SELECTOR = '.product-title';
var QTY_SELECTOR = "input[name='quantity-input']";
// ---------------------------------------------------------------
// Storage helpers
// ---------------------------------------------------------------
function getList() {
try {
var raw = localStorage.getItem(STORAGE_KEY);
var list = raw ? JSON.parse(raw) : [];
return Array.isArray(list) ? list : [];
} catch (e) {
console.warn('AKTA Enquiry: could not read localStorage', e);
return [];
}
}
function saveList(list) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(list));
} catch (e) {
console.warn('AKTA Enquiry: could not write localStorage', e);
}
}
function addToList(name, qty) {
name = (name || '').trim();
qty = parseInt(qty, 10);
if (!name || isNaN(qty) || qty < 1) {
console.warn('AKTA Enquiry: invalid product name/quantity, ignored', name, qty);
return;
}
var list = getList();
var existing = null;
for (var i = 0; i < list.length; i++) {
if (list[i].name.toLowerCase() === name.toLowerCase()) {
existing = list[i];
break;
}
}
if (existing) {
existing.qty += qty;
} else {
list.push({ name: name, qty: qty });
}
saveList(list);
renderEnquiryPage();
showConfirmation(name, qty);
}
function removeFromList(name) {
var list = getList().filter(function (item) {
return item.name !== name;
});
saveList(list);
renderEnquiryPage();
}
function clearList() {
saveList([]);
renderEnquiryPage();
}
// ---------------------------------------------------------------
// Confirmation toast (shown on product pages after adding)
// ---------------------------------------------------------------
var toastTimer = null;
function showConfirmation(name, qty) {
var toast = document.getElementById('akta-toast');
if (!toast) {
toast = document.createElement('div');
toast.id = 'akta-toast';
document.body.appendChild(toast);
}
toast.textContent = 'Added ' + qty + ' \u00d7 ' + name + ' to your enquiry';
toast.classList.add('akta-toast-visible');
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toast.classList.remove('akta-toast-visible');
}, 2500);
}
// ---------------------------------------------------------------
// Product pages: intercept "Add to Enquiry" clicks
// ---------------------------------------------------------------
function bindAddButtons() {
var buttons = document.querySelectorAll(ADD_BUTTON_SELECTOR);
buttons.forEach(function (btn) {
if (btn.getAttribute('data-akta-bound') === 'true') return;
btn.setAttribute('data-akta-bound', 'true');
// Capture phase + stopImmediatePropagation gives this the best
// chance of running before Squarespace's own cart handler.
// NOTE: on some templates Squarespace's listener may still fire
// first — see the installation guide's "Known limitation" note.
btn.addEventListener('click', handleAddClick, true);
});
}
function handleAddClick(e) {
e.preventDefault();
e.stopPropagation();
if (e.stopImmediatePropagation) e.stopImmediatePropagation();
var titleEl = document.querySelector(TITLE_SELECTOR);
var qtyEl = document.querySelector(QTY_SELECTOR);
var name = titleEl ? titleEl.textContent.trim() : '';
var qty = qtyEl && qtyEl.value ? qtyEl.value : '1';
if (!name) {
console.warn('AKTA Enquiry: could not find product title (' + TITLE_SELECTOR + ')');
return;
}
addToList(name, qty);
return false;
}
// ---------------------------------------------------------------
// Enquiry page: render list, remove/clear, autofill form
// ---------------------------------------------------------------
function isEnquiryPage() {
var path = window.location.pathname.replace(/\/$/, '');
return path === ENQUIRY_PATH;
}
function renderEnquiryPage() {
if (!isEnquiryPage()) return;
var itemsContainer = document.getElementById('akta-enquiry-items');
if (!itemsContainer) return; // container HTML not present on this page yet
var emptyMsg = document.getElementById('akta-enquiry-empty');
var list = getList();
itemsContainer.innerHTML = '';
if (list.length === 0) {
if (emptyMsg) emptyMsg.style.display = 'block';
} else {
if (emptyMsg) emptyMsg.style.display = 'none';
list.forEach(function (item) {
var row = document.createElement('div');
row.className = 'akta-enquiry-item';
var nameSpan = document.createElement('span');
nameSpan.className = 'akta-enquiry-item-name';
nameSpan.textContent = item.name;
var qtySpan = document.createElement('span');
qtySpan.className = 'akta-enquiry-item-qty';
qtySpan.textContent = 'Qty: ' + item.qty;
var removeBtn = document.createElement('button');
removeBtn.type = 'button';
removeBtn.className = 'akta-enquiry-item-remove';
removeBtn.textContent = 'Remove';
removeBtn.setAttribute('aria-label', 'Remove ' + item.name + ' from enquiry list');
removeBtn.addEventListener('click', function () {
removeFromList(item.name);
});
row.appendChild(nameSpan);
row.appendChild(qtySpan);
row.appendChild(removeBtn);
itemsContainer.appendChild(row);
});
}
fillProductsTextarea();
}
function bindClearButton() {
var btn = document.getElementById('akta-enquiry-clear');
if (!btn || btn.getAttribute('data-akta-bound') === 'true') return;
btn.setAttribute('data-akta-bound', 'true');
btn.addEventListener('click', function () {
if (getList().length === 0) return;
if (window.confirm('Clear all items from your enquiry list?')) {
clearList();
}
});
}
// ---- Locating & filling the "Products Selected" form field ----
function findLabelTextFor(field) {
if (field.id) {
var lbl = document.querySelector('label[for="' + field.id + '"]');
if (lbl) return lbl.textContent;
}
var parentLabel = field.closest('label');
if (parentLabel) return parentLabel.textContent;
var wrapper = field.closest('.field, .form-item, .sqs-block-form-field, .fluid-engine-item');
if (wrapper) {
var innerLabel = wrapper.querySelector('label, .title, .field-title, .form-field-title');
if (innerLabel) return innerLabel.textContent;
}
return '';
}
function findProductsTextarea() {
// Preferred: a field explicitly flagged with this data attribute
// (see installation guide, "reliable targeting" option).
var flagged = document.querySelector('[data-akta-products-field]');
if (flagged) return flagged;
// Fallback: match by the field's visible label text.
var textareas = document.querySelectorAll('form textarea, .sqs-block-form textarea');
for (var i = 0; i < textareas.length; i++) {
var label = findLabelTextFor(textareas[i]);
if (label && /products\s*selected/i.test(label)) {
return textareas[i];
}
}
return null;
}
function formatListForTextarea(list) {
if (list.length === 0) return '';
return list
.map(function (item) {
return item.qty + ' x ' + item.name;
})
.join('\n');
}
function fillProductsTextarea() {
var ta = findProductsTextarea();
if (!ta) return;
ta.value = formatListForTextarea(getList());
// Fire input/change so Squarespace's own field validation registers it
ta.dispatchEvent(new Event('input', { bubbles: true }));
ta.dispatchEvent(new Event('change', { bubbles: true }));
}
function bindFormSubmit() {
var forms = document.querySelectorAll('.sqs-block-form form, form');
forms.forEach(function (form) {
if (form.getAttribute('data-akta-bound') === 'true') return;
form.setAttribute('data-akta-bound', 'true');
form.addEventListener(
'submit',
function () {
fillProductsTextarea();
},
true
);
});
}
// Best-effort: clear the list once Squarespace shows its own
// "thank you" / submission-success message. This is not guaranteed
// on every template — see installation guide.
function watchForFormSuccess() {
var blocks = document.querySelectorAll('.sqs-block-form');
blocks.forEach(function (block) {
if (block.getAttribute('data-akta-watch') === 'true') return;
block.setAttribute('data-akta-watch', 'true');
var obs = new MutationObserver(function () {
var successEl = block.querySelector(
'.form-submission-message, .sqs-block-form-success, .form-success'
);
if (successEl && successEl.offsetParent !== null) {
clearList();
obs.disconnect();
}
});
obs.observe(block, { childList: true, subtree: true, attributes: true });
});
}
// ---------------------------------------------------------------
// Init + re-init on Squarespace's AJAX-style navigation
// ---------------------------------------------------------------
function init() {
bindAddButtons();
if (isEnquiryPage()) {
renderEnquiryPage();
bindClearButton();
bindFormSubmit();
watchForFormSuccess();
}
}
document.addEventListener('DOMContentLoaded', init);
window.addEventListener('load', init);
window.addEventListener('popstate', init);
// Debounced MutationObserver so re-binding survives Squarespace's
// partial page loads (quick-view, ajax navigation) without
// hammering the DOM on every tiny change.
var debounceTimer = null;
var observer = new MutationObserver(function () {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(init, 150);
});
observer.observe(document.body, { childList: true, subtree: true });
})();