Add to cart form not adding items to cart - shopify

I'm trying to create buttons that add specific quantities of a product to the cart, so I modified the form that is automatically generated by the product page in Shopify, but it seems my code won't add any products from any of my 3 buttons to the cart page. I created 3 different IDs because each button posts the same product but a different quantity of that product. It also has a different description otherwise I would just leave it as 1 ID to keep it simple.
<form action="/cart/add" method="post" enctype="multipart/form-data" id="AddToCartForm">
{% for variant in product.variants %}
{% if variant.available %}
<option value="{{ variant.id }}">
{{ variant.title }} - {{ variant.price | money_with_currency }}
</option>
{% else %}
<option disabled="disabled">
{{ variant.title }} - sold out
</option>
{% endif %}
{% endfor %}
{{ current_variant.price | money }}
<input type="hidden" id="Quantity" name="quantity" value="1" min="1">
<input type="submit" class="two-cans" name="id" quantity="1" id="6556104458433" value="Get 2 Cans"/>
<input type="submit" class="four-cans" name="id" quantity="2" id="6556136014017" value="Get 4 Cans"/>
<input type="submit" class="six-cans" name="id" quantity="3" id="6556139389121" value="Get 6 Cans"/>
</form>

Adding the id attribute on a submit button will not do what you expect it to do, as it has nothing to do with the actual Shopify id of a product or a variant.
The quantity attribute does not do anything by itself, so that will not work either.
A typical add to cart form will look something like this:
<form method="post" action="/cart/add">
<input type="hidden" name="id" value="{{ product.variants.first.id }}" />
<input min="1" type="number" id="quantity" name="quantity" value="1"/>
<input type="submit" value="Add to cart" class="btn" />
</form>
For your specific use case, a good approach would be using JS instead of liquid. You can use Shopify's REST Api, start by replacing the submit inputs with simple buttons and moving them outside of the form:
<button class="custom-submit-button two-cans" name="id" quantity="2" id="6556104458433">Get 2 Cans</button>
<button class="custom-submit-button four-cans" name="id" quantity="4" id="6556136014017">Get 4 Cans</button>
<button class="custom-submit-button six-cans" name="id" quantity="6" id="6556139389121">Get 6 Cans</button>
Then adding a bit of jQuery to handle the requests:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
function addItemToCart(variant_id, qty) {
var data = {
"id": variant_id,
"quantity": qty
}
$.ajax({
type: 'POST',
url: '/cart/add.js',
data: data,
dataType: 'json',
success: function() {
location.reload();
}
});
}
$('.custom-submit-button').click(function(){
addItemToCart($(this).attr("id"), $(this).attr("quantity"));
});
</script>

Related

when i click on add to cart button, page refreshes and then product is added how can i do this without getting the page refreshing

