← back to Dw Theme Boost Fix
assets/dw-grid-control.js
136 lines
/**
* DW Grid Control — Inline grid column selector for collection pages
* Positioned at top-left directly above the product grid
* Only appears on pages with a product image grid
*/
(function() {
'use strict';
/* === DW 2026-06-25 CONSOLIDATION: this control is SUPERSEDED, hard-disabled ===
dw-boost-overrides.liquid now owns the single density slider that targets
Boost's real grid. This legacy control injected a SECOND control on the same
.boost-sd__product-list (already CSS-hidden via `.dw-gc{display:none}` in the
overrides) and was a competing localStorage('dw-grid-cols') writer. Returning
early stops the two layers fighting. Reversible: remove this return to restore. */
return;
/* eslint-disable no-unreachable */
var path = window.location.pathname;
if (!path.startsWith('/collections/')) return;
if (path.indexOf('/products/') !== -1) return;
var STORAGE_KEY = 'dw-grid-cols';
var DEFAULT = 3;
var MIN = 1;
var MAX = 8;
var saved = parseInt(localStorage.getItem(STORAGE_KEY)) || DEFAULT;
var attempts = 0;
function findGrid() {
var selectors = [
'.boost-pfs-filter-products',
'.boost-sd__product-list',
'[data-boost-products]',
'.product-grid',
'.collection-products',
'.product-loop',
'.collection-grid',
'#product-loop',
'.product-list--collection'
];
for (var i = 0; i < selectors.length; i++) {
var el = document.querySelector(selectors[i]);
if (el && el.children.length > 2) return el;
}
// Fallback: container with 4+ product links
var containers = document.querySelectorAll('[class*="product"]');
for (var j = 0; j < containers.length; j++) {
if (containers[j].querySelectorAll('a[href*="/products/"]').length >= 4 && containers[j].children.length >= 4)
return containers[j];
}
return null;
}
function applyGrid(container, cols) {
container.style.display = 'grid';
container.style.gridTemplateColumns = 'repeat(' + cols + ', 1fr)';
container.style.gap = '4px';
var imgWidth = container.offsetWidth / cols;
container.style.paddingRight = imgWidth + 'px';
var ch = container.children;
for (var i = 0; i < ch.length; i++) {
ch[i].style.width = '100%';
ch[i].style.maxWidth = '100%';
ch[i].style.flex = 'none';
ch[i].style.float = 'none';
// Hide product names when grid > 4 columns
var nameEls = ch[i].querySelectorAll('[class*="title"] a, [class*="product-title"], [class*="product-name"]');
for (var j = 0; j < nameEls.length; j++) {
nameEls[j].style.display = cols > 4 ? 'none' : '';
}
}
}
function createControl(container) {
var style = document.createElement('style');
style.textContent = [
'.dw-gc{display:inline-flex;align-items:center;gap:8px;padding:6px 16px;margin:0 0 6px;font-family:-apple-system,BlinkMacSystemFont,sans-serif;font-size:11px;user-select:none;background:#fff;border:1.5px solid #000;border-radius:999px}',
'.dw-gc-lbl{color:#000;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1.5px}',
'.dw-gc-slider{-webkit-appearance:none;width:140px;height:3px;background:#ccc;border-radius:2px;outline:none;cursor:pointer}',
'.dw-gc-slider::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;background:#000;border-radius:50%;cursor:pointer}',
'.dw-gc-slider::-moz-range-thumb{width:16px;height:16px;background:#000;border-radius:50%;cursor:pointer;border:none}',
'.dw-gc-val{color:#000;font-weight:700;font-size:14px;min-width:16px;text-align:center}',
].join('');
document.head.appendChild(style);
var bar = document.createElement('div');
bar.className = 'dw-gc';
var label = document.createElement('span');
label.className = 'dw-gc-lbl';
label.textContent = 'Grid';
bar.appendChild(label);
var slider = document.createElement('input');
slider.type = 'range';
slider.className = 'dw-gc-slider';
slider.min = MIN;
slider.max = MAX;
slider.value = saved;
bar.appendChild(slider);
var val = document.createElement('span');
val.className = 'dw-gc-val';
val.textContent = saved;
bar.appendChild(val);
slider.addEventListener('input', function() {
var v = parseInt(this.value);
saved = v;
val.textContent = v;
localStorage.setItem(STORAGE_KEY, v);
applyGrid(container, v);
});
// Insert directly above the grid, top-left
container.parentNode.insertBefore(bar, container);
applyGrid(container, saved);
}
function init() {
var grid = findGrid();
if (grid) {
createControl(grid);
new MutationObserver(function() {
applyGrid(grid, parseInt(localStorage.getItem(STORAGE_KEY)) || DEFAULT);
}).observe(grid, { childList: true });
} else if (++attempts < 50) {
setTimeout(init, 200);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() { setTimeout(init, 500); });
} else {
setTimeout(init, 500);
}
})();