How to make Dawn theme slide cart refresh and open when items are added to cart?

I created a snippet that adds some buttons to the product page and allows the customer to add to cart. Initially, I was using a slide cart app, and it works fine. I am trying to switch to using the Dawn Theme built in slide cart, but I do not know how to force the cart to refresh & slide open when items are added.

In the addToCart function below, the following 2 lines work with the app’s slide cart and update then slide it open accordingly. I am looking to do this with the Dawn Theme slide cart. Is this achievable?

this.window.SLIDECART_UPDATE(response);
this.window.SLIDECART_OPEN();

addToCart function:

function addToCart(product_formData) {
    let formData = product_formData;
    fetch(window.Shopify.routes.root + 'cart/add.js', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(formData)
    })
    .then((response) => response.json())
    .then((response) => {
        this.window.SLIDECART_UPDATE(response);
        this.window.SLIDECART_OPEN();
    })
    .catch((e) => {
        console.error(e);
    });

Would you like to activate the cart drawer in your store?

The cart drawer is already activated in my store. This is a custom add to cart button that I am working with, and when the items are added to the cart I want the slide cart to update and open. As of now, it does not update the slide cart until page refresh.

"I’ve checked the code you provided, and it’s working fine for me. I’ve added the button in the buy-buttons.liquid file. When I click the button, the item is added to the cart and the cart drawer opens.

<button id="additional_button"  onclick="addToCart()"  type="submit" class="product-form__submit button button--full-width button--primary">
    Additional Button
</button>
<script>
function addToCart() {
	let formData = product - form;
	fetch(window.Shopify.routes.root + 'cart/add.js', {
		method: 'POST',
		headers: {
			'Content-Type': 'application/json',
		},
		body: JSON.stringify(formData),
	})
		.then((response) => response.json())
		.then((response) => {
			this.window.SLIDECART_UPDATE(response);
			this.window.SLIDECART_OPEN();
		})
		.catch((e) => {
			console.error(e);
		});
}
</script>

If you add it to the buy-buttons.liquid file, it is not actually using the addToCart function it is just doing the same thing that the regular buy button does. If you removed the addToCart script or the onClick in your code, it would still do the same thing I believe.

I have created a file in the snippets folder named additional-buttons.liquid and added the below code.

<div>
  <product-form
    class="product-form"
    id="product-form-{{ product_form_id }}"
  >
    {%- form 'product', product, id: product_form_id, class: 'form', novalidate: 'novalidate' -%}
      <input
        type="hidden"
        name="id"
        value="{{ product.selected_or_first_available_variant.id }}"
        {% if product.selected_or_first_available_variant.available == false
          or quantity_rule_soldout
          or product.selected_or_first_available_variant == null
        %}
          disabled
        {% endif %}
        class="product-variant-id"
      >
      <button
        id="additional_button"
        type="submit"
        class="product-form__submit button button--full-width button--primary"
      >
        Additional Button
      </button>
      {%- render 'loading-spinner' -%}
    {%- endform -%}
  </product-form>
</div>

In the main-product.liquid file, I have added the snippet below the buy-buttons.

{%- render 'additional-buttons',
    block: block,
    product: product,
    product_form_id: product_form_id,
    section_id: section.id,
    show_pickup_availability: true
-%}

The code add the product to the cart and open the drawer.

Oh, I see. Is there a way to adjust your code so that it adds 3 items to the cart? On my page I have 2 checkbox upsells (image below):

My goal with this is if both checkboxes are selected when the user clicks the ATC button, all 3 items are added to the cart, and the cart drawer opens. If only 1 checkbox is checked, it adds that upsell and the main product to the cart, etc…

My current implementation achieves this but it does not cause the cart to visually update until page reload. My implementation does not utilize a form though, it just makes a post request when the button is clicked. Can your code be edited to add 3 items to cart at the same time?

Thank you for taking the time to help me. I appreciate it.

Could you please try the code below?

  1. Create a new file snippets/additional-buttons.liquid
<input
  type="checkbox"
  id="upsell-checkbox-1"
  name="upsell-1"
  value="true"
  data-variant-id={{ data-variant-id }}
  data-product-id={{ data-product-id }}
  section-id={{ section_id }}
