← back to Designer Wallcoverings
MOQ theme fix: exempt Sample variants (force qty 1 when Sample selected, server + client side)
091457192e46034f24f4841482436aa5bc3a91ea · 2026-06-22 14:03:26 -0700 · Steve Abrams
Files touched
M shopify/theme-moq/sections-product.FIXED.liquid
Diff
commit 091457192e46034f24f4841482436aa5bc3a91ea
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jun 22 14:03:26 2026 -0700
MOQ theme fix: exempt Sample variants (force qty 1 when Sample selected, server + client side)
---
shopify/theme-moq/sections-product.FIXED.liquid | 56 +++++++++++++++++++++----
1 file changed, 48 insertions(+), 8 deletions(-)
diff --git a/shopify/theme-moq/sections-product.FIXED.liquid b/shopify/theme-moq/sections-product.FIXED.liquid
index 155ff06e..b5db0a4e 100644
--- a/shopify/theme-moq/sections-product.FIXED.liquid
+++ b/shopify/theme-moq/sections-product.FIXED.liquid
@@ -47,7 +47,10 @@
<label class="form-label">SIZE:</label>
<div class="variant-buttons">
{% for variant in product.variants %}
- <button type="button" class="variant-btn {% if variant == product.selected_or_first_available_variant %}active{% endif %}" data-variant-id="{{ variant.id }}">
+ {%- assign _vt = variant.title | downcase -%}
+ {%- assign _is_sample = 0 -%}
+ {%- if _vt contains 'sample' -%}{%- assign _is_sample = 1 -%}{%- endif -%}
+ <button type="button" class="variant-btn {% if variant == product.selected_or_first_available_variant %}active{% endif %}" data-variant-id="{{ variant.id }}" data-is-sample="{{ _is_sample }}">
{{ variant.title }}
</button>
{% endfor %}
@@ -65,12 +68,20 @@
if moq_step < 1
assign moq_step = 1
endif
+ # sample variants are exempt from the minimum (always orderable at qty 1)
+ assign sel_title = product.selected_or_first_available_variant.title | downcase
+ assign init_min = moq_min
+ assign init_step = moq_step
+ if sel_title contains 'sample'
+ assign init_min = 1
+ assign init_step = 1
+ endif
-%}
<div class="form-group">
- <label class="form-label">QUANTITY:{% if moq_min > 1 %} <span class="moq-note">(min {{ moq_min }}{% if moq_step > 1 %}, in {{ moq_step }}s{% endif %})</span>{% endif %}</label>
+ <label class="form-label">QUANTITY:{% if moq_min > 1 %} <span class="moq-note"{% if init_min == 1 %} style="display:none"{% endif %}>(min {{ moq_min }}{% if moq_step > 1 %}, in {{ moq_step }}s{% endif %})</span>{% endif %}</label>
<div class="quantity-control">
<button type="button" class="qty-btn minus">−</button>
- <input type="number" name="quantity" value="{{ moq_min }}" min="{{ moq_min }}" step="{{ moq_step }}" data-min="{{ moq_min }}" data-step="{{ moq_step }}" class="qty-input">
+ <input type="number" name="quantity" value="{{ init_min }}" min="{{ init_min }}" step="{{ init_step }}" data-min="{{ init_min }}" data-step="{{ init_step }}" data-moq-min="{{ moq_min }}" data-moq-step="{{ moq_step }}" class="qty-input">
<button type="button" class="qty-btn plus">+</button>
</div>
</div>
@@ -348,21 +359,50 @@
<script>
/* DW MOQ 2026-06-22: enforce order minimum + increment on the custom PDP quantity box.
- Conflict-safe: re-clamps to data-min / data-step after any +/- click, on change/blur,
- and before form submit — regardless of any other handlers. */
+ - Reads product MOQ from data-moq-min / data-moq-step.
+ - Sample variants are EXEMPT: when a variant whose button has data-is-sample="1"
+ is active, min/step drop to 1 (order a single sample).
+ - Conflict-safe: re-clamps after any +/- click, on change/blur, before submit,
+ and on variant change — regardless of any other handlers. */
(function(){
var q = document.querySelector('.quantity-control .qty-input');
if(!q) return;
- var min = parseInt(q.getAttribute('data-min'),10) || 1;
- var step = parseInt(q.getAttribute('data-step'),10) || 1;
+ var moqMin = parseInt(q.getAttribute('data-moq-min'),10) || 1;
+ var moqStep = parseInt(q.getAttribute('data-moq-step'),10) || 1;
+ var note = document.querySelector('.moq-note');
+
+ function applyConstraints(isSample){
+ var min = isSample ? 1 : moqMin;
+ var step = isSample ? 1 : moqStep;
+ q.setAttribute('min', min);
+ q.setAttribute('step', step);
+ q.setAttribute('data-min', min);
+ q.setAttribute('data-step', step);
+ if(note){ note.style.display = (min > 1) ? '' : 'none'; }
+ clamp();
+ }
function clamp(){
+ var min = parseInt(q.getAttribute('data-min'),10) || 1;
+ var step = parseInt(q.getAttribute('data-step'),10) || 1;
var v = parseInt(q.value,10);
if(isNaN(v) || v < min){ v = min; }
var r = (v - min) % step;
if(r !== 0){ v = v - r + step; }
q.value = v;
}
- clamp();
+
+ // initial state from the active variant button (fallback: current input)
+ var active = document.querySelector('.variant-btn.active');
+ applyConstraints(active && active.getAttribute('data-is-sample') === '1');
+
+ // variant switch → recompute (runs after any other click handler via setTimeout)
+ Array.prototype.forEach.call(document.querySelectorAll('.variant-btn'), function(btn){
+ btn.addEventListener('click', function(){
+ var isSample = btn.getAttribute('data-is-sample') === '1';
+ setTimeout(function(){ applyConstraints(isSample); }, 0);
+ });
+ });
+
var ctrl = q.closest('.quantity-control');
if(ctrl){ ctrl.addEventListener('click', function(){ setTimeout(clamp, 0); }); }
q.addEventListener('change', clamp);
← f68f5a77 Restore grid density slider + add product descriptions to co
·
back to Designer Wallcoverings
·
Add push script for grid slider + description deploy ac76db9f →