i added the button on product page below each product but they are refreshing the page i tried this code but whenever i click on add to cart page refreshes, how can it be done without refreshing the page and product still get added to cart without refreshing and redirecting to other page
<div class="buy-now-bx">
{% if card_product.available %}
<form method="post" action="/cart/add">
<input type="hidden" name="id" value="{{ card_product.selected_or_first_available_variant.id }}">
<div style="display: flex">
<input type="hidden" name="return_to" value="back" />
<input type = "submit" value = "Add to Cart" name = "addbutn" id="addbutn" class="button buynow-btn" data-id="{{ card_product.variants.first.id }}"/>
</div>
</form>
{% else %}
<a class="button buynow-btn" tabindex="0" href="{{ card_product.url | default: '#' }}">Sold out</a>
{%- endif -%}
</div>
To add an add-to-cart button to a Shopify product page without causing a page refresh, you can use Shopify's AJAX API to perform an AJAX request to the Shopify cart API. This allows you to add products to the cart without a page refresh.
Here's an example code snippet that you can use to achieve this:
In your product.liquid file, add a button to trigger the AJAX request when clicked:
<div class="buy-now-bx">
{% if card_product.available %}
<form method="post" action="/cart/add" id="add-to-cart-form">
<input type="hidden" name="id" value="{{ card_product.selected_or_first_available_variant.id }}">
<div style="display: flex">
<input type="hidden" name="return_to" value="back" />
<button type="submit" class="button buynow-btn" data-id="{{ card_product.variants.first.id }}" id="add-to-cart-btn">Add to Cart</button>
</div>
</form>
{% else %}
<a class="button buynow-btn" tabindex="0" href="{{ card_product.url | default: '#' }}">Sold out</a>
{% endif %}
</div>
Add the following code to your theme.js file or create a new file with the following code:
$(document).ready(function() {
$('#add-to-cart-form').submit(function(event) {
event.preventDefault(); // prevent the default form submit behavior
var form = $(this);
var addToCartButton = form.find('#add-to-cart-btn');
var originalButtonText = addToCartButton.text();
addToCartButton.attr('disabled', true).text('Adding...'); // disable the button and change the text
$.ajax({
type: 'POST',
url: '/cart/add.js',
data: form.serialize(),
dataType: 'json',
success: function() {
addToCartButton.text('Added!'); // change the button text
setTimeout(function() {
addToCartButton.attr('disabled', false).text(originalButtonText); // re-enable the button and change the text back to the original text after a delay
}, 1000);
},
error: function() {
addToCartButton.text('Error'); // handle the error by changing the button text
}
});
});
});
This code will handle the form submit event and send an AJAX request to the Shopify cart API when the add-to-cart button is clicked. It will also disable the button and change the text to indicate that the product is being added to the cart. Once the request is complete, it will change the button text to "Added!" and then change it back to the original text after a delay.

Combine two customer inputs in shopify to one customer tag

How can i get this code to combine the information from the drop down and the customer input into a single customer tag?
<div class="relative">
<label for="SocialMediatype">Select a social media</label>
<select id="socialmediatype" name="customer[tags]">
<option>Discord</option>
<option>Reddit</option>
<option>Instagram</option>
</select>
</div>
<label for="SocialMediaUsername">Social Media Username</label>
<input type="text" name="customer[note]" id="socialuser" {% if socialuser %}value="{{ socialuser }}"{% endif %} >
{% assign social = socialmediatype.id %}
{% assign socialuser = socialmediatype.id %}
<input type="hidden" name="customer[tags]" id="socialName" value="{{social, socialuser}}" >

Shopify Palo Alto Theme; Attempting to include an 'Add To Cart' in product-grid-item

I know that Timber/Palo Alto is no longer supported but I am working on an old account that uses it and am not familiar with the theme.
I have been able to create a button that adds an item to a cart but after clicking add to cart it redirects to the cart page, I just want to add the item and allow the user to still browse the collection.
Any suggestions will be helpful, Thank you in advance
<!-- /snippets/product-grid-item.liquid -->
<form action="/cart/add" data-productid="{{product.id}}" method="post" enctype="multipart/form-data" id="AddToCartForm--{{section.id}}">
<div class = "variants-wrapper">
{% if variants_count > 1 %}
<select name="id" data-productid="{{product.id}}" id="productSelect--{{section.id}}" class="product-single__variants">
{% for variant in product.variants %}
{% if variant.available %}
<option {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} data-sku="{{ variant.sku }}" value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money_with_currency }}</option>
{% else %}
<option disabled="disabled">
{{ variant.title }} - {{ 'products.product.sold_out' | t }}
</option>
{% endif %}
{% endfor %}
</select>
{% else %}
<input name="id" data-productid="{{product.id}}" type="hidden" value="{{ product.variants[0].id }}">
{% endif %}
{% if sold_out %}
<input type="hidden" type="text" id="Quantity1" name="quantity" value="0" min="0" class="quantity-selector quantity-input">
<a class="btn" href="{{ product.url | within: collection }}">{{ 'products.product.view_item' | t }}</a>
{% else %}
<div class="qtydiv">
<input type="text" id="Quantity1" name="quantity" value="1" min="1" class="quantity-selector quantity-input">
</div>
<button type="submit" name="add" id="AddToCart" class="btn" style="display: inline">
<span id="AddToCartText">{{ 'products.product.add_to_cart' | t }}</span>
</button>
{% endif %}
</div>
</form>
ajax-cart.js.liquid
ShopifyAPI.addItemFromForm = function(form, callback, errorCallback) {
var params = {
type: 'POST',
url: '/cart/add.js',
data: jQuery(form).serialize(),
dataType: 'json',
success: function(line_item) {
if ((typeof callback) === 'function') {
callback(line_item, form);
}
else {
ShopifyAPI.onItemAdded(line_item, form);
}
},
error: function(XMLHttpRequest, textStatus) {
if ((typeof errorCallback) === 'function') {
errorCallback(XMLHttpRequest, textStatus);
}
else {
ShopifyAPI.onError(XMLHttpRequest, textStatus);
}
}
};
jQuery.ajax(params);
};
This redirects to cart page, because that is how form action value is defined. So if you want to add it without page redirect and reload, use Shopify AJAX API that allows you manage CRUD operations on cart. Shopify AJAX API.
In the above scenario, you need to have a look at Add to Cart functionality.
Post Data
{
quantity: 2,
id: 794864229
}
Sample Code
// Send a seralized form
jQuery.post('/cart/add.js', $('form[action="/cart/add"]').serialize());
// or construct post data
jQuery.post('/cart/add.js', {
quantity: 1,
id: 794864229,
properties: {
'First name': 'Caroline'
}
});
Another approach that is a bit easy to implement is to use CartJS
So using data API, it would just be
<button data-cart-add="12345678">Add Product</button>
Sample implementation on Timber Shopify theme
in theme.liquid after timber.js load CartJS
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/shopify-cartjs/0.4.1/cart.min.js"></script>
Then below that in the jQuery ready function, initialize CartJS
CartJS.init({{ cart | json }}, {
"dataAPI": true
});
The add this code in product-grid-item.liquid
<button data-cart-add="{{ product.variants.first.id }}">Add Product</button>
This is working on my test installation of Timber theme.