>
<label for="upsell-checkbox-1"> The Multi-managed Snowboard </label>
  1. snippets/buy-buttons.liquid
{%- render 'additional-buttons',
    data-variant-id: "42143107678268",
    data-product-id: "7775528878140",
    section_id: section.id
-%}

Currently, I have hardcoded the add-on product ID and placed the snippet above the <product-form> tag.

  1. assets/product-form.js

Please update the onSubmitHandler(evt) in the product-form.js file with the code below.

    async onSubmitHandler(evt) {
    	evt.preventDefault();
    	if (this.submitButton.getAttribute('aria-disabled') === 'true') return;
    
    	this.handleErrorMessage();
    
    	this.submitButton.setAttribute('aria-disabled', true);
    	this.submitButton.classList.add('loading');
    	this.querySelector('.loading__spinner').classList.remove('hidden');
    
    	const config = fetchConfig('javascript');
    	config.headers['X-Requested-With'] = 'XMLHttpRequest';
    	delete config.headers['Content-Type'];
    
    	const formData = new FormData(this.form);
    	if (this.cart) {
    		formData.append(
    			'sections',
    			this.cart.getSectionsToRender().map((section) => section.id),
    		);
    		formData.append('sections_url', window.location.pathname);
    		this.cart.setActiveElement(document.activeElement);
    	}
    
    	config.body = formData;
    	let data = {};
    	try {
    		const response = await fetch(`${routes.cart_add_url}`, config);
    		data = await response.json();
    
    		if (data.status) {
    			publish(PUB_SUB_EVENTS.cartError, {
    				source: 'product-form',
    				productVariantId: formData.get('id'),
    				errors: data.errors || data.description,
    				message: data.message,
    			});
    			this.handleErrorMessage(data.description);
    
    			const soldOutMessage =
    				this.submitButton.querySelector('.sold-out-message');
    			if (!soldOutMessage) return;
    			this.submitButton.setAttribute('aria-disabled', true);
    			this.submitButtonText.classList.add('hidden');
    			soldOutMessage.classList.remove('hidden');
    			this.error = true;
    			return;
    		} else if (!this.cart) {
    			window.location = window.routes.cart_url;
    			return;
    		}
    
    		if (!this.error) {
    			publish(PUB_SUB_EVENTS.cartUpdate, {
    				source: 'product-form',
    				productVariantId: formData.get('id'),
    				cartData: data,
    			});
    		}
    
    		const upsellCheckbox = document.getElementById('upsell-checkbox-1');
    		const upsellProductId = upsellCheckbox.getAttribute('data-product-id');
    		const upsellVariantId = upsellCheckbox.getAttribute('data-variant-id');
    		const sectionId = upsellCheckbox.getAttribute('section-id');
            const quantityElement = document.getElementById('Quantity-template--17232286384188__main');
            const quantityValue = quantityElement ? quantityElement.value : 1; 
          
    		if (upsellCheckbox.checked) {
    			formData.append('id', upsellVariantId);
    			formData.append('quantity', quantityValue);
    			formData.append('product-id', upsellProductId);
    			config.body = formData;
    			const upsellResponse = await fetch(`${routes.cart_add_url}`, config);
    			data = await upsellResponse.json();
    		}
    
    		this.error = false;
    
    		const quickAddModal = this.closest('quick-add-modal');
    		if (quickAddModal) {
    			document.body.addEventListener(
    				'modalClosed',
    				() => {
    					setTimeout(() => {
    						this.cart.renderContents(data);
    					});
    				},
    				{ once: true },
    			);
    			quickAddModal.hide(true);
    		} else {
    			this.cart.renderContents(data);
    		}
    	} catch (e) {
    		console.error(e);
    	} finally {
    		this.submitButton.classList.remove('loading');
    		if (this.cart && this.cart.classList.contains('is-empty')) {
    			this.cart.classList.remove('is-empty');
    		}
    		if (!this.error) this.submitButton.removeAttribute('aria-disabled');
    		this.querySelector('.loading__spinner').classList.add('hidden');
    	}
    }