[object Object]

← 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

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 →