Adding an "ADD TO CART" button to a collection

I have a client asking to add an "ADD TO CART" button under each product in their collections and I can't figure out how.
I'm new to the Shopify platform and I am not familiar with Liquid but I did try to use the built in "Channel" of adding a Buy Button, but when trying to paste in the code it didn't populate anything in the preview page.
Any help would be wonderful.
Use the shopify API by adding this into the collection.liquid
<form method="post" action="/cart/add">
<input type="hidden" name="id" value="{{ product.variant.id }}" />
<input min="1" type="number" id="quantity" name="quantity" value="1"/>
<input type="submit" value="Buy" class="btn" />
</form>
Add that somewhere in this loop
{% for product in collection.products %}
...
{% endfor %}
product.variant.id identifies which item is added to the cart and it could be replaced with product.variants.first.id
This details how it works and applies to standard, non ajax, forms too
https://help.shopify.com/en/themes/development/getting-started/using-ajax-api#add-to-cart

Dynamic Attribute Names in Shopify Cart

I'm so close on this, but I just can't get the syntax right. I've been messing with this off and on for days. Essentially I have a greeting card message and I want the message to be filled in by the customer for every Greeting Card on the checkout page (cart.liquid) and I need the attribute name to change for every index. Therefore I'm adding the index to each attribute name, but to no avail. For testing purposes, here's a basic input field:
<p class="cart-attribute__field" style="min-width:300px;">
<label for="to{{ forloop.index }}">To:</label>
<input class="checkMe" id="to{{ forloop.index }}" type="text" name="attributes[To{{ forloop.index }}]" maxlength="40" data-stk="{{item.id}}" value="{{ cart.attributes['To'+forloop.index] }}" >
</p>
And its this part (value="{{ cart.attributes['To'+forloop.index] }}") that is giving me trouble.
You cannot use '+' operator in liquid code to append. Try this instead:
{% assign cart_attr = 'To' | append: forloop.index %}
<p class="cart-attribute__field" style="min-width:300px;">
<label for="to{{ forloop.index }}">To:</label>
<input class="checkMe" id="to{{ forloop.index }}" type="text" name="attributes[To{{ forloop.index }}]" maxlength="40" data-stk="{{item.id}}" value="{{ cart.attributes[cart_attr] }}" >
</p>
Note: Improvise as required.
Why would you not just use line item properties as described on https://docs.shopify.com/manual/configuration/store-customization/page-specific/product-page/get-customization-information-for-products