Probleme mit Formular im Warenkorb

Hallo Zusammen,

ich habe für unsere neuen digitalen Produkte eine kleine Formularerweiterung in den cart-drawer.liquid geschrieben:

{% assign ist_digital = false %}           
{% if item.product.tags contains 'digital' %}
   {% assign ist_digital = true %}
{% endif %}
{% if ist_digital %}
   <p class="kleiner">
      <input type="hidden" name="cart[Widerrufsverzicht]" value="Nein">
      <input type="checkbox" name="cart[Widerrufsverzicht]" value="Ja" id="widerrufsverzicht" required>
      <label for="widerruf">
         Ich stimme zu, dass die Ausführung des Vertrags beim Kauf dieses Produktes vor Ablauf der Widerrufsfrist beginnt und ich mein Widerrufsrecht verliere.
      </label>
   </p>
{% endif %}

Lege ich den Artikel in den Warenkorb, erscheint die Checkbox wie sie es auch soll und gibt eine Meldung aus, wenn ich auf ‘Zur Kasse‘ klicke ohne die Checkbox zu aktivieren. So weit, so gut! Setze ich das Häkchen und klicke auf ‘Zur Kasse‘ erscheint aber folgendes neben der Checkbox: ‘Du kannst diesen Artikel nur in Abstufungen von hinzufügen‘. Da es ein digitales Produkt ist, kann ich sowieso nur die Menge 1 nehmen.

Hat vielleicht irgendjemand eine Ahnung, wieso das so ist? Wo mein Fehler liegt?

Herzlichen Dank bereits jetzt für jedwede Hilfe

Markus

Sounds like it’s getting confused. Try it with the required in Javascript instead of the html:

{% assign ist_digital = false %}

{% if item.product.tags contains 'digital' %}

  {% assign ist_digital = true %}

{% endif %}



{% if ist_digital %}

  <p class="kleiner">

    <input type="hidden" name="cart[Widerrufsverzicht]" value="Nein">

    <input type="checkbox" name="cart[Widerrufsverzicht]" value="Ja" id="widerrufsverzicht">

    <label for="widerrufsverzicht">

      Ich stimme zu, dass die Ausführung des Vertrags beim Kauf dieses Produktes vor Ablauf der Widerrufsfrist beginnt und ich mein Widerrufsrecht verliere.

    </label>

  </p>

{% endif %}


Then add this to handle the requirement:

<script>

     document.querySelector('a[href="/checkout"], button[name="checkout"]').addEventListener('click', function(e) {

       const cb = document.querySelector('#widerrufsverzicht');

       if (cb && !cb.checked) {

         e.preventDefault();

         cb.closest('p').style.outline = '1px solid red';

         cb.scrollIntoView({ behavior: 'smooth', block: 'center' });

       }

     });

   </script>


Thanks for your answer! But it behaves still the same!

try a bare minimum cart attribute, and then you can add to it if it’s successful:

{% if item.product.tags contains 'digital' %}
  <input type="checkbox" name="cart[digital_consent]" value="Ja" id="widerrufsverzicht">
  <label for="widerrufsverzicht">
    Ich stimme zu, dass die Ausführung des Vertrags beim Kauf dieses Produktes vor Ablauf der Widerrufsfrist beginnt und ich mein Widerrufsrecht verliere.
  </label>
{% endif %}

Then if it doesn’t give you an error, you can add the hidden back in:

{% if item.product.tags contains 'digital' %}
  <input type="hidden" name="cart[digital_consent]" value="Nein">
  <input type="checkbox" name="cart[digital_consent]" value="Ja" id="widerrufsverzicht">
  <label for="widerrufsverzicht">
    Ich stimme zu, dass die Ausführung des Vertrags beim Kauf dieses Produktes vor Ablauf der Widerrufsfrist beginnt und ich mein Widerrufsrecht verliere.
  </label>
{% endif %}

It is still the same. By the time I klick the checkbox, nothing works anymore!

What theme please, and where exactly are you adding this? What file, and where in the file?

The theme is Craft.

I’m working in

snippets/cart-drawer.liquid, line 443 – 455

and

sections/main-cart-footer.liquid, line 66 - 76

Herzliche Grüße

Markus

Ok I’m going to provide a solution. You should delete all code that you have done so far, and follow this instruction.

  1. Code Editor, find the Snippets folder. Click on Snippets. Then Click add. Name it “cart-legal-checkbox.liquid”

  2. Paste this code and save:

{% comment %} cart-legal-checkbox.liquid — Craft theme, cart attribute {% endcomment %}
<div class="cart-legal-checkbox" id="cart-legal-checkbox-wrapper">
  <label class="cart-legal-checkbox__label">
    <input
      type="checkbox"
      id="cart-legal-checkbox-input"
      name="attributes[legal_consent_widerruf]"
      value="Zugestimmt"
      class="cart-legal-checkbox__input"
      aria-required="true"
      {% if cart.attributes.legal_consent_widerruf == 'Zugestimmt' %}checked{% endif %}
    />
    <span class="cart-legal-checkbox__text">
      Ich stimme zu, dass die Ausführung des Vertrags beim Kauf dieses Produktes vor Ablauf der Widerrufsfrist beginnt und ich mein Widerrufsrecht verliere.
    </span>
  </label>
  <p class="cart-legal-checkbox__error" id="cart-legal-checkbox-error" style="display:none;">
    Bitte bestätigen Sie die Zustimmung, um fortzufahren.
  </p>
