简体   繁体   中英

Shopify Ajax API, Alpine JS, add user selected options to cart using Ajax

I am building this Build A Box section where a user can select various items that make up 1 product. I'm having trouble getting items into the cart.

UPDATE: Current state is can add the hard coded main product in formData I did this first to get addToCart started. It's adds the main product but does not redirect to cart page. If you change url in browser to /cart its in there.

I need to figure out 2 things.

1 how to redirect to cart page after firing addToCart()

2 How to add user selected items as 1 product to cart not variants.

See Logs在此处输入图像描述

I can select elements and push into an array in my x-data component. The data looks like this:

 [
   {img_string: 'https://cdn.shopify.com/s/files/1/0695/7495/1222/files/Barky.webp? 
   v=1672528086&width=150', title: 'Barky', id: 'selected_item-1'},
   {img_string: 'https://cdn.shopify.com/s/files/1/0695/7495/1222/files/Barky.webp? 
   v=1672528086&width=150', title: 'Barky', id: 'selected_item-1'}
 ]

For my latest iteration, I just hard coded the variant id & a quantity. Still have to figure out how to get all the selected items into the cart.

UPDATE: I added preventDefault filter to Alpine addToCart() call now it does not redirect but if you change url in browser to /cart the hard coded main product is in there.

<div x-data="items: []"> 
  <div
        x-data="
          {
            qty: 1,
            addToCart(){
              let formData = {
              'items': [{
                'id': 44202123100470,
                'quantity': 1
                }]
              };
              fetch(window.Shopify.routes.root + 'cart/add.js', {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify(formData)
              })
              .then(response => {
                console.log(response)
                return response.json();
              })
              .catch((error) => {
                console.error('Error:', error);
              });
            }
          }
        "
        class="tw-mt-12 tw-flex tw-flex-col tw-p-auto tw-bg-brandText tw-opacity-80"
      >
        <div class="tw-p-8">
          <h2 class="tw-mb-4 tw-text-white">Your Selections</h2>
          {% assign product_form_id = 'product-form-' | append: section.id %}
          {%- form 'product',
            product,
            id: product_form_id,
            class: 'form',
            novalidate: 'novalidate',
            data-type: 'add-to-cart-form'
          -%}
            <input
              type="hidden"
              name="id"
              value="{{ product.selected_or_first_available_variant.id }}"
              disabled
            >
            <input type="hidden" name="quantity" x-model="qty" value="1">
            <div class="product-form__buttons">
              <button
                type="add"
                @click="addToCart()"
                :class="full_box ? 'tw-bg-ctaColor' : ''"
                class="tw-bg-white tw-text-brandText tw-flex tw-justify-center tw-py-4 tw-px-6 tw-rounded-full tw-font-bold"
              >
                <p class="" x-show="!full_box">
                  <span x-text="items_selected" class="tw-mr-2"></span><span class="tw-mr-2">of</span
                  ><span class="tw-font-bold" x-text="box_size"></span><span class="tw-ml-2">Selected</span>
                </p>
                <p x-show="full_box" class="">Add to cart</p>
              </button>
            </div>
          {%- endform -%}
        </div>
</div>

The way I solved the redirect issue was to use the Location API add location.href="/cart" in the success promise of the Ajax call.

             fetch(window.Shopify.routes.root + 'cart/add.js', {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify(formData)
              })
              .then(response => {
                console.log(response)
                return response.json();
              })
              .then((data) => {
               location.href = '/cart';
                console.log('Success:', data);
              })
              .catch((error) => {
                console.error('Error:', error);
              });

To solve the issue of how to get all selected items into the cart. I mapped over the items array of objects and returned an array of strings. Then I assigned to a variable selectedItems and called toString()

In the properties key of formData I added a value of selectItems to Box Items key. Kinda ugly at the moment no spaces in string. Definitely need to refactor this. Any feedback would be Super Cool ♂️

    <div
        x-data="
          {
            addToCart(items, id){

             let itemsToAdd = items.map((item) => {
               return item['title'];
             })

             let selectedItems = itemsToAdd.toString()

              let formData = {
              'items': [{
                'id': id,
                'quantity': 1,
                'properties': {
                  'Box Items': selectedItems,
                  }
                }]
              };

              fetch(window.Shopify.routes.root + 'cart/add.js', {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify(formData)
              })
              .then(response => {
                console.log(response)
                return response.json();
              })
              .then((data) => {
                location.href = '/cart';
                console.log('Success:', data);
              })
              .catch((error) => {
                console.error('Error:', error);
              });
              reset()
            }
          }
        "
        class="tw-mt-12 tw-flex tw-flex-col tw-p-auto tw-bg-brandText tw-opacity-80"
      >...</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM