← back to Dw Contact Us Pages
data/theme-preimage/145556635699/assets/dw-contact-us-cards.js
108 lines
/* dw-contact-us-cards.js — TK-11925
* Boost SD renders every browse/search grid CLIENT-SIDE, so neither
* product-list-item.liquid nor a server-rendered rule can reach those cards.
* This sweeps Boost cards and replaces the price with "Contact us for pricing"
* for the contact-us vendor cohort (Designers Guild / Ralph Lauren /
* Christian Lacroix Europe).
*
* VENDOR-KEYED (preferred): a live Boost card exposes its vendor as the text of
* a [class*="product-vendor"] node — measured on the live store, and the same
* hook the existing Newmor guard in layout/theme.liquid already relies on
* (isNewmor() reads exactly that node). Price nodes measured on the same guard:
* .boost-sd__product-price, .boost-sd__format-currency, [class*="compare-price"], [class*="unit-price"]
*
* Vendor list comes from window.DW_CONTACT_US_VENDORS, emitted by
* snippets/hide-browse-hidden.liquid from (in priority order)
* 1. shop metafield custom.contact_us_vendors
* 2. theme setting settings.contact_us_vendors
* 3. the literal 3-vendor fallback
* mirroring the showroom_vendors pattern. No id list is baked in, so the
* cohort can change without regenerating this asset.
*
* Optional id backstop: window.DW_CONTACT_US_IDS (array of product ids) is
* honoured if present, for cards whose vendor node is suppressed by a Boost
* theme setting.
*/
(function () {
if (window.__dwContactUsCards) return;
window.__dwContactUsCards = true;
var LABEL = 'Contact us for pricing';
var CARD_SEL = '.boost-sd__product-item';
var PRICE_SEL = '.boost-sd__product-price,.boost-sd__format-currency,[class*="product-price"],[class*="compare-price"],[class*="unit-price"]';
var VENDOR_SEL = '[class*="product-vendor"]';
function norm(s) { return String(s == null ? '' : s).trim().toLowerCase(); }
var VENDORS = (window.DW_CONTACT_US_VENDORS || [
'Designers Guild', 'Ralph Lauren', 'Christian Lacroix Europe'
]).map(norm).filter(Boolean);
var IDS = new Set((window.DW_CONTACT_US_IDS || []).map(String));
if (!VENDORS.length && !IDS.size) return;
function isTarget(card) {
var id = card.getAttribute('data-product-id');
if (id && IDS.has(String(id))) return true;
var v = card.querySelector(VENDOR_SEL);
if (v && VENDORS.indexOf(norm(v.textContent)) > -1) return true;
return false;
}
function treat(card) {
if (card.getAttribute('data-dw-contact-us') === '1') return;
card.setAttribute('data-dw-contact-us', '1');
var replaced = false;
card.querySelectorAll(PRICE_SEL).forEach(function (n) {
if (!replaced) {
// Reuse the first price node so the card keeps its layout/typography.
n.textContent = LABEL;
n.classList.add('dw-cu-card-price');
n.setAttribute('data-dw-contact-us-price', '1');
replaced = true;
} else {
n.remove();
}
});
if (!replaced && !card.querySelector('.dw-cu-card-price')) {
var p = document.createElement('p');
p.className = 'dw-cu-card-price';
p.setAttribute('data-dw-contact-us-price', '1');
p.textContent = LABEL;
card.appendChild(p);
}
// Nothing purchasable from the grid for this cohort.
card.querySelectorAll('[class*="quick-view"],[class*="quickView"],[class*="quick-add"],[class*="buy-now"],[class*="add-to-cart"]')
.forEach(function (n) { n.remove(); });
}
var pending = false;
function sweep() {
var cards = document.querySelectorAll(CARD_SEL + ':not([data-dw-contact-us])');
for (var i = 0; i < cards.length; i++) {
if (isTarget(cards[i])) treat(cards[i]);
}
}
function schedule() {
if (pending) return;
pending = true;
requestAnimationFrame(function () { pending = false; sweep(); });
}
function start() {
sweep();
new MutationObserver(schedule).observe(document.documentElement, { childList: true, subtree: true });
}
var css = document.createElement('style');
css.textContent = '.dw-cu-card-price{font-size:12px!important;letter-spacing:.02em;color:#6b6357!important;margin:4px 0 0}' +
'.boost-sd__product-item[data-dw-contact-us] .boost-sd__format-currency:not([data-dw-contact-us-price]){display:none!important}';
(document.head || document.documentElement).appendChild(css);
if (document.readyState !== 'loading') start();
else document.addEventListener('DOMContentLoaded', start);
})();