</div>

<style>
  .cart-legal-checkbox {
    margin: 16px 0;
    padding: 12px 14px;
    border: 1px solid rgba(var(--color-border), 1);
    border-radius: var(--border-radius, 4px);
    background: rgba(var(--color-background), 1);
  }
  .cart-legal-checkbox__label {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    cursor: pointer;
    font-size: var(--font-body-size, 13px);
    line-height: 1.5;
    color: rgba(var(--color-foreground), 1);
  }
  .cart-legal-checkbox__input {
    margin-top: 3px;
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    cursor: pointer;
    accent-color: rgba(var(--color-button), 1);
  }
  .cart-legal-checkbox__error {
    color: rgb(var(--color-error, 192 57 43));
    font-size: calc(var(--font-body-size, 13px) - 1px);
    margin: 6px 0 0 26px;
  }
  .cart-legal-checkbox--invalid .cart-legal-checkbox__input {
    outline: 2px solid rgb(var(--color-error, 192 57 43));
  }
</style>

<script>
  (function () {
    var wrapper = document.getElementById('cart-legal-checkbox-wrapper');
    var checkbox = document.getElementById('cart-legal-checkbox-input');
    var error = document.getElementById('cart-legal-checkbox-error');

    function getCheckoutButtons() {
      return document.querySelectorAll(
        '[name="checkout"], ' +
        'button[type="submit"].cart__checkout-button, ' +
        '.cart__ctas a[href*="checkout"], ' +
        '[data-cart-checkout-button]'
      );
    }

    function blockCheckout(e) {
      if (!checkbox.checked) {
        e.preventDefault();
        e.stopImmediatePropagation();
        wrapper.classList.add('cart-legal-checkbox--invalid');
        error.style.display = 'block';
        wrapper.scrollIntoView({ behavior: 'smooth', block: 'center' });
        return false;
      }
    }

    checkbox.addEventListener('change', function () {
      if (checkbox.checked) {
        wrapper.classList.remove('cart-legal-checkbox--invalid');
        error.style.display = 'none';
      }
      // Update cart attribute via AJAX when checkbox changes
      updateCartAttribute(checkbox.checked ? 'Zugestimmt' : '');
    });

    function updateCartAttribute(value) {
      fetch('/cart/update.js', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          attributes: { legal_consent_widerruf: value }
        })
      });
    }

    function attachListeners() {
      getCheckoutButtons().forEach(function (btn) {
        btn.removeEventListener('click', blockCheckout);
        btn.addEventListener('click', blockCheckout);
      });
    }

    attachListeners();

    document.addEventListener('cart:updated', attachListeners);
    document.addEventListener('cart:refresh', attachListeners);

    new MutationObserver(attachListeners).observe(document.body, {
      childList: true,
      subtree: true
    });
  })();
</script>

  1. Go to main-cart-footer.liquid, scroll down to the checkout button

  2. Paste this above the checkout button and save:

{% render 'cart-legal-checkbox' %}

  1. Add a product to cart, go to cart and see:

  2. Do a test order. The cart attribute will show here in “Additional Details”:

This is only rendering the snippet on the cart page. There is no “IF tag is ___”, so it will work with all products. If you want to add the tag condition, you can do wrap the render in the IF statement. Also, this is only on cart page. If you want it on the cart drawer, you need to do Step 4 in the drawer file.

Let me know if it doesn’t work

Now it works, thank you!

The main problem ist, it should only be active, when there is a digital product in cart.

Now my workaround with {if item.product.tags contains ‘digital‘} does not work anymore. Any idea?

You’ll need the necessary logic in the main-cart-footer.liquid file. This is what you need in addition:

{% assign has_digital = false %}
{% for item in cart.items %}
  {% if item.product.tags contains 'digital' %}
    {% assign has_digital = true %}
    {% break %}
  {% endif %}
{% endfor %}

Reason is because you need to access the items in the cart form and look for the tags.

So in total, Replace the “render” line with this:

{% assign has_digital = false %}
{% for item in cart.items %}
  {% if item.product.tags contains 'digital' %}
    {% assign has_digital = true %}
    {% break %}
  {% endif %}
{% endfor %}

{% if has_digital %}
  {% render 'cart-legal-checkbox' %}
{% endif %}

This code block should work in the cart drawer as well.

Thanks a lot! German law says, the hole thing belongs to the checkout page before you klick ‘buy now‘. But we can’t put it there, right?

Best regards, Markus

Unfortunately not. Checkout is restricted for non-plus plans. But If you set it up where you have to go through the cart/drawer in order to reach checkout, I think that would be acceptable (not legal advise lol), you would just need to disable any express checkout option on your site that bypasses the cart. Regards