Shopify / dawn

Shopify's first source available reference theme, with Online Store 2.0 features and performance built-in.
Other
2.47k stars 3.31k forks source link

updateQuantity function triggers on all input changes #3084

Open justin-gist-apps opened 10 months ago

justin-gist-apps commented 10 months ago

Describe the current behavior

Currently the updateQuantity function in cart.js triggers on all input changes, so if you have a text field in the cart form, updateQuantity() will run and fail resulting in an error being displayed in the cart form.

Describe the expected behavior

Ideally the updateQuantity function would only run when the quantity is updated to avoid displaying errors in the cart form when any input is changed.

Version information (Dawn, browsers and operating systems)

Itzdlg commented 9 months ago

Experienced this problem as well, which drove me crazy because I've never built on Shopify before.

Line 45-47 of assets/cart.js is the onUpdate function for the CartItems element, which contains the form where you add cart attribute fields. This function blindly triggers updateQuantity for any update inside of that element, and therefore on any update of new cart attribute fields.

The Bug

      <div>
        <p class="cart-attribute__field">
          <label for="username">Username</label>
          <input
            required
            class="required"
            id="username"
            type="text"
            name="attributes[username]"
            value="{{ cart.attributes["username"] }}"
          >
        </p>
      </div>

Request: POST /cart/change -> 400 Bad Request

Payload: {"quantity":"<Input from Attribute Field>","sections":["template--21814600007994__cart-items","cart-icon-bubble","cart-live-region-text","template--21814600007994__cart-footer"],"sections_url":"/cart"}

Response: {"errors":"expected String to be a Integer: quantity"}


Workaround

By modifying cart.js in the Theme Editor to read

  onChange(event) {
    if (event.target.classList.contains("cartjs-block-change"))
      return;

    this.updateQuantity(event.target.dataset.index, event.target.value, document.activeElement.getAttribute('name'), event.target.dataset.quantityVariantId);
  }

and adding cartjs-block-change to the class name of my cart attribute field input, the request is no longer sent and everything seems to work as expected.

This has been described in the Shopify dev discord @ https://discord.com/channels/842813079926603828/877581846077136988/1182799868125794416 for anyone interested in the full conversation leading me to conclude this is the issue.

Steps to Reproduce

  1. Modify Sections/main-cart-items.liquid to include an input element inside of the form tag
  2. Open Chrome Developer Tools @ Network tab
  3. Navigate to the Cart page, and write inside of the input element
  4. Unfocus the element
  5. Look for the failed network request to /change and the error message below the Check out buttons